Python get all paths from graph - python

I'm trying to find the paths that a user could take through a website. I have represented my graph using this format:
graph = { 0 : [1, 2],
1 : [3, 6, 0],
2 : [4, 5, 0],
3 : [1],
4 : [6, 2],
5 : [6, 2],
6 : [1, 4, 5]}
I have implemented a depth first algorithm, but it needs a change for it to be useful. It needs to return the path and not just the nodes in the order it goes to them.
visitedList = [[]]
def depthFirst(graph, currentVertex, visited):
visited.append(currentVertex)
for vertex in graph[currentVertex]:
if vertex not in visited:
depthFirst(graph, vertex, visited)
return visited
traversal = depthFirst(graph, 0, visitedList)
print('Nodes visited in this order:')
print(visitedList)
That function returns this:
[[], 0, 1, 3, 6, 4, 2, 5]
Whereas I want something like this:
[[0, 1, 3], [0, 1, 6], [0, 2, 4, 6], [0, 2, 5, 6]]

When passing a list in python it does not deep copy. Using list.copy() can really help here. I'm not sure this is what you wanted but here is the code:
visitedList = [[]]
def depthFirst(graph, currentVertex, visited):
visited.append(currentVertex)
for vertex in graph[currentVertex]:
if vertex not in visited:
depthFirst(graph, vertex, visited.copy())
visitedList.append(visited)
depthFirst(graph, 0, [])
print(visitedList)
It returns all the paths.
[[], [0, 1, 3], [0, 1, 6, 4, 2, 5], [0, 1, 6, 4, 2], [0, 1, 6, 4], [0, 1, 6, 5, 2, 4], [0, 1, 6, 5, 2], [0, 1, 6, 5], [0, 1, 6], [0, 1], [0, 2, 4, 6, 1, 3], [0, 2, 4, 6, 1], [0, 2, 4, 6, 5], [0, 2, 4, 6], [0, 2, 4], [0, 2, 5, 6, 1, 3], [0, 2, 5, 6, 1], [0, 2, 5, 6, 4], [0, 2, 5, 6], [0, 2, 5], [0, 2], [0]]
List copy worked for me in python3.

Related

delete elements from lists in a nested list [duplicate]

This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Closed 1 year ago.
I am using python, I have a nested list like this
sequences_list = [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]
I want to get a sort of sequences like this
sequences_list = [[0], [0, 1], [0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4, 5]]
this is my code
k = 1
j = 0
while (k <= len(sequences_list)):
del sequences_list[j][k:]
k = k+1
j = j+1
print(sequences_list)
the result i get is
[[0], [0], [0], [0], [0], [0]]
Try this one
sequences_list = [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]
print([element[0:po+1] for po,element in enumerate(sequences_list)])

Create a 4D list from a 3D list

I'm working with lists and something came up, so let's say I have a 3D list and I want to create a 4D list, so every two positions in the inner lists split, here is what I tried
mylist = [[[0, 2, 1], [0, 3, 1], [0, 4, 3, 1], [0, 4, 3, 1], [0, 3, 2, 1], [0, 2, 3, 4, 1]],
[[0, 2, 1], [0, 4, 2, 3, 1], [0, 4, 3, 1], [0, 4, 3, 1], [0, 3, 2, 1], [0, 2, 3, 4, 1]]]
newlist = [mylist[i: i + 2] for i in range(0, len(mylist), 2)]
print(newlist)
newlist = [[[[0, 2, 1], [0, 3, 1], [0, 4, 3, 1], [0, 4, 3, 1], [0, 3, 2, 1], [0, 2, 3, 4, 1]],
[[0, 2, 1], [0, 4, 2, 3, 1], [0, 4, 3, 1], [0, 4, 3, 1], [0, 3, 2, 1], [0, 2, 3, 4, 1]]]]
but I was expecting something like:
newlist = [[[[0, 2, 1], [0, 3, 1]], [[0, 4, 3, 1], [0, 4, 3, 1]], [[0, 3, 2, 1], [0, 2, 3, 4, 1]]],
[[0, 2, 1], [0, 4, 2, 3, 1]], [[0, 4, 3, 1], [0, 4, 3, 1]], [[0, 3, 2, 1], [0, 2, 3, 4, 1]]]]
I believe I'm missing a for in my list comprehension something like:
newlist = [[mylist[j: j + 2] for j in i] for i in range(0, len(my list), 2)]
but I'm having an error and I can't figure it out what is the problem, so any help will appreciated, thank you so much!
Try this:
newlist=[[list(ls) for ls in zip(i[::2], i[1::2])] for i in mylist]
print(newlist)
Output:
[[[[0, 2, 1], [0, 3, 1]],
[[0, 4, 3, 1], [0, 4, 3, 1]],
[[0, 3, 2, 1], [0, 2, 3, 4, 1]]],
[[[0, 2, 1], [0, 4, 2, 3, 1]],
[[0, 4, 3, 1], [0, 4, 3, 1]],
[[0, 3, 2, 1], [0, 2, 3, 4, 1]]]]
Here is a possible solution. You were very close!
newlist = [[lst[i:i+2] for i in range(0, len(lst), 2)] for lst in mylist]

How to reconcile itertools.product with multiprocessing?

I have the code shared at https://codereview.stackexchange.com/q/185129/157474. And I'm trying to use multiprocessing. I used such a remodeling:
count=1
def foo(i):
global count
dobre2=[]
if tuple(reversed(i)) >= tuple(i):
a = ['v{}'.format(x%2) for x in i]
# the rest of the code
return dodane_pary
And:
if __name__ == '__main__':
pool = mul.Pool(4)
result = pool.map(foo, itertools.product(tuple(range(2)), repeat=4))
pool.close()
pool.join()
print (result)
Instead:
count=1
dobre2=[]
for i in itertools.product(tuple(range(2)), repeat=4):
if tuple(reversed(i)) >= tuple(i):
a = ['v{}'.format(x%2) for x in i]
# the rest of the code
Expected output:
[[0, 2, 4, 6], [0, 2, 4, 1], [0, 2, 3, 8], [0, 2, 3, 5], [2, 3, 8, 7], [6, 1, 3, 8], [2, 3, 5, 9], [11, 0, 2, 3], [11, 4, 1, 5], [7, 1, 5, 9]]
Unfortunately, I do not receive the expected exit, but the list in this form:
[[[0, 2, 4, 6]], [[0, 2, 4, 6], [0, 2, 4, 1]], [[0, 2, 1, 4]], [[0, 2, 4, 6], [0, 2, 4, 1], [0, 2, 3, 5]], [[0, 2, 1, 4]], [[0, 2, 1, 4], [2, 1, 4, 3]], [[0, 2, 4, 6], [0, 2, 4, 1], [0, 2, 3, 5], [0, 7, 9, 8]], [[0, 2, 1, 4], [2, 1, 4, 3], [0, 5, 7, 3]], [[0, 2, 1, 4], [2, 1, 4, 3], [0, 5, 7, 3]], [[0, 2, 1, 4], [2, 1, 4, 3], [0, 5, 7, 3], [5, 0, 2, 1]], [[0, 2, 1, 4], [2, 1, 4, 3], [0, 5, 7, 3], [5, 0, 2, 1]], [[0, 2, 1, 4], [2, 1, 4, 3], [0, 5, 7, 3], [5, 0, 2, 1], [1, 4, 3, 7]], [[0, 2, 1, 4], [2, 1, 4, 3], [0, 5, 7, 3], [5, 0, 2, 1], [1, 4, 3, 7]], [[0, 2, 1, 4], [2, 1, 4, 3], [0, 5, 7, 3], [5, 0, 2, 1], [1, 4, 3, 7]], [[0, 2, 1, 4], [2, 1, 4, 3], [0, 5, 7, 3], [5, 0, 2, 1], [1, 4, 3, 7]], [[0, 2, 1, 4], [2, 1, 4, 3], [0, 5, 7, 3], [5, 0, 2, 1], [1, 4, 3, 7], [3, 7, 5, 9]]]
In addition, every time I start the program, I get some changed results as if the processes were randomly assigned. What am I doing wrong? How to synchronize it well?

finding paths in graphs with integer stack or array

Given a graph (ordered DAG) represented using an adjacency matrix
g = [
[0,1,1,0,0,0,0],
[0,0,0,1,0,0,0],
[0,0,0,1,0,0,0],
[0,0,0,0,1,1,0],
[0,0,0,0,0,0,1],
[0,0,0,0,0,0,1],
[0,0,0,0,0,0,0]
]
I wrote the following to figure out all the longest paths in the graph starting from the first node, node 0.
from collections import deque
stack = deque()
stack.append([0])
current_longest = 1
paths = []
N = len(g[0])
while stack:
cur_path = stack.pop()
print(cur_path)
last_node = cur_path[-1]
any_n = False
for new_node in range(last_node + 1, N):
if g[last_node][new_node] == 1:
any_n = True
stack.append(cur_path + [new_node])
if any_n == False:
if len(cur_path) > current_longest:
nmb_paths = 1
paths = []
paths.append(cur_path)
current_longest = len(cur_path)
elif len(cur_path) == current_longest:
nmb_paths += 1
paths.append(cur_path)
print(f"paths = {paths}")
The output of this:
[0]
[0, 2]
[0, 2, 3]
[0, 2, 3, 5]
[0, 2, 3, 5, 6]
[0, 2, 3, 4]
[0, 2, 3, 4, 6]
[0, 1]
[0, 1, 3]
[0, 1, 3, 5]
[0, 1, 3, 5, 6]
[0, 1, 3, 4]
[0, 1, 3, 4, 6]
paths = [[0, 2, 3, 5, 6], [0, 2, 3, 4, 6], [0, 1, 3, 5, 6], [0, 1, 3, 4, 6]]
but I am now trying to figure out if I can do this without the luxury of an array stack. So if I can't store arrays as elements of the stack, I can only use an integer stack or a normal array. I am stuck on this, I think it's a matter of keeping track of the length of the list, as it grows, storing each path, and if it doesn't grow, storing the path, but a little stumped atm, any hints?
not much interest, but thought I'd put up my solution anyway, in case it helps anyone (I was implementing this in C so it was a pain having to write an ArrayStack) this was my prototype:
g = [
[0,1,1,0,0,0,0],
[0,0,0,1,0,0,0],
[0,0,0,1,0,0,0],
[0,0,0,0,1,1,0],
[0,0,0,0,0,0,1],
[0,0,0,0,0,0,1],
[0,0,0,0,0,0,0]
]
N = len(g[0])
nmb_paths = 1
current_longest = 1
paths = []
array = [0]
current_length = 1
visited = [0] * N
visited[0] = 1
pred = [-1] * N
while current_length > 0:
last_node = array[current_length-1]
any_n = False
new_node = last_node + 1
print('paths = ', paths)
while not any_n and new_node < N:
if g[last_node][new_node] == 1 and visited[new_node] != 1:
if pred[new_node] != last_node:
pred[new_node] = last_node
any_n = True
array.append(new_node)
visited[new_node] = 1
current_length += 1
last_node = new_node
if current_length > current_longest:
paths = []
app = array.copy()
paths.append(app)
current_longest = current_length
nmb_paths = 1
elif current_length == current_longest:
app = array.copy()
paths.append(app)
nmb_paths += 1
new_node+=1
if any_n == False:
final = array[current_length - 1]
del array[current_length-1]
visited[final] = 0
for j in range(final+1, N):
pred[j] = -1
current_length -= 1
the progression of paths:
paths = []
paths = [[0, 1]]
paths = [[0, 1, 3]]
paths = [[0, 1, 3, 4]]
paths = [[0, 1, 3, 4, 6]]
paths = [[0, 1, 3, 4, 6]]
paths = [[0, 1, 3, 4, 6]]
paths = [[0, 1, 3, 4, 6]]
paths = [[0, 1, 3, 4, 6], [0, 1, 3, 5, 6]]
paths = [[0, 1, 3, 4, 6], [0, 1, 3, 5, 6]]
paths = [[0, 1, 3, 4, 6], [0, 1, 3, 5, 6]]
paths = [[0, 1, 3, 4, 6], [0, 1, 3, 5, 6]]
paths = [[0, 1, 3, 4, 6], [0, 1, 3, 5, 6]]
paths = [[0, 1, 3, 4, 6], [0, 1, 3, 5, 6]]
paths = [[0, 1, 3, 4, 6], [0, 1, 3, 5, 6]]
paths = [[0, 1, 3, 4, 6], [0, 1, 3, 5, 6]]
paths = [[0, 1, 3, 4, 6], [0, 1, 3, 5, 6], [0, 2, 3, 4, 6]]
paths = [[0, 1, 3, 4, 6], [0, 1, 3, 5, 6], [0, 2, 3, 4, 6]]
paths = [[0, 1, 3, 4, 6], [0, 1, 3, 5, 6], [0, 2, 3, 4, 6]]
paths = [[0, 1, 3, 4, 6], [0, 1, 3, 5, 6], [0, 2, 3, 4, 6]]
paths = [[0, 1, 3, 4, 6], [0, 1, 3, 5, 6], [0, 2, 3, 4, 6], [0, 2, 3, 5, 6]]
paths = [[0, 1, 3, 4, 6], [0, 1, 3, 5, 6], [0, 2, 3, 4, 6], [0, 2, 3, 5, 6]]
paths = [[0, 1, 3, 4, 6], [0, 1, 3, 5, 6], [0, 2, 3, 4, 6], [0, 2, 3, 5, 6]]
paths = [[0, 1, 3, 4, 6], [0, 1, 3, 5, 6], [0, 2, 3, 4, 6], [0, 2, 3, 5, 6]]
paths = [[0, 1, 3, 4, 6], [0, 1, 3, 5, 6], [0, 2, 3, 4, 6], [0, 2, 3, 5, 6]]

Sum a staggered array "columns" in this way

Let's say I have the following array
import numpy as np
matrix = np.array([
[[1, 2, 3, 4], [0, 1], [2, 3, 4, 5]],
[[1, 2, 3], [4], [0, 1], [2, 0], [0, 0]],
[[2, 2], [3, 4, 0], [1, 1, 0, 0], [0]],
[[6, 3, 3, 4, 0], [4, 2, 3, 4, 5]],
[[1, 2, 3, 2], [0, 1, 2], [3, 4, 5]]])
As you can see, it's a staggered array. What I want to do is to sum the elements in a way so that the output is:
[11, 11, 15, 18, 0, 8, 9, 9, 12, 15]
I want to sum the elements in the "columns" of the matrix, but I don't know how to do it.
As mentioned by juanpa.arrivillaga in the comments, you don't have a multi-dimensional array, you have a 1-D array of lists of lists. You need to flatten the inner lists first :
>>> np.array([[z for y in x for z in y] for x in matrix])
array([[1, 2, 3, 4, 0, 1, 2, 3, 4, 5],
[1, 2, 3, 4, 0, 1, 2, 0, 0, 0],
[2, 2, 3, 4, 0, 1, 1, 0, 0, 0],
[6, 3, 3, 4, 0, 4, 2, 3, 4, 5],
[1, 2, 3, 2, 0, 1, 2, 3, 4, 5]])
It should be much easier to solve your problem now. This matrix has a shape of (5,10), and supports T for transposition and np.sum() for summing rows or columns.
You didn't write any code, so I won't solve the problem completely, but with this matrix, you're one step away from:
array([11, 11, 15, 18, 0, 8, 9, 9, 12, 15])

Categories