Java 有向图中的回路数
关于如何在有向图中找到循环数/回路数,有各种各样的问题。我大部分时间都访问过它们,我确实拿出了一个代码来实现这一点 当我的代码没有给出长度小于3的循环/电路时,我被击中了 代码:Java 有向图中的回路数,java,algorithm,data-structures,Java,Algorithm,Data Structures,关于如何在有向图中找到循环数/回路数,有各种各样的问题。我大部分时间都访问过它们,我确实拿出了一个代码来实现这一点 当我的代码没有给出长度小于3的循环/电路时,我被击中了 代码: 公共类循环图{ //建模为边列表的图 静态int[][]图= { {1, 2}, {2, 3}, {3, 4}, {4, 3}, {3, 1} }; 静态列表周期=新的ArrayList(); /** *@param args */ 公共静态void main(字符串[]args){ 对于(int i=0;i
公共类循环图{
//建模为边列表的图
静态int[][]图=
{
{1, 2}, {2, 3}, {3, 4}, {4, 3},
{3, 1}
};
静态列表周期=新的ArrayList();
/**
*@param args
*/
公共静态void main(字符串[]args){
对于(int i=0;i
我得到的输出:
1,3,2
但我也应该得到3,4,因为
3-4-3
也会在图形中生成一个循环。在什么时候,当您使用调试器运行此程序时,它的行为是否与预期的不同?@ScottHunter,我得到的是所有循环,长度低于3的除外。更令人担忧的是,我得到了一些随机顺序的周期(为了找到所有的循环,你需要通过深度优先搜索来探索每个可能的路径,而你的程序显然没有这样做。这并不能回答问题。@ScottHunter,我还没有在这个程序中使用调试器。我一定会这样做。在什么情况下,当你使用调试器运行这个程序时,它的行为会与预期的不同吗?@ScottHunter,我是我得到了所有的周期,除了长度小于3的周期。更让人担心的是,我得到的周期是随机的(为了找到所有的循环,你需要通过深度优先搜索探索每一条可能的路径,而你的程序显然没有这样做,但这并不能回答问题。@ScottHunter,我还没有在这个程序中使用调试器。我一定会这样做。
public class CyclesInGraph {
// Graph modeled as list of edges
static int[][] graph =
{
{1, 2}, {2, 3}, {3, 4}, {4, 3},
{3, 1}
};
static List<int[]> cycles = new ArrayList<int[]>();
/**
* @param args
*/
public static void main(String[] args) {
for (int i = 0; i < graph.length; i++)
for (int j = 0; j < graph[i].length; j++)
{
findNewCycles(new int[] {graph[i][j]});
}
for (int[] cy : cycles)
{
String s = "" + cy[0];
for (int i = 1; i < cy.length; i++)
{
s += "," + cy[i];
}
o(s);
}
}
static void findNewCycles(int[] path)
{
int n = path[0];
int x;
int[] sub = new int[path.length + 1];
for (int i = 0; i < graph.length; i++)
for (int y = 0; y <= 1; y++)
if (graph[i][y] == n)
// edge refers to our current node
{
x = graph[i][(y + 1) % 2];
if (!visited(x, path))
// neighbor node not on path yet
{
sub[0] = x;
System.arraycopy(path, 0, sub, 1, path.length);
// explore extended path
findNewCycles(sub);
}
else if ((path.length > 2) && (x == path[path.length - 1]))
// cycle found
{
int[] p = normalize(path);
int[] inv = invert(p);
if (isNew(p) && isNew(inv))
{
cycles.add(p);
}
}
}
}
// check of both arrays have same lengths and contents
static Boolean equals(int[] a, int[] b)
{
Boolean ret = (a[0] == b[0]) && (a.length == b.length);
for (int i = 1; ret && (i < a.length); i++)
{
if (a[i] != b[i])
{
ret = false;
}
}
return ret;
}
// create a path array with reversed order
static int[] invert(int[] path)
{
int[] p = new int[path.length];
for (int i = 0; i < path.length; i++)
{
p[i] = path[path.length - 1 - i];
}
return normalize(p);
}
// rotate cycle path such that it begins with the smallest node
static int[] normalize(int[] path)
{
int[] p = new int[path.length];
int x = smallest(path);
int n;
System.arraycopy(path, 0, p, 0, path.length);
while (p[0] != x)
{
n = p[0];
System.arraycopy(p, 1, p, 0, p.length - 1);
p[p.length - 1] = n;
}
return p;
}
// compare path against known cycles
// return true, iff path is not a known cycle
static Boolean isNew(int[] path)
{
Boolean ret = true;
for(int[] p : cycles)
{
if (equals(p, path))
{
ret = false;
break;
}
}
return ret;
}
static void o(String s)
{
System.out.println(s);
}
// return the int of the array which is the smallest
static int smallest(int[] path)
{
int min = path[0];
for (int p : path)
{
if (p < min)
{
min = p;
}
}
return min;
}
// check if vertex n is contained in path
static Boolean visited(int n, int[] path)
{
Boolean ret = false;
for (int p : path)
{
if (p == n)
{
ret = true;
break;
}
}
return ret;
}
}