Это потому, что ваш алгоритм неверен. Проблема с вашим алгоритмом заключается в том, что он зависит от того, к каким краям мы начинаем создавать список тел. Чтобы объяснить это, возьмем простой пример графика с 4 ребрами как - edges = [('1','2'),('2','3'),('3','4'),('1','4')]
.
Первый случай -
>>> edges = [('1','2'),('2','3'),('3','4'),('1','4')]
>>> bodylist = []
>>> for edge in edges:
... #If at least one node of the edge is anywhere in bodylist, append the new nodes to that list.
... try:
... index = [i for i, body in enumerate(bodylist) if edge[0] in body or edge[1] in body][0]
... bodylist[index].append(edge[0])
... bodylist[index].append(edge[1])
... #If not, make a new list containing the new nodes.
... except:
... bodylist.append([edge[0], edge[1]])
...
>>> print([set(x) for x in bodylist])
[{'4', '1', '3', '2'}]
Вы получаете одно тело с вершинами - 1, 2, 3, 4
. Зачем?
Беспокойство, начатое с (1,2), добавлено в список объектов. Затем вы взяли (2,3), вы видите, что 2 уже есть в элементе, добавленном в список объектов, вы добавляете его снова к тому же, и это продолжается, и все они добавляются в один и тот же объект.
Теперь давайте берем те же края в другом порядке - edges = [('1','2'),('3','4'),('2','3'),('1','4')]
. Это получается как -
>>> edges = [('1','2'),('3','4'),('2','3'),('1','4')]
>>> bodylist = []
>>> .... #same logic
>>> print([set(x) for x in bodylist])
[{'4', '1', '3', '2'}, {'4', '3'}]
Как вы можете видеть, на этот раз, у вас есть два различных тела (и, очевидно, что они не правы) Почему?
Снова вы начали с (1,2), добавили, что для бодилера как тела, тогда вы взяли (3,4), проверяя это, вы видите, что ни одна из вершин уже не существует в любом теле, следовательно вы добавили это в отдельный орган. Принимая третий элемент (2,3), вы видите, что это есть как в первом, так и во втором теле, но ваша логика состоит в том, чтобы просто взять первое тело и добавить к нему элемент. (Вы видите, где вы собираетесь не так?)
Вот почему вы получите разные результаты, когда вы перетасовать список, так как порядок имеет важное значение для вашей логики (что неправильно).
Что вам нужно сделать, так это то, что если вы найдете вершины для края в нескольких телах, вам нужно объединить оба тела в единое тело.
Другой совет, нам не нужно, чтобы добавить списки в bodylist
вместо этого мы можем использовать sets
для каждого body
.
Образец решение будет выглядеть -
from random import shuffle
edges = [('7', '9'), ('2', '8'), ('4', '10'), ('5', '9'), ('1', '2'), ('1', '6'), ('6', '10')]
bodylist = []
shuffle(edges)
for edge in edges:
bodies = [body for i, body in enumerate(bodylist) if edge[0] in body or edge[1] in body]
if len(bodies) > 0:
tempset = {edge[0],edge[1]}
for x in bodies:
tempset.update(x)
print('tempset :',tempset)
bodylist.remove(x)
bodylist.append(tempset)
else:
bodylist.append({edge[0],edge[1]})
print([set(x) for x in bodylist])
Что значит другой ответ? В отличие от чего? –
Я мог бы не понимать этого ... В общем, вы получили бы другой ответ, когда вы перетасовываете список, нет? Или вы говорите, что это также перетасовка кортежей в вашем списке, а не только порядок кортежей? – Stiffo
Результатом является набор несвязанных тел, и этот набор изменяется каждый раз, когда края перетасовываются. Он должен быть независимым от заказа. –