【问题标题】:Return Vertices In Undirected Graph返回无向图中的顶点
【发布时间】:2015-07-13 10:23:54
【问题描述】:

我正在尝试在 Python 中提出一种贪心算法,该算法在给定某个起始顶点的情况下返回无向图中的顶点。我知道 DFS 确定是否存在循环,但我试图实际返回形成循环的顶点。我使用邻接矩阵来表示下图:

adjacencyMatrix = [[0, 1, 1, 0], [1, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]]

从图形上看,这是一个由单个循环组成的无向图。

我目前的思考过程是将我的起始索引设置为我遇到的第一个1(在本例中为adjacencyMatrix[0][1])。然后我会查看该行的其余部分,看看是否有另一个1,因为这意味着我当前的顶点连接到该索引。但是,我不完全确定(a)这是否是正确的方法以及(b)如何“移动”到下一个顶点。例如,我将如何导航嵌套的for 循环以从adjacencyMatrix[0][1] 顶点移动到adjacencyMatrix[0][2] 顶点?我可以交换行索引和列索引吗?

编辑 我想出的这个解决方案似乎适用于我尝试过的几个图表:

def findCycle(matrix):
    visited = list()
    cycleNotFound = True
    row = 0
    col = 0
    startVertex = (0, 0)

    while cycleNotFound:

        # Only add a vertex if it has not already been visited
        if (matrix[row][col] == 1) and ((row, col) not in visited):
            # Set the startVertex when the first node is found
            if len(visited) == 0:
                startVertex = (row, col)

            # Add the current vertex and its counter part
            visited.append((row, col))
            visited.append((col, row))

            # If row and col are equal, infite loop will get created
            if row != col:
                row = col
                col = 0
            else:
                row += 1

        # If back at starting point, break look
        elif ((row, col) == startVertex) and (len(visited) > 1):
            cycleNotFound = False
            visited.append(startVertex)

        # Else, continue to look for unvisted neighbors
        else:
            col += 1

    return visited

if __name__ == "__main__":
    matrix = [[0, 1, 1, 0], [1, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]]
    cycle = findCycle(matrix)
    index = 0
    # Print the vertices.  Only print even vertices to avoid duplicates.
    while (index < len(cycle)):
        print cycle[index]
        index += 2

这不是最优雅的解决方案,我确信需要进行一些重大的重构。

【问题讨论】:

  • 如果你在做 DFS,你会递归地去你的邻居之一,在从这个邻居完成 DFS 之后,你会继续到下一个邻居等等。
  • 好的,那我是不是先运行 DFS 来确定是否存在循环,然后使用稍微修改的 DFS 方法返回所有访问过的顶点?
  • 首先,邻接矩阵是对称的。顶点的数量由矩阵的大小定义。大小为n x n 的矩阵意味着有n 个顶点。要列出连接到某个顶点的顶点,请检查相应的行,它们的索引“是”您要查找的顶点。

标签: python algorithm graph undirected-graph


【解决方案1】:

你可以试试这个:

def findCycle(node):
    cycle = stack()
    if( DFS(node, cycle) ):
        return cycle
    return None

def DFS(node, cycle):
    cycle.append(node)
    mark node as visited
    foreach node.neighbors as neighbor:
        if neighbor already visited:
            return true
        else:
            if( DFS(neighbor, cycle) ) return true
    cycle.remove(node)
    return false

【讨论】:

  • 好的,这实际上可能与我目前的工作类似。我假设neighbors 函数将返回每个[row][col] == 1 的列号列表?例如,使用提供的邻接矩阵 1.neighbors 将返回 [2, 3]?
  • @steveclark 嗨,如果您认为正确,请选择我的答案。谢谢
  • 我无法实现您的解决方案,因为我在调试递归方面很糟糕,我决定继续研究我已经在研究的那个。我在问题中发布了我的解决方案的代码作为编辑。
  • @TobyD:我认为findCycle 可以返回错误的节点。 DFS 不会将已经标记的节点添加到 cycle(尽管它可以在顶部节点的邻居中找到,希望仍然被标记)。更糟糕的是,它在cycle 中包含不是 循环一部分的节点。考虑一个循环 A->B->C->B:从cycle 弹出的节点将是:C、B、A。如果 DFS 在返回 True 之前将 B 推到 cycle 上,findCycle可以弹出和yield B,然后继续弹出和yielding,直到B再次出现。但是如果没有堆栈顶部的“有罪”节点,findCycle 需要进行一些调查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多