I started using python and networkx from a few days.
I have an unoriented graph and I try to iterate on the edges incident to a node.
I used
print (G.edges)
for i in G.nodes:
print( G.edges(i))
obtaining
[(0, 1), (0, 2), (0, 4), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
[(0, 1), (0, 2), (0, 4)]
[(1, 0), (1, 2), (1, 3), (1, 4)]
[(2, 0), (2, 1), (2, 3), (2, 4)]
[(3, 1), (3, 2), (3, 4)]
[(4, 0), (4, 1), (4, 2), (4, 3)]
The edges provided by G.edges() have the two nodes reversed in some cases (e.g., for i=1 I have edge (1,0), but it does not exist !! I have only (0,1). Since the graph is unoriented, it is the same edge, but if I try to use it as the index of a vector of the edges it does not work.
I tried
for i in G. nodes
... do something with .... x[e] for e in G.edges(i)
You can extend the list of G.edges() to be in both direction
a = [e for e in G.edges]
gives you the list of edges [(0, 1), (0, 2), (0, 4), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)] which removes duplicate representations of undirected edges while neighbor reporting across all nodes will naturally report both directions, according to networkx Documentation.
You can either:
1) duplicate the list by adding edges representation in reversed order
a = [e for e in G.edges] + [(y, x) for (x, y) in G.edges]
which gives you
[(0, 1), (0, 2), (0, 4), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4), (1, 0), (2, 0), (4, 0), (2, 1), (3, 1), (4, 1), (3, 2), (4, 2), (4, 3)]
or; 2) use list comprehension to get edges from G.edges(i) like you did:
b = [e for i in G.nodes for e in G.edges(i)]
output:
[(0, 1), (0, 2), (0, 4), (1, 0), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 3), (2, 4), (3, 1), (3, 2), (3, 4), (4, 0), (4, 1), (4, 2), (4, 3)]
Related
I created a graph, with Networkx 2.4, with the following edges:
EdgeView([(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (3, 4), (3, 5), (3, 6), (3, 7), (4, 6), (4, 7), (5, 6), (5, 7)])
When I request all cliques using networx.enumerate_all_cliques(G), the maximum clique has only four vertices, e.g. [2,3,5,7].
How do I list cliques with more than 4 vertices, e.g. [0,1,2,3,5,6] or, some other way to get all possible subgraphs from 1 to n nodes.
I am currently trying to understand how to nest two for loops together before utilizing any comprehension loops. My mission is to return a list of every combination as a tuple, instead i am receiving a list of 6 lists, when i want a list of 36 combinations.
I have tried to iterate over the two ranges.
def build_roll_permutations():
dice = []
for i in range(1,7):
dicee = []
for j in range(1,7):
dicee.append((i,j))
dice.append(dicee)
return dice
expected results:
[(1,1),(1,2)(1,3)...etc]
my results:
[[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6)], [(2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6)], [(3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6)], [(4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6)], [(5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6)], [(6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6)]]
Just get rid of dicee and append directly to dice.
def build_roll_permutations():
dice = []
for i in range(1,7):
for j in range(1,7):
dice.append((i,j))
return dice
Note you can do this with a simple list comprehension
def build_roll_permuatations():
return [(i,j) for i in range(1,7) for j in range(1,7)]
or itertools.product (since this is, in fact, a product and not a permutation):
def build_rolls():
return list(product(range(1,7), repeat=2))
Use extend instead of append, when modifying dice:
def build_roll_permutations():
dice = []
for i in range(1, 7):
dicee = []
for j in range(1, 7):
dicee.append((i, j))
dice.extend(dicee) # line to fix
return dice
print(build_roll_permutations())
Output
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6)]
{(0, 0): {(0, 1), (1, 0)},
(0, 3): {(0, 2), (0, 4), (1, 3)},
(0, 4): {(0, 3), (1, 4)},
(1, 1): {(0, 1), (1, 0), (1, 2), (2, 1)},
(1, 2): {(0, 2), (1, 1), (1, 3), (2, 2)},
(2, 0): {(1, 0), (2, 1), (3, 0)},
(2, 2): {(1, 2), (2, 1), (2, 3), (3, 2)},
(2, 3): {(1, 3), (2, 2), (2, 4), (3, 3)},
(2, 4): {(1, 4), (2, 3), (3, 4)},
(3, 0): {(2, 0), (3, 1)},
(3, 1): {(2, 1), (3, 0), (3, 2)},
(3, 3): {(2, 3), (3, 2), (3, 4)}}
Above is a dictionary that I have obtained from a 2D List:
keys -- tuples (co-ordinates)
values -- set of tuples (co-ordinates)
The co-ordinates are cells in the 2D list.
My goal is to compare the value of given key with next key.
example: compare {(0, 2), (0, 4), (1, 3)} with (0, 4).
If the key is present in the value of the previous key then I would like to update the first value with values of the key that was found. For the given example: the result should be something like: {(0, 2), (0, 4), (1, 3), (0, 3), (1, 4)}.
I would like to know if this is even possible? Is there a way to compare values of a dictionary with keys of the same dictionary?
I was also thinking of using DFS but I do not have all the vertices for that. Is DFS the right approach?
If you only want to do this to a given keys value then you could make a function to do this:
def get_value(data, key):
keys = tuple(data)
value = data[key]
next_value = keys[keys.index(key)+1]
next_value = data[next_value]
return value | next_value if key in value else value | next_value
You can use it like this:
get_value(data, (0, 3))
#{(1, 3), (1, 4), (0, 4), (0, 3), (0, 2)}
If you want to do this to the whole dict then you could make a lookahead iterator, and compare them that way:
from itertools import zip_longest
data = {(0, 0): {(0, 1), (1, 0)},
(0, 3): {(0, 2), (0, 4), (1, 3)},
(0, 4): {(0, 3), (1, 4)},
(1, 1): {(0, 1), (1, 0), (1, 2), (2, 1)},
(1, 2): {(0, 2), (1, 1), (1, 3), (2, 2)},
(2, 0): {(1, 0), (2, 1), (3, 0)},
(2, 2): {(1, 2), (2, 1), (2, 3), (3, 2)},
(2, 3): {(1, 3), (2, 2), (2, 4), (3, 3)},
(2, 4): {(1, 4), (2, 3), (3, 4)},
(3, 0): {(2, 0), (3, 1)},
(3, 1): {(2, 1), (3, 0), (3, 2)},
(3, 3): {(2, 3), (3, 2), (3, 4)}}
lookahead = iter(data.items()); next(lookahead)
for (k,v), (_k, _v) in zip_longest(data.items(), lookahead, fillvalue=(None,None)):
if all((_k, _v)) and v >= {_k}:
v |= _v
This results in:
{(0, 0): {(0, 1), (1, 0)},
(0, 3): {(1, 3), (1, 4), (0, 4), (0, 3), (0, 2)},
(0, 4): {(0, 3), (1, 4)},
(1, 1): {(1, 3), (0, 2), (2, 1), (1, 0), (0, 1), (1, 2), (2, 2), (1, 1)},
(1, 2): {(1, 3), (1, 1), (0, 2), (2, 2)},
(2, 0): {(3, 0), (1, 0), (2, 1)},
(2, 2): {(3, 2), (1, 3), (2, 1), (2, 3), (1, 2), (3, 3), (2, 2), (2, 4)},
(2, 3): {(1, 3), (3, 3), (1, 4), (2, 3), (2, 2), (3, 4), (2, 4)},
(2, 4): {(3, 4), (2, 3), (1, 4)},
(3, 0): {(3, 2), (3, 0), (3, 1), (2, 1), (2, 0)},
(3, 1): {(3, 0), (3, 2), (2, 1)},
(3, 3): {(3, 4), (3, 2), (2, 3)}}
Note if you’re using python 3 you shouldn’t have an issue with ordering otherwise it’s safest to ensure the dict is in correct order and use a collections.OrderedDict especially in py2
I have a list say x=[1,2,3,4,5] and want to look at different permutations of this list taken two number at a time.
x=[1,2,3,4,5]
from itertools import permutations
y=list(i for i in permutations(x,2) if i[0]<i[1])
print(y)
output: [(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
But i also want [(1,1),(2,2),(3,3),(4,4),(5,5)] in the output.How to rectify this?
You want combinations_with_replacement() instead:
>>> from itertools import combinations_with_replacement
>>> list(combinations_with_replacement(x, 2))
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 2), (2, 3), (2, 4), (2, 5), (3, 3), (3, 4), (3, 5), (4, 4), (4, 5), (5, 5)]
I'd like to have an algorithm which calculates the transitions from these STATE/ACTIONS tuples. For example, if you are in state (2,1) you can transition to states [(2,2),(2,0)]. This is calculated by adding the actions [(0,1),(-1,0)], to the state (2,1). I'm somewhat new to python so I'm wondering what the most efficient way to do this is. I would end up with a dict similar to the ACTIONS dict. Thanks!!
STATES=[
(0,0),
(0,1),
(0,2),
(0,3),
(1,0),
# '1,1',
(1,2),
(1,3),
(2,0),
(2,1),
(2,2),
(2,3)
]
ACTIONS={
(0,0):[(0,1),(1,0)],
(0,1):[(0,1),(0,-1)],
(0,2):[(0,-1),(1,0),(0,1)],
(0,3):[(0,-1),(1,0)],
(1,0):[(1,0),(-1,0)],
# '1,1':0,
(1,2):[(1,0),(-1,0),(0,1)],
(1,3):[],
(2,0):[(0,1),(-1,0)],
(2,1):[(0,1),(0,-1)],
(2,2):[(0,-1),(-1,0),(0,1)],
(2,3):[]
}
You can set up a list of possible offsets corresponding to the actions available. From there, you build a dictionary of actions using the state as key.
STATES=[(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
offsets = [(0, 1),(-1, 0), (1, 1), (-1, -1)]
actions = {}
for state in STATES:
actions[state] = [(state[0] + off0, state[1] + off1) for off0, off1 in offsets]
actions
output:
{(0, 0): [(0, 1), (-1, 0), (1, 1), (-1, -1)],
(0, 1): [(0, 2), (-1, 1), (1, 2), (-1, 0)],
(0, 2): [(0, 3), (-1, 2), (1, 3), (-1, 1)],
(0, 3): [(0, 4), (-1, 3), (1, 4), (-1, 2)],
(1, 0): [(1, 1), (0, 0), (2, 1), (0, -1)],
(1, 2): [(1, 3), (0, 2), (2, 3), (0, 1)],
(1, 3): [(1, 4), (0, 3), (2, 4), (0, 2)],
(2, 0): [(2, 1), (1, 0), (3, 1), (1, -1)],
(2, 1): [(2, 2), (1, 1), (3, 2), (1, 0)],
(2, 2): [(2, 3), (1, 2), (3, 3), (1, 1)],
(2, 3): [(2, 4), (1, 3), (3, 4), (1, 2)]}