简体   繁体   English

在无向图中找到4个循环的最简单算法

[英]Simplest algorithm to find 4-cycles in an undirected graph

I have an input text file containing a line for each edge of a simple undirected graph. 我有一个输入文本文件,其中每个简单无向图的每个边都包含一条线。 The file contains reciprocal edges, ie if there's a line u,v , then there's also the line v,u . 该文件包含相互的边,即,如果有u,v ,那么也有v,u

I need an algorithm which just counts the number of 4-cycles in this graph. 我需要一个仅计算此图中4个循环数的算法。 I don't need it to be optimal because I only have to use it as a term of comparison. 我不需要它是最佳的,因为我只需要使用它作为比较项即可。 If you can suggest me a Java implementation, I would appreciate it for the rest of my life. 如果您可以向我推荐Java实现,那么我将在余生中感激不尽。

Thank you in advance. 先感谢您。

Construct the adjacency matrix M , where M[i,j] is 1 if there's an edge between i and j. 构造邻接矩阵M ,如果i和j之间有边,则M[i,j]为1。 is then a matrix which counts the numbers of paths of length 2 between each pair of vertices. 然后是一个矩阵,用于计算每对顶点之间长度为2的路径的数量。

The number of 4-cycles is sum_{i<j}(M²[i,j]*(M²[i,j]-1)/2)/2 . 4个循环的数目为sum_{i<j}(M²[i,j]*(M²[i,j]-1)/2)/2 This is because if there's n paths of length 2 between a pair of points, the graph has n choose 2 (that is n*(n-1)/2) 4-cycles. 这是因为如果在一对点之间存在长度为2的n条路径,则该图具有n个选择2(即n *(n-1)/ 2)个4圈。 We sum only the top half of the matrix to avoid double counting and degenerate paths like ababa. 我们仅对矩阵的上半部分求和,以避免重复计数和退化路径(如ababa)。 We still count each 4-cycle twice (once per pair of opposite points on the cycle), so we divide the overall total by another factor of 2. 我们仍然会对每个4个周期计数两次(该周期上每对相对点一次),因此我们将总数除以另一个因子2。

If you use a matrix library, this can be implemented in a very few lines code. 如果使用矩阵库,则可以用很少的几行代码来实现。

深度优先搜索,DFS-这就是您需要的

Detecting a cycle is one thing but counting all of the 4-cycles is another. 检测一个周期是一回事,而计算所有4个周期则是另一回事。 I think what you want is a variant of breadth first search (BFS) rather than DFS as has been suggested. 我认为您想要的是广度优先搜索(BFS)的变体,而不是建议的DFS。 I'll not go deeply into the implementation details, but note the important points. 我将不深入介绍实现细节,但请注意要点。

1) A path is a concatenation of edges sharing the same vertex. 1)路径是共享相同顶点的边的串联。

2) A 4-cycle is a 4-edge path where the start and end vertices are the same. 2)4循环是4边路径,其中起始和结束顶点相同。

So I'd approach it this way. 所以我会这样处理。

Read in graph G and maintain it using Java objects Vertex and Edge. 读入图G并使用Java对象Vertex和Edge对其进行维护。 Every Vertex object will have an ArrayList of all of the Edges that are connected to that Vertex. 每个顶点对象都有一个连接到该顶点的所有边的ArrayList。

The object Path will contain all of the vertexes in the path in order. 对象Path将按顺序包含路径中的所有顶点。 PathList will contain all of the paths. PathList将包含所有路径。

Initialize PathList to all of the 1-edge paths which are exactly all of edges in G. BTW, this list will contain all of the 1-cycles (vertexes connected to themselves) as well as all other paths. 将PathList初始化为恰好是G中所有边缘的所有1-edge路径。此列表将包含所有1-cycle(与自身相连的顶点)以及所有其他路径。

Create a function that will (pseudocode, infer the meaning from the function name) 创建一个将(伪代码,从函数名称推断含义)的函数

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;
}

Replace currentPathList with PathList.iterate(currentPathList) once and you will have all of the 2-cyles, call it twice and you will have all of the 3 cycles, call it 3 times and you will have all of the 4 cycles. 一次将currentPathList替换为PathList.iterate(currentPathList),您将拥有所有2个循环,调用两次,将拥有所有3个循环,将其调用3次,将拥有所有4个循环。

Search through all of the paths and find the 4-cycles by checking 搜索所有路径并通过检查找到4个循环

Path.firstVertex().isEqualTo(path.lastVertex())

Construct an adjacency matrix, as prescribed by Anonymous on Jan 18th, and then find all the cycles of size 4. 根据Anonymous在1月18日的规定,构造一个邻接矩阵,然后找到所有大小为4的循环。

It is an enumeration problem. 这是一个枚举问题。 If we know that the graph is a complete graph, then we know off a generating function for the number of cycles of any length. 如果我们知道该图是一个完整的图,那么我们就知道了任意长度的循环数的生成函数。 But for most of other graphs, you have to find all the cycles to find the exact number of cycles. 但是对于大多数其他图形,您必须找到所有循环才能找到精确的循环数。

Depth first search with backtracking should be the ideal strategy. 具有回溯功能的深度优先搜索应该是理想的策略。 Implement it with each node as the starting node, one by one. 将每个节点作为起始节点,一一实现。 Keep track of visited nodes. 跟踪访问的节点。 If you run out of nodes without finding a cycle of size 4, just backtrack and try a different route. 如果节点用完而找不到大小为4的循环,则只需回溯并尝试其他路由即可。

Backtrack is not ideal for larger graphs. 对于较大的图形,回溯并不是理想的选择。 For example, even a complete graph of order 11 is a little to much for backtracking algorithms. 例如,对于回溯算法,即使是11阶的完整图也差不多。 For larger graphs you can look for a randomized algorithm. 对于较大的图,您可以寻找随机算法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM