问题
So I got a question and I was hoping you can point me to the right direction, full context problem, I have a 3D numpy array that I use to create graphs using Networkx and with these graphs I find the shortest path. What I need is that given a set of coordinates add "1" in these coordinates until the list of the shortest path changes (This is just an example, the list of coordinates can have more coordinates), my code is the following:
import numpy as np
import networkx as nx
arr = np.array([[[ 0., 378., 50., 174., 125.],
[ 0., 0., 0., 0., 0.],
[ 0., 154., 0., 20., 0.],
[ 0., 111., 15., 0., 22.],
[ 0., 16., 0., 12., 0.]],
[[ 0., 488., 64., 98., 117.],
[ 0., 0., 0., 0., 0.],
[ 0., 151., 0., 24., 0.],
[ 0., 35., 13., 0., 24.],
[ 0., 71., 0., 10., 0.]],
[[ 0., 374., 110., 187., 189.],
[ 0., 0., 0., 0., 0.],
[ 0., 195., 0., 12., 0.],
[ 0., 42., 14., 0., 21.],
[ 0., 16., 0., 19., 0.]]])
graphs = []
path = []
for i in arr:
graphs.append(nx.from_numpy_array(i, create_using = nx.DiGraph)) #Create graphs from numpy array
for graph in graphs:
path.append(nx.shortest_path(graph, 0, 1, weight = 'weight')) #Find the shortest path
print(path)
#path = [[0, 2, 3, 4, 1], [0, 2, 3, 1], [0, 2, 3, 4, 1]] #Shortest path for each array
coordinates = [[2, 3], [3, 4]] #List of coordinates in the array that I want to add 1
I want to iterate through my list of coordinates and be adding 1 until my path list changes, for example
#My first coordinate is [2, 3] so I add 1 to these coordinates and calculate the shortest path again
#to see if the path changes
arr[:, 2, 3] = arr[:, 2, 3] + 1 #Path = [[0, 2, 3, 4, 1], [0, 2, 3, 1], [0, 2, 3, 4, 1]]
arr[:, 2, 3] = arr[:, 2, 3] + 2 #Path = [[0, 2, 3, 4, 1], [0, 2, 3, 1], [0, 2, 3, 4, 1]]
...
arr[:, 2, 3] = arr[:, 2, 3] + 9 #Path = [[0, 2, 3, 4, 1], [0, 2, 3, 1], [0, 2, 3, 4, 1]]
arr[:, 2, 3] = arr[:, 2, 3] + 10 #Path = [[0, 2, 3, 4, 1], [0, 3, 1], [0, 2, 3, 4, 1]] #Here the path changes so I keep the 9
After I finish with the first coordinate, then I go to the second one.
#The second coordinate is [3, 4] so...
arr[:, 3, 4] = arr[:, 3, 4] + 1 #Path = [[0, 2, 3, 4, 1], [0, 2, 3, 1], [0, 2, 3, 4, 1]]
...
arr[:, 3, 4] = arr[:, 3, 4] + 4 #Path = [[0, 2, 3, 4, 1], [0, 2, 3, 1], [0, 2, 3, 4, 1]]
arr[:, 3, 4] = arr[:, 3, 4] + 5 #Path = [[0, 2, 3, 4, 1], [0, 2, 3, 1], [0, 2, 3, 1]] #Here the path changes so I keep the 4
I was thinking about using a while loop something like while (path == newpath)
then continue adding one, but I'm not sure how to iterate through the list of coordinates and how to stop after it finds the value that changes the path, so any help will be appreciated, thank you!
回答1:
You were correct in assuming the structure of the loop. Just make sure that you copy the arrays properly. Here is the code:
from copy import deepcopy
for x,y in coordinates:
# Make deepcopies of path and arr
# For the first iteration, set newpath = path
new_path = deepcopy(path)
temp_arr = deepcopy(arr)
# Set counter for each coordinate to zero
cnt = 0
# Iterate till a change in path is observed
while path == new_path:
# Add 1 to x,y
temp_arr[:, x, y] = temp_arr[:, x, y] + 1
# Increment the counter
cnt += 1
# Reconstruct the graph and shortest path
temp_graph = []
new_path = []
for i in temp_arr:
temp_graph.append(nx.from_numpy_array(i, create_using = nx.DiGraph))
for graph in temp_graph:
new_path.append(nx.shortest_path(graph, 0, 1, weight = 'weight'))
# If we are out of the loop, this means that
# the shortest path has changed. Print the details.
print("For coordinates X={} and Y={} the change is at {}".format(x, y, cnt))
For a working version, you can check out this notebook.
Also, I am not sure if you always want to find out the shortest path between source=0
and target=1
, but you can change the values to your need. You can check out the documentation here.
References:
- Deepcopy Python List
来源:https://stackoverflow.com/questions/62732136/given-a-list-of-coordinates-add-values-to-those-coordinates-until-shortest-path