Учитывая список координат, добавляйте значения к этим координатам, пока кратчайший путь не изменится. - PullRequest
1 голос
/ 11 июля 2020

Итак, я несколько дней задавал вопрос go (вот вопрос ) в основном то, что я пытаюсь сделать, - это 3D-массив и список координат, добавляю значения к этим координаты до изменения кратчайшего пути, пользователь Mohammed Kashif поможет мне с моим вопросом, но это было с 2D-списком координат, теперь я пытаюсь сделать то же самое, но с 3D-списком координат , первый список координат с первыми 5 массивами и второй список координат со следующими 5 массивами. Вот что я пробую: (Это всего лишь пример, мой список координат, а трехмерный массив может иметь больше элементов)

import numpy as np
import networkx as nx
from copy import deepcopy

arr = np.array ([[[  0., 303.,  43.,  26.,  20.],
                  [  0.,   0.,   0.,   0.,   0.],
                  [  0.,  21.,   0.,   8.,   0.],
                  [  0.,  47.,   5.,   0.,   4.],
                  [  0.,  35.,   0.,   1.,   0.]],

                 [[  0., 356.,  40.,  32.,  49.],
                  [  0.,   0.,   0.,   0.,   0.],
                  [  0.,  36.,   0.,   1.,   0.],
                  [  0.,  25.,   1.,   0.,   1.],
                  [  0.,  40.,   0.,   3.,   0.]],

                 [[  0., 372.,  27.,  34.,  44.],
                  [  0.,   0.,   0.,   0.,   0.],
                  [  0.,  37.,   0.,   3.,   0.],
                  [  0.,  41.,   8.,   0.,   1.],
                  [  0.,  34.,   0.,   6.,   0.]],

                 [[  0., 300.,  46.,  37.,  46.],
                  [  0.,   0.,   0.,   0.,   0.],
                  [  0.,  40.,   0.,   1.,   0.],
                  [  0.,  48.,   2.,   0.,   5.],
                  [  0.,  43.,   0.,   2.,   0.]],

                 [[  0., 321.,  42.,  22.,  22.],
                  [  0.,   0.,   0.,   0.,   0.],
                  [  0.,  42.,   0.,   3.,   0.],
                  [  0.,  20.,   3.,   0.,   5.],
                  [  0.,  20.,   0.,   9.,   0.]],

                 [[  0., 319.,  48.,  21.,  39.],
                  [  0.,   0.,   0.,   0.,   0.],
                  [  0.,  29.,   0.,   0.,   1.],
                  [  0.,  38.,   0.,   0.,   7.],
                  [  0.,  40.,   1.,   5.,   0.]],

                 [[  0., 374.,  46.,  25.,  28.],
                  [  0.,   0.,   0.,   0.,   0.],
                  [  0.,  25.,   0.,   0.,   2.],
                  [  0.,  44.,   0.,   0.,   6.],
                  [  0.,  44.,   2.,   9.,   0.]],

                 [[  0., 341.,  34.,  21.,  49.],
                  [  0.,   0.,   0.,   0.,   0.],
                  [  0.,  27.,   0.,   0.,   9.],
                  [  0.,  25.,   0.,   0.,   8.],
                  [  0.,  49.,   1.,   1.,   0.]],

                 [[  0., 310.,  30.,  44.,  47.],
                  [  0.,   0.,   0.,   0.,   0.],
                  [  0.,  34.,   0.,   0.,   2.],
                  [  0.,  21.,   0.,   0.,   8.],
                  [  0.,  37.,   9.,   8.,   0.]],

                 [[  0., 321.,  27.,  44.,  31.],
                  [  0.,   0.,   0.,   0.,   0.],
                  [  0.,  21.,   0.,   0.,   5.],
                  [  0.,  41.,   0.,   0.,   1.],
                  [  0.,  41.,   1.,   5.,   0.]]])

n = 5          #Number of array for each path list and coordinates list 
graphs = []
pathaux = []

for i in arr:
    graphs.append(nx.from_numpy_array(i, create_using = nx.DiGraph)) #Create graphs from numpy array

