Неожиданный результат в глубине первого поиска - PullRequest
2 голосов
/ 13 апреля 2019

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

Мой граф представлен как {a: {b: c}}, где a и b - вершины, соединенные друг с другом, а c - вес ребра. Это ненаправленный граф. Я хотел бы реализовать мою функцию do_path_exist () для ненаправленного графа. В настоящее время он вычисляется так, как если бы мой график был направленным.

Дано:

{0: {1: 5.0, 2: 10.0}, 1: {3: 3.0, 4: 6.0}, 3: {2: 2.0, 4: 2.0, 5: 2.0}, 4: {6: 6.0}, 5: {6: 2.0}, 7: {9: 1.0}, 8: {7: 2.0, 9: 4.0}}

Путь существует от вершины 2 до 3. Поскольку моя функция ориентирована на направление, она возвращает False.

class Graph:
    def __init__(self, n):
        """
        Constructor
        :param n: Number of vertices
        """
        self.order = n
        self.size = 0
        self.vertex = {}

    def insert_edge(self, u, v, w): #works fine
        if u in self.vertex and v < self.order:
            if not v in self.vertex[u]:
                self.vertex[u][v] = w
                self.size += 1
        elif u not in self.vertex and u < self.order and v < self.order:
            self.vertex[u] = {}
            self.vertex[u][v] = w
            self.size += 1
        else:
            raise IndexError

    def does_path_exist(self, u, v): #works for directed graph, but not non-directed graph
        if u >= self.order or v >= self.order:
            raise IndexError
        if u == v:
            return True
        stac = []
        stac.append(u)
        visited = []
        while len(stac) != 0:
            u = stac.pop(0)
            if u not in visited:
                if u == v:
                    return True
                visited.append(u)
                if u in self.vertex:
                    t = self.vertex[u]
                else:
                    break
                a = t.keys()
                for u in a:
                    if u not in visited:
                        stac.append(u)
        return False

Моя основная функция:

def main():

g = Graph(10)
g.insert_edge(0,1,5.0)
g.insert_edge(0,2,10.0)
g.insert_edge(1,3,3.0)
g.insert_edge(1,4,6.0)
g.insert_edge(3,2,2.0)
g.insert_edge(3,4,2.0)
g.insert_edge(3,5,2.0)
g.insert_edge(4,6,6.0)
g.insert_edge(5,6,2.0)
g.insert_edge(7,9,1.0)
g.insert_edge(8,7,2.0)
g.insert_edge(8,9,4.0)

print(g.vertex)
print(g.does_path_exist(2,3)) #returns False but should return True

if __name__ == '__main__':
    main()

Ответы [ 2 ]

3 голосов
/ 13 апреля 2019

Ваш цикл проверяет только исходящие ребра . Если вы дадите ему u=2, он не найдет исходящих ребер из 2 и завершится после одной итерации.

Вам нужно либо:

  1. Добавить направленные ребра в обоих направлениях в insert_edge(). Это немного больше работы в insert_edge() и немного больше использования памяти.
  2. Поиск в словаре вершин не только прямых, но и задних ребер в цикле. Это значительно больше вычислений в does_edge_exist().
0 голосов
/ 13 апреля 2019

Вы упомянули, что граф является ориентированным графом, но вы назначаете ребро только от u до v в функции insert_edge.Я обновил функцию, чтобы она также присваивала ребро от v до u и вернула True для тестового ввода.

    def insert_edge(self, u, v, w): #works fine
        # Allow to travel from u to v
        if u in self.vertex and v < self.order:
            if not v in self.vertex[u]:
                self.vertex[u][v] = w
                self.size += 1
        elif u not in self.vertex and u < self.order and v < self.order:
            self.vertex[u] = {}
            self.vertex[u][v] = w
            self.size += 1
        else:
            raise IndexError

        # Allow travel to v from u
        if v in self.vertex and u < self.order:
            if not u in self.vertex[v]:
                self.vertex[v][u] = w
        elif v not in self.vertex and v < self.order and u < self.order:
            self.vertex[v] = {}
            self.vertex[v][u] = w
        else:
            raise IndexError
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...