Given a list of coordinates add values to those coordinates until shortest path list changes

十年热恋 提交于 2021-01-28 13:30:31

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!