Подсчет количества направленных циклов многоточия в python - PullRequest
1 голос
/ 06 мая 2020

Я пытаюсь написать код, который считает количество циклов в структуре данных. Примером может быть:

A = [(), ()]
B = [A, A]
A[0] = B
A[1] = B

Итак, если мы нарисуем диаграмму прямоугольника и указателя, будет 4 цикла:

(index 0, B) -> (index 0, A) -> index(0, B)
(index 0, B) -> (index 1, A) -> index(0, B)
(index 1, B) -> (index 0, A) -> index(0, B)
(index 1, B) -> (index 1, A) -> index(0, B)

Я нашел сообщения, связанные с этим, наиболее многообещающие один из них: Поиск всех циклов в ориентированном графе

Но моя основная проблема в том, что многоточие, подобное приведенному выше, является абсолютной проблемой для работы. Например, проверка членства

C = [A, B]
B in A     # Gives an error here

Это приводит к другим проблемам. Например, в упомянутом выше сообщении решения рекомендуют создать список смежности. Но сначала вы должны найти способ пометить эти узлы. Я сделал это следующим образом:

(0, A) 
(1, A)
(0, B)
(1, B)

Проблема в том, что если вы попытаетесь создать словарь с этими ключами, вы получите сообщение об ошибке.

Что у меня есть пока удалось придумать:

def check_repeated_nodes(tup_lst):   # To test for membership since we cannot use "in"
    unique_nodes = []
    repeated_nodes = []    # If this list is not empty, there is a repeated node and hence a cycle
    for idx, lst in tup_lst:
        is_unique = True       # flag to test the uniqueness of a node
        for unique_idx, unique_lst in unique_nodes:
            if lst is unique_lst and idx is unique_idx:
                repeated_nodes.append((idx, lst))
                is_unique = False
        if is_unique:
            unique_nodes.append((idx, lst))
    return len(repeated_nodes) > 0


def count_cycles(lst):
    cycle_lst = []

    def helper(lst, track = []):
        for i in range(len(lst)):
            node = (i, lst)     # We label a node as (index, list)
            track.append(node)     # append to the tracker list
            if check_repeated_nodes(track):   # If there is a repeated node, we append to our cycle list
                cycle_lst.append(track)
            else:
                if type(lst[i]) == list:     # check if lst[i] is also a node
                    helper(lst[i], track)     # execute the process again if it is a node

    helper(lst)
    return len(cycle_lst)    # The length of this list is the number of cycles

Результат, который я надеялся получить, был:

[
    [(0, B), (0, A), (0, B)], 
    [(0, B), (1, A), (0, B)],
    [(1, B), (0, A), (0, B)], 
    [(1, B), (1, A), (0, B)]
]

Но вместо этого я получил:

[
    [(0, B), (0, A), (0, B)], 
    [(0, B), (0, A), (0, B), (1, A)], 
    [(0, B), (0, A), (0, B), (1, B), (1, A)], 
    [(0, B), (0, A), (0, B), (1, B), (1, A), (1, B)]
]

Я подозреваю, что проблема связана с возвратом? Как будто функция не возвращается в начальную точку, если попадает в цикл. Я пытался решить эту проблему в течение нескольких дней, но не могу найти правильного решения. Есть совет?

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