Алгоритм Питона Дейкстры - PullRequest
3 голосов
/ 15 февраля 2011

Я пытаюсь написать Алгоритм Дейкстры, однако я пытаюсь понять, как «сказать» определенные вещи в коде.Для наглядности вот столбцы, которые я хочу представить с помощью массивов:

   max_nodes  
   A  B  C         Length       Predecessor       Visited/Unvisited
A 0  1   2             -1                                              U
B 1  0   1             -1                                              U
C 2  1   0             -1                                              U

Итак, будет несколько массивов, как видно из моего кода ниже:

def dijkstra (graph, start, end)

network[max_nodes][max_nodes]
state  [max_nodes][length]
state2 [max_nodes][predecessor]
state3 [max_nodes][visited]
initialNode = 0

    for nodes in graph:
      D[max_nodes][length] = -1
      P[max_nodes][predecessor] = ""
      V[max_nodes][visited] = false

      for l in graph:

       length = lengthFromSource[node] + graph[node][l]
          if length < lengthFromSourceNode[w]:
             state[l][length] = x
             state2[l][predecessor] 
             state3[l][visited] = true
          x +=1

Часть, выделенная жирным шрифтомвот где я застрял - я пытаюсь реализовать этот раздел алгоритма:

3.Для текущего узла рассмотрите все его не посещенные соседи и вычислите их предварительное расстояние.Например, если текущий узел (A) имеет расстояние 6, а ребро, соединяющее его с другим узлом (B), равно 2, расстояние от B до A будет 6 + 2 = 8.Если это расстояние меньше ранее записанного расстояния, перезапишите расстояние
4. Когда мы закончим с учетом всех соседей текущего узла, отметьте его как посещенный.Посещенный узел больше не будет проверяться;его записанное расстояние является окончательным и минимальным

Я думаю, что я на правильном пути, я просто застрял в том, как сказать «начать с узла, получить длину от источника до узла,если длина меньше, перезапишите предыдущее значение, затем перейдите к следующему узлу

Ответы [ 2 ]

8 голосов
/ 20 апреля 2013

Я также использовал словарь для хранения сети.

создание сетевого словаря (предоставляется пользователем)

net = {'0':{'1':100, '2':300},
       '1':{'3':500, '4':500, '5':100},
       '2':{'4':100, '5':100},
       '3':{'5':20},
       '4':{'5':20},
       '5':{}
       }

алгоритм кратчайшего пути (пользователю необходимо указать начальный и конечный узлы)

def dijkstra(net, s, t):
    # sanity check
    if s == t:
        return "The start and terminal nodes are the same. Minimum distance is 0."
    if net.has_key(s)==False:
        return "There is no start node called " + str(s) + "."
    if net.has_key(t)==False:
        return "There is no terminal node called " + str(t) + "."
    # create a labels dictionary
    labels={}
    # record whether a label was updated
    order={}
    # populate an initial labels dictionary
    for i in net.keys():
        if i == s: labels[i] = 0 # shortest distance form s to s is 0
        else: labels[i] = float("inf") # initial labels are infinity
    from copy import copy
    drop1 = copy(labels) # used for looping
    ## begin algorithm
    while len(drop1) > 0:
        # find the key with the lowest label
        minNode = min(drop1, key = drop1.get) #minNode is the node with the smallest label
        # update labels for nodes that are connected to minNode
        for i in net[minNode]:
            if labels[i] > (labels[minNode] + net[minNode][i]):
                labels[i] = labels[minNode] + net[minNode][i]
                drop1[i] = labels[minNode] + net[minNode][i]
                order[i] = minNode
        del drop1[minNode] # once a node has been visited, it's excluded from drop1
    ## end algorithm
    # print shortest path
    temp = copy(t)
    rpath = []
    path = []
    while 1:
        rpath.append(temp)
        if order.has_key(temp): temp = order[temp]
        else: return "There is no path from " + str(s) + " to " + str(t) + "."
        if temp == s:
            rpath.append(temp)
            break
    for j in range(len(rpath)-1,-1,-1):
        path.append(rpath[j])
    return "The shortest path from " + s + " to " + t + " is " + str(path) + ". Minimum distance is " + str(labels[t]) + "."

# Given a large random network find the shortest path from '0' to '5'
print dijkstra(net=randNet(), s='0', t='5')
2 голосов
/ 15 февраля 2011

Во-первых, я предполагаю, что это домашняя задача, так как лучше всего не писать ее самостоятельно, а найти существующую реализацию в Интернете. Вот тот, который выглядит довольно хорошо, например, .

Если вам нужно заново изобрести колесо, код, на который там ссылаются, использует словари для хранения данных узла. Таким образом, вы кормите его что-то вроде:

{ 
  's': {'u' : 10, 'x' : 5}, 
  'u': {'v' : 1, 'x' : 2}, 
  'v': {'y' : 4}, 
  'x': {'u' : 3, 'v' : 9, 'y' : 2}, 
  'y': {'s' : 7, 'v' : 6}
}

Это кажется более интуитивным способом представления информации о графике. Посещенные узлы и расстояния также могут быть сохранены в словарях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...