Форум сайта python.su
Пытаюсь справиться с теорией графов. Написала алгоритм, нарисовала граф и блок схему
(вариант проще: https://www.dropbox.com/s/e6ymisumg9mhccl/Block2.png?dl=0), но что-то не так. Я неправильно возвращаю результат.
Что пытаюсь сделать: установить кратчайший путь между вершиной и циклическим графом, при условии, что эта вершина либо уже в циклическом графе, либо соединена с ним напрямую, то есть через вершину, принадлежащую циклу, либо через другие вершины, которые таким же образом могут быть связаны с графом и находятся в списке вершин, которые с графом связываться могут.
По-моему, я неверно расставила return. Что не так? Как правильно?
Вот мой код, версия в который раз исправленная и дополненная:
arrWhatToConnect = ['F', 'G', 'N', 'X2', 'X3', 'K3', 'K1', 'K2', 'E'] #THERE IS NO X8!!!!! arrWithWhatToConnect = [['A', 'B', 'C', 'D', 'E'], ['Z', 'P', 'L', 'Y']] arrAllConnections = [['F', 'G'], ['G', 'F'], ['G', 'N'], ['N', 'G'], ['N', 'E'], ['E', 'N'], ['E', 'D'], ['D', 'E'], ['D', 'C'], ['C', 'D'], ['C', 'B'], ['B', 'C'], ['B', 'A'], ['A', 'B'], ['A', 'E'], ['E', 'A'], ['B', 'X8'], ['X8', 'B'], ['X8', 'X3'], ['X3', 'X8'], ['X3', 'X2'], ['X2', 'X3'], ['C', 'T'], ['T', 'C'], ['T', 'T1'], ['T1', 'T'], ['T1', 'Y'], ['Y', 'T1'], ['Y', 'L'], ['L', 'Y'],['L', 'P'], ['P', 'L'], ['P', 'Z'], ['Z', 'P'], ['Z', 'Y'], ['Y', 'Z'], ['L', 'K3'], ['K3', 'L'], ['Z', 'K1'], ['K1', 'Z'], ['K1', 'K2'], ['K2', 'K1']] nullFirstConnect = [] #arrAllConnections = (sorted(item for item in arrAllConnections)) arrAllConnections = [list(i) for i in set(map(tuple, arrAllConnections))] print(arrAllConnections, 'REMOVED?') def visited(itemNext, arrConnect): return itemNext in arrConnect def connect(arrWithWhatToConnect, arrWhatToConnect, arrAllConnections, item, olderItems, mainItemOfConnection): arrAllConDel = arrAllConnections #print('CONTENTS OF TRUNCATED ARR CONNECTIONS', arrAllConDel) arrConnected = [] arrVisited = [] for cycle in arrWithWhatToConnect: print('ARRCONNECTED', arrConnected) if item in cycle: arrConnected.extend(cycle) arrConnected.extend(olderItems) print('My item in cycle', item, cycle, arrConnected, mainItemOfConnection) return set(arrConnected) #print('My item in cycle', item, cycle, arrConnected, mainItemOfConnection) #return set(arrConnected) else: if item in arrWhatToConnect: #print('Not in cycle', item) #print('GOING TO CHECK ELSEWHERE!') olderItems.extend(item) olderItems.extend(olderItems) for connection in arrAllConnections: item1 = connection[0] item2 = connection[1] if item in connection: if item == item1: #print('connection is', connection, 'item', item, 'item1', item1, 'item2', item2) if item2 not in arrConnected: del arrAllConDel[arrAllConnections.index(connection)] connect(arrWithWhatToConnect, arrWhatToConnect, arrAllConDel, item2, olderItems, mainItemOfConnection) return arrConnected #how to send previous item, so to let program know that it should be not just ring, but ring + item? elif item == item2: if item1 not in arrConnected: del arrAllConDel[arrAllConnections.index(connection)] connect(arrWithWhatToConnect, arrWhatToConnect, arrAllConDel, item1, olderItems, mainItemOfConnection) return arrConnected for item in arrWhatToConnect: print(item) print('CONNECTED CONNECTED CONNECTED', connect(arrWithWhatToConnect, arrWhatToConnect, arrAllConnections, item, nullFirstConnect, item))
Отредактировано AnnaLischen (Апрель 28, 2015 21:38:14)
Офлайн
очень сложно читать код!
давайте так: вы опишите каждую строку, хорошо опишите
и тогда или вы сами поймете или мы вам поможем
Отредактировано terabayt (Апрель 28, 2015 23:25:25)
Офлайн
Спасибо!!! Я просто в ужасе, работаю одна. Спасибо большое за ответ и возможность обсудить.
Начну с массивов:
arrWhatToConnect = ['F', 'G', 'N', 'X2', 'X3', 'K3', 'K1', 'K2', 'E']
['A', 'B', 'C', 'D', 'E', 'N', 'G', 'F']; ['A', 'B', 'C', 'D', 'E', 'N', 'G'];['A', 'B', 'C', 'D', 'E', 'N']
arrWithWhatToConnect = [['A', 'B', 'C', 'D', 'E'], ['Z', 'P', 'L', 'Y']]
arrAllConnections = [['F', 'G'], ['G', 'F'], ['G', 'N'], ['N', 'G'], ['N', 'E'], ['E', 'N'], ['E', 'D'], ['D', 'E'], ['D', 'C'], ['C', 'D'], ['C', 'B'], ['B', 'C'], ['B', 'A'], ['A', 'B'], ['A', 'E'], ['E', 'A'], ['B', 'X8'], ['X8', 'B'], ['X8', 'X3'], ['X3', 'X8'], ['X3', 'X2'], ['X2', 'X3'], ['C', 'T'], ['T', 'C'], ['T', 'T1'], ['T1', 'T'], ['T1', 'Y'], ['Y', 'T1'], ['Y', 'L'], ['L', 'Y'],['L', 'P'], ['P', 'L'], ['P', 'Z'], ['Z', 'P'], ['Z', 'Y'], ['Y', 'Z'], ['L', 'K3'], ['K3', 'L'], ['Z', 'K1'], ['K1', 'Z'], ['K1', 'K2'], ['K2', 'K1']]
arrAllConnections = [list(i) for i in set(map(tuple, arrAllConnections))]
for item in arrWhatToConnect: print(item) print('CONNECTED CONNECTED CONNECTED', connect(arrWithWhatToConnect, arrWhatToConnect, arrAllConnections, item, nullFirstConnect, item))
def connect(arrWithWhatToConnect, arrWhatToConnect, arrAllConnections, item, olderItems, mainItemOfConnection):
for cycle in arrWithWhatToConnect:
if item in cycle: arrConnected.extend(cycle) arrConnected.extend(olderItems) print('My item in cycle', item, cycle, arrConnected, mainItemOfConnection) return set(arrConnected)
else:
if item in arrWhatToConnect:
else return None?
for connection in arrAllConnections:
item1 = connection[0] item2 = connection[1]
if item == item1: #print('connection is', connection, 'item', item, 'item1', item1, 'item2', item2) if item2 not in arrConnected: del arrAllConDel[arrAllConnections.index(connection)] connect(arrWithWhatToConnect, arrWhatToConnect, arrAllConDel, item2, olderItems, mainItemOfConnection) return arrConnected #how to send previous item, so to let program know that it should be not just ring, but ring + item? elif item == item2: if item1 not in arrConnected: del arrAllConDel[arrAllConnections.index(connection)] connect(arrWithWhatToConnect, arrWhatToConnect, arrAllConDel, item1, olderItems, mainItemOfConnection) return arrConnected
if item2 not in arrConnected:
else: if item in arrWhatToConnect: #print('Not in cycle', item) #print('GOING TO CHECK ELSEWHERE!') olderItems.extend(item) olderItems.extend(olderItems)
connect(arrWithWhatToConnect, arrWhatToConnect, arrAllConDel, item1, olderItems, mainItemOfConnection)
del arrAllConDel[arrAllConnections.index(connection)]
Отредактировано AnnaLischen (Апрель 28, 2015 23:59:11)
Офлайн
Что делает connect? Соединяет вершины только? Тебе известно про списки смежности?
AnnaLischenДругими словами надо найти расстояние между вершиной графа A и циклическим графом B, являющимся подграфом графа A, да? Если вершина находится в графе B, то расстояние будет равно нулю?
Что пытаюсь сделать: установить кратчайший путь между вершиной и циклическим графом, при условии, что эта вершина либо уже в циклическом графе, либо соединена с ним напрямую, то есть через вершину, принадлежащую циклу, либо через другие вершины, которые таким же образом могут быть связаны с графом и находятся в списке вершин, которые с графом связываться могут.
Офлайн
Нет. Надо найти не расстояние, надо найти все вершины, которые располагаются между интересующей вершиной и циклом, включая цикл и эту саму вершину.
О расстояниях речь вообще не идёт. Направленность, думаю, тоже не имеет значения. Кратчайший путь в том смысле, что я не пытаюсь соединить всё со всем. Я просто ищу ближайший цикл.
Отредактировано AnnaLischen (Апрель 29, 2015 03:11:05)
Офлайн
Ах да, путь. А по остальным вопросам?
С путем такой же вопрос почти: другими словами надо найти путь между вершиной графа A и циклическим графом B, являющимся подграфом графа A, да? Если вершина находится в графе B, то путь будет равен нулю (пустому списку)?
Или, как вы уже говорите, надо найти до любого ближайшего цикла?
Граф же статически задается, что подразумевается под словом “соединить”?
Офлайн
не проще разве задавать граф примерно так:
GRAPH = { 'F' : ['G'] 'G' : ['F', 'N'] 'N' : ['G', 'E'] 'E' : ['N', 'D', 'A'] ... }
Офлайн
Надо составить матрицу смежности и её анализировать.
AnnaLischenЭто можно в матрице отразить, удалив ненужные вершины или их рёбра.
Первый массив, массив разрешенных элементов, это те элементы, которые могут устанавливать соединение с циклами и/или через которые можно устанавливать соединение.
AnnaLischenЛучше двумерный массив нулей и единиц обрабатывать, так как там не только легко найти для одной вершины все связи, но и поменять конфигурацию. Если простые линии не интересуют, их можно обнулить, чтобы они не участвовали в поиске.
Третий массив содержит попарные связи между вершинами
Офлайн
@kamisama это один из способов записи, именно способ записи, как мне кажется, не должен влиять на саму функцию
@py.user.next с моей точки зрения звучит довольно сложно, как это сделать я себе плохо представляю. А вы можете сказать что-то по моему коду? Я бы очень хотела именно его отладить. Как мне кажется, я нашла решение проблемы, но оно “почти работает”, убрать бы это почти))
py.user.next
Надо составить матрицу смежности и её анализировать.
py.user.nextНо всё равно надо сначала понять какие рёбра и вершины можно и нужно удалять, кроме того, мне надо получить на выходе несколько массивов, т. е. для каждого разрешённого элемента (да, можно по очереди удалять те вершины и рёбра, которые соединены последовательно, но к циклу может быть привязан ещё какой-то “хвост” с другой стороны цикла, его простраивать заново?)
Это можно в матрице отразить, удалив ненужные вершины или их рёбра
py.user.nextПочему лучше?
Лучше двумерный массив нулей и единиц обрабатывать, так как там не только легко найти для одной вершины все связи, но и поменять конфигурацию. Если простые линии не интересуют, их можно обнулить, чтобы они не участвовали в поиске.
Офлайн
AnnaLischen
Такой записью намного проще делать рекурсивный обход и функция займет несколько строк. А твой код лучше выкинуть и забыть как страшный сон.
Нужна еще постановка задачи в строгом виде — что дано и что найти. Ты почему-то в этом игнорируешь.
py.user.next говорит о матрице, но он это кажется неправильно говорит. Для матрицы алгоритм будет сложнее
Офлайн