How to treat a `networkx.digraph` as un-directed - python

I have a directed graph G represented as a networkx.digraph. I want to be able to do shortest-path computations on the undirected version of that graph. How do I get an object that is the undirected version of that graph.
I know it will involve making a graph view, however
the documentation for generic_graph_view is not very useful in explaining how to achieve this; nor is the code itself for some one that is not familiar with the internals of the library.

You can just pass your directed graph to nx.Graph
G=nx.fast_gnp_random_graph(10,.2,directed=True)
G_undirected = nx.Graph(G)
print(G.edges)
# OutEdgeView([(0, 1), (0, 5), (1, 0), (1, 2), (1, 6), (1, 9),
# (2, 7), (2, 9), (3, 4), (4, 7), (5, 4), (6, 0), (7, 8),
# (8, 9), (9, 4)])
print(G_undirected.edges)
# EdgeView([(0, 1), (0, 5), (0, 6), (1, 2), (1, 6), (1, 9), (2, 7),
# (2, 9), (3, 4), (4, 7), (4, 5), (4, 9), (7, 8), (8, 9)])

Related

How to make a list using Networkx in Python

I have a list,
selected=[[0,5,9,10,0],[0,2,4,7,8,0],[0,1,3,6,0]]
It's a route of 3 cars.I want to convert it below,
selected1=[(0,5),(5,9),(9,10),(10,0),(0,2),(2,4),(4,7),(7,8),(8,0),(0,1),(1,3),(3,6),(6,0)]
I can do reverse by using networkx library(selected1 to selected),but now i need selected to selected1.Thanks for everyone.
Using a list comprehension might do the work :
selected=[[0,5,9,10,0],[0,2,4,7,8,0],[0,1,3,6,0]]
selected1 = [(s[i], s[i+1]) for s in selected for i in range(len(s)-1)]
# [(0, 5), (5, 9), (9, 10), (10, 0), (0, 2), (2, 4), (4, 7), (7, 8), (8, 0), (0, 1), (1, 3), (3, 6), (6, 0)]

How to sort edges of path based on start and end point?

I have a problem with the path of each truck. From my model, I get the output of each truck path is misorder. I would like to order my list of edges based on the start and endpoint.
trucks = {0: (10, 1),1:(7,1),2: (3, 10),3:(7,4)} # truck_number:(start_point, end_point)
input I need to change:
path = {0: [(2, 1), (5, 2), (6, 5), (10, 6)],
1: [(2, 1), (5, 2), (6, 5), (7, 6)],
2: [(2, 5), (3, 2), (5, 6), (6, 10)],
3: [(5, 4), (6, 5), (7, 6)]}
output I need
output_i_need ={0: [(10, 6), (6, 5), (5, 2), (2, 1)],
1: [(7, 6), (6, 5), (5, 2), (2, 1)],
2: [(3, 2), (2, 5), (5, 6), (6, 10)],
3: [(7, 6), (6, 5), (5, 4)]}
is there any library in python to order my list of edges?
I don't know of a library, but writing a function to reorder the list of edges is easy if you convert the list of edges into a dictionary mapping edge_start to edge_end.
trucks = {0: (10, 1),1:(7,1),2: (3, 10),3:(7,4)} # truck_number:(start_point, end_point)
paths = {0: [(2, 1), (5, 2), (6, 5), (10, 6)],
1: [(2, 1), (5, 2), (6, 5), (7, 6)],
2: [(2, 5), (3, 2), (5, 6), (6, 10)],
3: [(5, 4), (6, 5), (7, 6)]}
def reordered(l, start, end):
d = dict(l)
result = []
while start != end:
result.append((start, d[start]))
start = d[start]
return result
new_paths = { truck: reordered(path, trucks[truck][0], trucks[truck][1])
for truck,path in paths.items() }
print(new_paths)
# {0: [(10, 6), (6, 5), (5, 2), (2, 1)],
# 1: [(7, 6), (6, 5), (5, 2), (2, 1)],
# 2: [(3, 2), (2, 5), (5, 6), (6, 10)],
# 3: [(7, 6), (6, 5), (5, 4)]}

Itertools product return sets [duplicate]

