我有一个输入文本文件,其中包含简单无向图的每个边的一条线。该文件包含倒数边,即如果有一行u,v
,那么还有一行v,u
。
我需要一个算法,它只计算此图中4个周期的数量。我不需要它是最佳的,因为我只需要将它作为比较术语。如果你可以建议我实现Java,我会在余生中感激它。
提前谢谢。
答案 0 :(得分:3)
构造邻接矩阵M
,如果i和j之间存在边缘,则M[i,j]
为1。 M²
是一个矩阵,它计算每对顶点之间长度为2的路径数。
4个周期的数量为sum_{i<j}(M²[i,j]*(M²[i,j]-1)/2)/2
。这是因为如果在一对点之间存在n个长度为2的路径,则图形具有n选择2(即n *(n-1)/ 2)4个循环。我们只对矩阵的上半部分求和,以避免重复计算和退化路径,如a-b-a-b-a。我们仍然计算每个4个循环两次(每个循环中每对相反点一次),因此我们将总计除以另一个因子2。
如果使用矩阵库,可以用很少的行代码实现。
答案 1 :(得分:0)
深度优先搜索,DFS-这就是你需要的
答案 2 :(得分:0)
检测循环是一回事,但计算所有4个循环是另一回事。我认为你想要的是广度优先搜索(BFS)的变体,而不是已建议的DFS。我不会深入了解实施细节,但请注意重点。
1)路径是共享相同顶点的边的串联。
2)4周期是4边缘路径,其中起点和终点是相同的。
所以我会这样接近它。
读入图G并使用Java对象Vertex和Edge维护它。每个Vertex对象都有一个连接到该顶点的所有边的ArrayList。
对象Path将按顺序包含路径中的所有顶点。 PathList将包含所有路径。
将PathList初始化为所有1条边路径,这些路径恰好是G中的所有边.BTW,此列表将包含所有1个周期(连接到它们自身的顶点)以及所有其他路径。
创建一个函数(伪代码,推断函数名称的含义)
PathList iterate(PathList currentPathList)
{
newPathList = new PathList();
for(path in currentPathList.getPaths())
{
for(edge in path.lastVertexPath().getEdges())
{
PathList.addPath(Path.newPathFromPathAndEdge(path,edge));
}
}
return newPathList;
}
将currentPathList替换为PathList.iterate(currentPathList)一次,你将拥有所有的2-cyles,调用它两次,你将拥有所有3个循环,调用它3次,你将拥有所有4个循环
搜索所有路径并通过检查
找到4个周期Path.firstVertex().isEqualTo(path.lastVertex())
答案 3 :(得分:0)
根据Anonymous在1月18日的规定构建一个邻接矩阵,然后找到所有大小为4的周期。
这是一个枚举问题。如果我们知道图形是一个完整的图形,那么我们就知道任何长度的循环数的生成函数。但对于大多数其他图表,您必须找到所有周期才能找到确切的周期数。
使用回溯进行深度优先搜索应该是理想的策略。以每个节点为起始节点逐个实现它。跟踪访问过的节点。如果在没有找到大小为4的循环的情况下用完节点,只需回溯并尝试不同的路径。
Backtrack不适合较大的图表。例如,即使是顺序11的完整图表对于回溯算法也是有点太多。对于较大的图,您可以查找随机算法。