Инициализация графа с использованием словарей для алгоритма флойд на неориентированных графах?

Хотелось бы узнать, как реализовать флойд на неориентированном графе. В этой реализации

for k in graph:
    for i in graph:
        for j in graph:
            if dist[i][k] + dist[k][j] < dist[i][j]:
                dist[i][j] = dist[i][k] + dist[k][j]
                pred[i][j] = pred[k][j]

Я могу получить матрицу смежности:

   __0 __1 __2 __3 __4 

0|  0  28  38  33  63 

1|  inf  0  10  60  44 

2|  inf  inf  0  50  80 

3|  inf  inf  inf  0  30 

4|  inf  inf  inf  inf  0 

Это ориентированный граф. Это нормально, но я бы хотел, чтобы матрица смежности отображала неориентированные графики. Насколько я понимаю, для неориентированного графа эти пути должны быть отражены по диагонали 0, но я не уверен, как это сделать.

Я пытался:

for k in graph:
    for i in graph:
        for j in graph:
            if dist[i][k] + dist[k][j] < dist[i][j]:
                dist[i][j] = dist[i][k] + dist[k][j]
                dist[j][i] = dist[i][k] + dist[k][j]
                pred[i][j] = pred[k][j]

Но мой график оказывается неправильным, и похоже, что алгоритм проходит через ненужные ребра, чтобы добраться до нужной вершины.

   __0 __1 __2 __3 __4 

0|  0  48  38  93  63 

1|  48  0  110  60  44 

2|  38  110  0  110  80 

3|  93  60  110  0  30 

4|  63  inf  80  inf  0 

Вот график, который я использую:

{0 : {1:28, 3:33},
1 : {2:10, 4:44},
2 : {3:50},
3 : {4:30},
4 : {}}

РЕДАКТИРОВАТЬ: вот полный код

import ast

def floyd(graph):
    dist = {}
    pred = {} 

    for u in graph:
        dist[u] = {}
        pred[u] = {}

        for v in graph:
            dist[u][v] = float('INF')
            pred[u][v] = -1
            dist[u][u] = 0
        for z in graph[u]:
            dist[u][z] = graph[u][z]
            pred[u][z] = u

    for k in graph:
        for i in graph:
            for j in graph:
                if dist[i][k] + dist[k][j] < dist[i][j]:
                    dist[i][j] = dist[i][k] + dist[k][j]

    return dist, pred

graph = {}
graph = ast.literal_eval(open("file2.txt").read())
print graph

dist, pred = floyd(graph)

print "  ",
for j in dist: print "__" + str(j),
print "\n"
for i in dist:
        print str(i) + "|",
        for v in dist: print " %s" % (dist[i][v]),
        print "\n"

person moomin    schedule 02.03.2016    source источник
comment
Версия неориентированного графа идентична версии ориентированного графа. Если ваш исходный немодифицированный алгоритм не работает на ориентированных графах, вероятно, это связано с неправильной настройкой матрицы смежности.   -  person user2357112 supports Monica    schedule 02.03.2016
comment
Можете ли вы показать нам свой полный код и пример ввода, на котором он не работает?   -  person Tony Babarino    schedule 02.03.2016
comment
@ user2357112 Он действительно работает с неориентированными графиками, и я, по сути, распечатываю словарь Python, просто с форматированием. Может быть, это все, но я все еще не вижу, что происходит. Отредактирую вопрос.   -  person moomin    schedule 02.03.2016
comment
Для вашего неориентированного графа, добавляете ли вы все ребра в ваш словарь другим путем, например, добавляя 0: 33 к ребрам узла 3?   -  person Marius    schedule 02.03.2016
comment
@ Тони Бабарино Я отредактировал вопрос и включил код.   -  person moomin    schedule 02.03.2016
comment
@Marius Нет, только один способ, но я бы хотел, чтобы Флойд интерпретировал его как неориентированный граф.   -  person moomin    schedule 02.03.2016
comment
@moomin это круто, но мы все еще не можем запустить его, потому что не знаем, что находится в file2.txt. Прочтите stackoverflow.com/help/mcve. Кроме того, я все еще не уверен, в чем основная проблема - чего вы не хотите достичь и где ваш код дает сбой. Вопрос слишком хаотичный.   -  person Tony Babarino    schedule 02.03.2016
comment
@TonyBabarino Я уже включил содержимое файла в исходный вопрос. Это ввод из словаря выше. Я не уверен, где происходит сбой кода, я изначально думал, что floyd необходимо изменить для работы с неориентированными графами, но, видимо, что-то не так с тем, как я настроил свою матрицу смежности? Оператор печати должен быть в порядке, я просто печатаю отформатированную версию содержимого словаря, поэтому я могу точно указать только на инициализацию словарей внутри floyd (), а не на сам алгоритм floyd.   -  person moomin    schedule 02.03.2016


Ответы (1)


Я думаю, вашу проблему можно решить, просто отразив все ребра в вашем словаре графов, например:

graph = {0 : {1:28, 3:33},
1 : {2:10, 4:44},
2 : {3:50},
3 : {4:30},
4 : {}}
# Mirror all edges
for u in graph:
    for v in graph[u]:
        if not u in graph[v]:
            graph[v][u] = graph[u][v]

Это самый простой способ настроить ввод как неориентированный граф (хотя, очевидно, теперь вам нужно быть более осторожным, если вы затем редактируете / удаляете ребра). Когда я вставляю это в ваш код, я получаю:

 __0__1__2__3__4

0| 0 28 38 33 63

1| 28 0 10 60 44

2| 38 10 0 50 54

3| 33 60 50 0 30

4| 63 44 54 30 0
person Marius    schedule 02.03.2016
comment
Это хорошее быстрое исправление для текущего прицела. Я думал, что проблема в реализации флойда, но видимо все в порядке. В любом случае, благодарю Вас. - person moomin; 02.03.2016