Форум сайта python.su
0
Пытаюсь справиться с теорией графов. Написала алгоритм, нарисовала граф
и блок схему
(вариант проще: 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)
Офлайн
103
очень сложно читать код!
давайте так: вы опишите каждую строку, хорошо опишите
и тогда или вы сами поймете или мы вам поможем
Отредактировано terabayt (Апрель 28, 2015 23:25:25)
Офлайн
0
Спасибо!!! Я просто в ужасе, работаю одна. Спасибо большое за ответ и возможность обсудить.
Начну с массивов:
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)
Офлайн
4
Что делает connect? Соединяет вершины только? Тебе известно про списки смежности?
AnnaLischenДругими словами надо найти расстояние между вершиной графа A и циклическим графом B, являющимся подграфом графа A, да? Если вершина находится в графе B, то расстояние будет равно нулю?
Что пытаюсь сделать: установить кратчайший путь между вершиной и циклическим графом, при условии, что эта вершина либо уже в циклическом графе, либо соединена с ним напрямую, то есть через вершину, принадлежащую циклу, либо через другие вершины, которые таким же образом могут быть связаны с графом и находятся в списке вершин, которые с графом связываться могут.
Офлайн
0
Нет. Надо найти не расстояние, надо найти все вершины, которые располагаются между интересующей вершиной и циклом, включая цикл и эту саму вершину.
О расстояниях речь вообще не идёт. Направленность, думаю, тоже не имеет значения. Кратчайший путь в том смысле, что я не пытаюсь соединить всё со всем. Я просто ищу ближайший цикл.
Отредактировано AnnaLischen (Апрель 29, 2015 03:11:05)
Офлайн
4
Ах да, путь. А по остальным вопросам?
С путем такой же вопрос почти: другими словами надо найти путь между вершиной графа A и циклическим графом B, являющимся подграфом графа A, да? Если вершина находится в графе B, то путь будет равен нулю (пустому списку)?
Или, как вы уже говорите, надо найти до любого ближайшего цикла?
Граф же статически задается, что подразумевается под словом “соединить”?
Офлайн
4
не проще разве задавать граф примерно так:
GRAPH = { 'F' : ['G'] 'G' : ['F', 'N'] 'N' : ['G', 'E'] 'E' : ['N', 'D', 'A'] ... }
Офлайн
857
Надо составить матрицу смежности и её анализировать.
AnnaLischenЭто можно в матрице отразить, удалив ненужные вершины или их рёбра.
Первый массив, массив разрешенных элементов, это те элементы, которые могут устанавливать соединение с циклами и/или через которые можно устанавливать соединение.
AnnaLischenЛучше двумерный массив нулей и единиц обрабатывать, так как там не только легко найти для одной вершины все связи, но и поменять конфигурацию. Если простые линии не интересуют, их можно обнулить, чтобы они не участвовали в поиске.
Третий массив содержит попарные связи между вершинами
Офлайн
0
@kamisama это один из способов записи, именно способ записи, как мне кажется, не должен влиять на саму функцию
@py.user.next с моей точки зрения звучит довольно сложно, как это сделать я себе плохо представляю. А вы можете сказать что-то по моему коду? Я бы очень хотела именно его отладить. Как мне кажется, я нашла решение проблемы, но оно “почти работает”, убрать бы это почти))
py.user.next
Надо составить матрицу смежности и её анализировать.
py.user.nextНо всё равно надо сначала понять какие рёбра и вершины можно и нужно удалять, кроме того, мне надо получить на выходе несколько массивов, т. е. для каждого разрешённого элемента (да, можно по очереди удалять те вершины и рёбра, которые соединены последовательно, но к циклу может быть привязан ещё какой-то “хвост” с другой стороны цикла, его простраивать заново?)
Это можно в матрице отразить, удалив ненужные вершины или их рёбра
py.user.nextПочему лучше?
Лучше двумерный массив нулей и единиц обрабатывать, так как там не только легко найти для одной вершины все связи, но и поменять конфигурацию. Если простые линии не интересуют, их можно обнулить, чтобы они не участвовали в поиске.
Офлайн
4
AnnaLischen
Такой записью намного проще делать рекурсивный обход и функция займет несколько строк. А твой код лучше выкинуть и забыть как страшный сон.
Нужна еще постановка задачи в строгом виде — что дано и что найти. Ты почему-то в этом игнорируешь.
py.user.next говорит о матрице, но он это кажется неправильно говорит. Для матрицы алгоритм будет сложнее
Офлайн