for graph in graphs:
    pathaux.append(nx.shortest_path(graph, 0, 1, weight = 'weight'))   #Find the shortest path

path = [pathaux[i: i+n] for i in range(0, len(pathaux), n)] #Creates a 3D list "separating" for each 5 arrays 

print(path)
#path = [[[0, 4, 3, 2, 1], [0, 3, 1], [0, 2, 1], [0, 3, 2, 1], [0, 3, 1]], [[0, 3, 4, 2, 1], [0, 4, 2, 1], [0, 3, 1], [0, 2, 4, 3, 1], [0, 2, 1]]]

#path[0] = [[0, 4, 3, 2, 1], [0, 3, 1], [0, 2, 1], [0, 3, 2, 1], [0, 3, 1]] #Shortest path for the first 5 arrays
#path[1] = [[0, 3, 4, 2, 1], [0, 4, 2, 1], [0, 3, 1], [0, 2, 4, 3, 1], [0, 2, 1]] #Shortest path for the next 5 arrays

#Here are the 3D list of coordinates, the first two pair is for the first 5 array, the next four pairs are for the other 5 arrays
coordinates = [[[4, 3], [3, 2]], [[3, 4], [4, 2], [2, 4], [4, 3]]]

for i in coordinates:
    for x,y in i:
        # Make deepcopies of path and arr
        # For the first iteration, set newpath = path
        new_path = deepcopy(pathaux)
        temp_arr = deepcopy(arr)

        # Set counter for each coordinate to zero
        cnt = 0

        # Iterate till a change in path is observed
        while pathaux == 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 the first 5 arrays
For coordinates X=4 and Y=3 the change is at 3
For coordinates X=3 and Y=2 the change is at 1

#For the next 5 arrays
For coordinates X=3 and Y=4 the change is at 1
For coordinates X=4 and Y=2 the change is at 1
For coordinates X=2 and Y=4 the change is at 1
For coordinates X=4 and Y=3 the change is at 3

Как видите, координаты верны, но значения изменения неверны, если я делаю это вручную, добавляя значения к координатам, пока мой список не изменится, это мой реальный результат:

#For the first 5 arrays
For coordinates X=4 and Y=3 the change is at 5
For coordinates X=3 and Y=2 the change is at 6

#For the next 5 arrays
For coordinates X=3 and Y=4 the change is at 1
For coordinates X=4 and Y=2 the change is at 1
For coordinates X=2 and Y=4 the change is at 3
For coordinates X=4 and Y=3 the change is at 3

I подумал о том, может быть, изменить форму arr из 3D-массива в 4D-массив с формой (2, 5, 5, 5), но я считаю, что мне нужно сделать двойное for-loop, поэтому он медленнее, я знаю, что это длинный вопрос, но я не знаю как заставить соответствующие первые 5 массивов с первым кратчайшим путем и первым списком координат работать вместе и сделать то же самое для следующих пяти массивов с соответствующими кратчайшим путем и координатами. Опять же, извините за длинный вопрос, любая помощь будет оценена, спасибо!

1 Ответ

2 голосов
/ 13 июля 2020

Перегородки следует рассматривать отдельно. Примените следующие изменения к существующему коду, и он должен работать:

...

arr_partition = [arr[i: i+n] for i in range(0, len(arr), n)]
j = 0
for i in coordinates:
    print("The tree is", j)
    for x, y in i:
        new_path = deepcopy(path[j])
        temp_arr = deepcopy(arr_partition[j])
        cnt = 0
        while path[j] == new_path:
            ...
    print()
    j += 1
        
...

Вывод:

The tree is 0
For coordinates X=4 and Y=3 the change is at 5
For coordinates X=3 and Y=2 the change is at 6

The tree is 1
For coordinates X=3 and Y=4 the change is at 1
For coordinates X=4 and Y=2 the change is at 1
For coordinates X=2 and Y=4 the change is at 3
For coordinates X=4 and Y=3 the change is at 3
...