This question already has answers here:
Cartesian products of lists without duplicates
(2 answers)
Closed 3 years ago.
I want to create an iterator with cartesian products where no duplicates are present in the sense of sets.
import itertools
A = list(range(1,10))
iterator = itertools.product(A,repeat=2)
print(list(iterator))
>> [(1,1),(1,2),...,(2,1),...,(9,9)]
Above is wrong in the sense that set((1,2)) == set((2,1)). I could do
B = list()
for i in iterator:
if all(set(i) != set(j) for j in B):
B.append(i)
and get a list of the wanted output, but I would like to stay away from lists since I run into memory problems when scaling the repeat-option.
Can anyone help me out?
A = list(range(1,10))
k = []
for i, v in enumerate(A):
for _, v1 in enumerate(A[i:]):
k.append((v, v1))
print(k)
Output is
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (3, 3), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (4, 4), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (5, 5), (5, 6), (5, 7), (5, 8), (5, 9), (6, 6), (6, 7), (6, 8), (6, 9), (7, 7), (7, 8), (7, 9), (8, 8), (8, 9), (9, 9)]

Combine unknown amount of lists, keep only common values

I want to combine N lists and keep only the values that are in every single one of them. I don't know how many lists there are, so the code must be dynamic.
a_list = [(3, -1), (3, -1), (3, 0), (4, -1), (3, 1), (5, -1), (3, 2), (6, -1), (3, 3), (7, -1), (7, -1), (3, 3), (7, 0), (4, 3), (7, 1), (5, 3), (7, 2), (6, 3), (7, 3), (7, 3)]
b_list = [(-3, 3), (-3, 3), (-3, 4), (-2, 3), (-3, 5), (-1, 3), (-3, 6), (0, 3), (-3, 7), (1, 3), (-3, 8), (2, 3), (-3, 9), (3, 3), (3, 3), (-3, 9), (3, 4), (-2, 9), (3, 5), (-1, 9), (3, 6), (0, 9), (3, 7), (1, 9), (3, 8), (2, 9), (3, 9), (3, 9)]
a = set(a_list)
b = set(b_list)
print(list(a&b))
This code works perfectly for a known number of lists, but I don't know how many lists there are.
Note: "Unknown number of lists" means it depends on the values the script is ran with.
Edit: N > 0
You can use the built-in set function intersection:
print (set.intersection(*map(set, lists)))
Use reduce
import functools
list_of_sets = [set(x) for x in list_of_lists]
intersection = functools.reduce(lambda x, y: x & y, list_of_sets)

Making Combinations (Python)

In Python, is there a better way to get the set of combinations of n elements from a k-element set than nested for loops or list comprehensions?
For example, say from the set [1,2,3,4,5,6] I want to get [(1,2),(1,3),(1,4),(1,5),(1,6),(2,3),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6),(4,5),(4,6),(5,6)]. Is there a better of of making it than
nums=[1,2,3,4,5,6]
doubles=[]
for a in nums:
for b in nums[a+1:]
doubles.append((a,b))
? It's okay if the elements of the list we end up with are sets, tuples, or lists; I just feel there should be an easier way to do this.
You can use itertools.combinations:
>>> from itertools import combinations
>>> nums = [1,2,3,4,5,6]
>>> list(combinations(nums, 2))
[(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 3), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6), (4, 5), (4, 6), (5, 6)]
The itertools module has a lot of really powerful tools that can be used in situations like this. In this case, you want itertools.combinations. Some other ones that you might find useful are itertools.combinations_with_replacement and itertools.permutations.
Example:
>>> import itertools
>>> list(itertools.combinations(range(1,7),2))
[(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 3), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6), (4, 5), (4, 6), (5, 6)]
>>> list(itertools.combinations_with_replacement(range(1,7),2))
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (3, 3), (3, 4), (3, 5), (3, 6), (4, 4), (4, 5), (4, 6), (5, 5), (5, 6), (6, 6)]
>>> list(itertools.permutations(range(1,7),2))
[(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 1), (2, 3), (2, 4), (2, 5), (2, 6), (3, 1), (3, 2), (3, 4), (3, 5), (3, 6), (4, 1), (4, 2), (4, 3), (4, 5), (4, 6), (5, 1), (5, 2), (5, 3), (5, 4), (5, 6), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5)]
You could use the itertools module
import itertools
alphabet = ['1','2','3','4','5','6']
combos = list(itertools.combinations(alphabet, 2))
print combos

Categories

Resources