Networkx tools in Python - python

Hi i am still quite new to networkx python.
does anyone know how i can get all of the intersection?
Intersection nodes are the red circled. This is for undirected Graph, I would also very keen to know if there is also a way to get intersection for directed graph
Once i got the intersection, I also would like to get the start and the end node. the reason is I wanted to put different group to the path (from start node to end node)
Can I achieve this result too :<

If with intersections you mean nodes with more than two neighbors than you can use that exact logic like
intersections = [node for node in G.nodes() if len(list(G.neighbors(node)))>2]
H = G.copy()
H.remove_nodes_from(intersections)
components = nx.connected_components(H)
For "spotting" intersection you can issue them an attribute like this:
intersections_subgraph = nx.subgraph(G, intersetions)
nx.set_node_attributes(intersections_subgraph, True, 'intersection')
Adding intersections back into the sections should works by looping through the intersections neighbors and adding the intersection to the section the neighbors are in.
For sorting I would loop through the section to find a start point (only one edge/neighbor) and then move from node to node. Note that sets are always unordered so you will have to switch over to an ordered structure like a list.
Ill leave implementing those to you

Related

How to add an additional edge between nodes that already have edges?

I have a Graph object and between each pair of nodes that already has an edge, I would like to add an additional edge? Is there a way to do this without brute force looping through all the edges?
A simple way to do this is:
temp = nx.Graph(our_graph)
new_graph = nx.MultiGraph(temp)
new_graph.add_edges_from(temp.edges)

How to build graph paths from list of nodes in NetworkX

What I am trying to do is build a graph in NetworkX, in which every node is a train station. To build the nodes I did:
G = nx.Graph()
G.add_nodes_from(trains['Stopping place'].unique())
which (at least as it looks like) it's working.
Now, since for each line I have the stops in sequence, I built my paths like so:
stops_by_line = ((belgium_trains.sort_values(['Train number','Actual arrival datetime']).groupby('Train number'))['Stopping place'].apply(list).to_dict())
paths = ([tuple(val) for val in stops_by_line.values()])
and the variable looks like this:
[('HERGENRATH',
'CHENEE',
'ANGLEUR',
'LIEGE-GUILLEMINS',
'ANS',
'LEUVEN',
'HERENT',
'VELTEM',
'ERPS-KWERPS',
'KORTENBERG',
'NOSSEGEM',
'ZAVENTEM',
'DIEGEM',
'HAREN-ZUID',
'SCHAARBEEK',
'BRUSSEL-NOORD',
'BRUSSEL-CONGRES',
'BRUSSEL-CENTRAAL',
'BRUSSEL-KAPELLEKERK',
'BRUSSEL-ZUID'),
(...other ordered tuples of stops),...)]
Now my question is, since all of these elements are also node names, how can I build the edges using these tuples sequentially (for example add an edge between BRUSSEL-NOORD and BRUSSEL-CONGRES, then from BRUSSEL-CONGRES to BRUSSEL-CENTRAAL and so on)?
You can simply use the add_path method in a loop:
for path in paths:
nx.add_path(G, path)
Sidemark, if you add an edge (like e.g. above), then networkx also directly adds the respective nodes to the graph. So probably (if all stops are covered by some train) you don't need to add the nodes manually before.

How to simplify a proposed dictionary of different keys

