Скачиваний:
3
Добавлен:
30.10.2024
Размер:
6.9 Кб
Скачать

# -*- coding:UTF-8 -*-

# Веса ребер
speed = {
    1: 120,
    2: 200,
    3: 20,
    4: 20,
    5: 140,
    6: 100,
    7: 115,
    8: 120,
    9: 140,
    10: 170,
    11: 200,
    12: 100,
    13: 140,
    14: 110,
    15: 110,
    16: 170,
    17: 90,
    18: 90,
    19: 110,
    20: 120,
    21: 20,
    22: 115,
    23: 100,
    24: 90,
    25: 115
}
# Отношения между вершинами
G = {
    1: {2:speed[1], 3:speed[1], 4:speed[1], 6:speed[1], 8:speed[1]},
    2: {3:speed[2], 4:speed[2], 6:speed[2], 8:speed[2], 9:speed[2], 13:speed[2], 24:speed[2]},
    3: {4:speed[3], 5:speed[3], 6:speed[3], 7:speed[3], 8:speed[3], 11:speed[3], 14:speed[3], 15:speed[3], 16:speed[3], 17:speed[3], 22:speed[3]},
    4: {5:speed[4], 6:speed[4], 7:speed[4], 8:speed[4], 11:speed[4], 16:speed[4], 17:speed[4], 22:speed[4]},
    5: {6:speed[5], 7:speed[5], 11:speed[5], 14:speed[5], 15:speed[5], 16:speed[5], 17:speed[5], 22:speed[5]},
    6: {8:speed[6], 14:speed[6], 15:speed[6]},
    7: {10:speed[7], 11:speed[7], 15:speed[7], 16:speed[7], 17:speed[7], 20:speed[7], 22:speed[7]},
    8: {12:speed[8], 14:speed[8], 19:speed[8], 21:speed[8], 23:speed[8]},
    9: {12:speed[9], 13:speed[9], 18:speed[9], 21:speed[9], 24:speed[9]},
    10: {15:speed[10], 16:speed[10], 20:speed[10]},
    11: {16:speed[11], 17:speed[11], 22:speed[11]},
    12: {14:speed[12], 18:speed[12], 19:speed[12], 21:speed[12]},
    13: {24:speed[13]},
    14: {15:speed[14], 16:speed[14], 19:speed[14], 20:speed[14], 21:speed[14], 22:speed[14], 23:speed[14], 25:speed[14]},
    15: {16:speed[15], 20:speed[15]},
    16: {17:speed[16], 20:speed[16], 22:speed[16], 25:speed[16]},
    17: {20:speed[17], 22:speed[17], 25:speed[17]},
    18: {21:speed[18], 24:speed[18]},
    19: {21:speed[19], 23:speed[19]},
    20: {22:speed[20], 25:speed[20]},
    21: {24:speed[21], 23:speed[21]},
    22: {25:speed[22]},
    23: {},
    24: {},
    25: {}
}



print('\n  Граф G')
for i in G:
    print(i, ':', G[i])

N = len(G) #количество элементов в словаре (G)

t = [] #список посещённых вершин
p = {} #словарь {открытая вершина : её метка}
b = {} #словарь для отслеживания короткого пути
v = None #текущая вершина
e = None #конечная вершина

def dijkstra(v, p, t, b, e):
    print('\n  Обходим всех соседей текущей вершины')
    for x in G[v]: #для каждого соседа (х) текущей вершины (v)
        xm = p[v] + G[v][x] #новая метка соседа (xm) =
                            #метка текущей вершины (p[v]) +
                            #значение ребра vx (G[v][x])
                            
        if not x in p: #если соседа (x) нет в словаре (p)
            p[x] = xm #записываем новую метку (xm) в словарь с ключем (x)
            b[x] = v  #как только метка пересчитывается, запоминаем 
                      #(следующая вершина: предыдущая вершина) в словаре (b)
        elif not x in t: #иначе если (x) не в (t)
            if p[x] > xm: #если старая метка соседа больше новой метки
                p[x] = xm #новую метку записываем на место старой
                b[x] = v #как только метка пересчитывается, запоминаем 
                         #(следующая вершина: предыдущая вершина) в словаре (b)
            
        print('текущей вершины v =', v, ' сосед x =', x, 'c меткой xm =', xm)
    
    print('p =', p)
    
    print('\n  Добавляем текущую вершину в список посещенных')
    t.append(v)            
    print('t =', t) 
    
    if N <= len(t): # Условие выхода из функции
        print('\nВсё!\nВершины и их метки =', p)
        print('Словарь для отслеживания пути =', b)
        
        s = [] #кратчайший путь
        s.insert(0, e) #вставляем (е) в список (s) по индексу (0)
        
        while True:
            if b[e] == -1: #значение ключа (-1) имеет начальная вершина
                           #вот её и ищем в словаре (b)
                print('Кратчайший путь от начальной до конечной вершины =', s)
                break #выходим из цикла
            e = b[e] #теперь последней вершиной будет предыдущая
            s.insert(0, e) #вставляем (е) в список (s) по индексу (0)
                 
        return  s         
    
    print('\n  Находим вершину с минимальной меткой за исключением тех, что уже в t')
    for d in p: #вершина (d) с минимальной меткой из словаря (p)
        if d not in t:
            dm = p[d] #метка вершины (d)
            break #пусть это будет первая вершина из словаря (p)
    
    for y in p: #для каждой вершины (y) из словаря (p)
        if p[y] < dm and not y in t: #если метка вершины (y) <
                                     #метки вершины (d) & (y) нет в (t)
            dm = p[y] #метку вершины (y) записываем в (dm)
            d = y #вершину (y) записываем в (d)
            print('Вершина y =', y, 'с меткой dm =', dm)
    
    print('Вершина d =', d, 'имеет минимальную метку dm =', dm, \
          '\nтеперь текущей вершиной v будет вершина d')
    v = d #теперь текущей вершиной v будет вершина d
    
    print('\n  Рекурсивно вызываем функцию Дейкстры с параметрами v, p, t, b, e')
    dijkstra(v, p, t, b, e)

########## 

# 1-й способ изменения глобальной переменой:
# используем возвращаемые значения
def start_v(start, end):
    v = start
    e = end
    p[v] = 0
    b[v] = -1
    print('\n  Начальная текущая вершина v =', v)
    return v, p, b, e
    
v, p, b, e = start_v(1, 25)  # иницилизация начальной и конечной вершин
dijkstra(v, p, t, b, e)     # вызываем функцию Дейкстры

input()
Соседние файлы в папке Контрольная работа