I built a graph using NetworkX library. I used all_shortest_paths(graph, src, dest) that returns a list of a all possible shortest paths from a given source and a given destination (For example, between node 3 and 4 it may return [[3,5,4],[3,5,7,6,4]]). For the sake of my experiment, I want to store every returned list in a dictionary. My problem is how to utilize Python dictionary to do so. If I use the following scenario, it will be complicated:
dict = {'n1':['n2':[n1,n3,n4,n2], 'n3':[n1,n7,n3]], 'n2':['n6':[n2,n6,n8,n10,n2]], ...}
Is it possible in Python to have dictionary inside a dictionary where the the key will be src node and the value is another dictionary of a key dest and value all possible paths to the destination.
Thank you for any help.
You could represent your graph as an adjacency matrix. This is just a 2-dimensional array of 1's and 0's, of size (number of nodes x number of nodes) with the rows and columns representing the nodes, and an entry of 1 at a row and column where the nodes represented are neighbors, and a 0 where the nodes represented by that row and column are not neighbors.
If you plan to do any extensive work with graphs in Python, I strongly recommend looking into the NetworkX Python package. It is documented at http://networkx.github.io/ . If you use the Anaconda scientific Python distribution, NetworkX comes with it.
There are other methods in NetworkX, like all_pairs_shortest_path(), and floyd_warshall(), that return their results as a dictionary of shortest paths by node, keyed by source and destination node.
And all_pairs_shortest_path_length(), which returns its results as a dictionary of shortest path lengths, keyed by source and destination node.
Possibly one of these might work for you?

Find all vertices with the same edge attribute

I would like to find all vertices (vertex id's) sharing the same edge attribute (so there can be tons of vertices like this) by using Igraph. This would be very convenient when I want to find all "villages" (the vertices of my graph) on a "road", let's say "Route 69" (an edge attribute).
Is there a simple way in Igraph to do this? Maybe I've overcomplicated it.
Actually what I need is the opposite of: g.es.select(_within=g.vs[2:5]) or
>>> men = g.vs.select(gender="m")
>>> women = g.vs.select(gender="f")
>>> g.es.select(_between=(men, women))
because I know the edge attribute but I don't know the vertices.
I will select the edge and hope that it will return all related vertices.
Maybe I'm only tired now, but I don't find my way around this problem. I appreciate if somebody helps me out with the right way. Or maybe there is a method I miss in tutorial and documentation. It smells like there is a very simple method to this. Thank you in advance for any advice!
First, select all the edges on Route 69:
edges = g.es.select(name="Route69")
Then iterate through the selected edges and collect the endpoints of the vertices:
vertices = set()
for edge in edges:
vertices.update(edge.tuple)
This will give you a set containing the vertex IDs of all the vertices that are incident on at least one edge with name Route69. If you need a VertexSeq, you can simply do this:
vertices = g.vs[sorted(vertices)]
You should be able to do the following:
r69edges = g.es.select(name_eq='Route69') #Select all edges where name=='Route69'
sg = r69edges.subgraph() #Create a subgraph containing only the selected edges (and attached vertices)
village_verts = sg.vs.select(name_eq='villages') #Select the vertices where name=='villages'
This assumes that 'villages' and 'Route69' are stored in an attribute called 'name' on the vertices and edges... Adjust appropriately to match your attributes.
Of course - you can squash this all into one line if you want:
village_verts = g.es.select(name_eq='Route69').subgraph().vs.select(name_eq='villages')
Not sure if this is the most efficient way (though I'm not seeing any shortcuts in the documentation), but it should get you what you're after.

Double linking array in Python

Since I'm pretty new this question'll certainly sound stupid but I have no idea about how to approach this.
I'm trying take a list of nodes and for each of the nodes I want to create an array of predecessors and successors in the ordered array of all nodes.
Currently my code looks like this:
nodes = self.peers.keys()
nodes.sort()
peers = {}
numPeers = len(nodes)
for i in nodes:
peers[i] = [self.coordinator]
for i in range(0,len(nodes)):
peers[nodes[i%numPeers]].append(nodes[(i+1)%numPeers])
peers[nodes[(i+1)%numPeers]].append(nodes[i%numPeers])
# peers[nodes[i%numPeers]].append(nodes[(i+4)%numPeers])
# peers[nodes[(i+4)%numPeers]].append(nodes[i%numPeers])
The last two lines should later be used to create a skip graph, but that's not really important. The problem is that it doesn't really work reliably, sometimes a predecessor or a successor is skipped, and instead the next one is used, and so forth. Is this correct at all or is there a better way to do this? Basically I need to get the array indices with certain offsets from each other.
Any ideas?
I would almost bet that when the error occurs, the values in nodes have duplicates, which would cause your dictionary in peers to get mixed up. Your code assumes the values in nodes are unique.

Categories