纠正用于回溯图着色算法的 Java 递归代码

Posted

技术标签:

【中文标题】纠正用于回溯图着色算法的 Java 递归代码【英文标题】:Rectifying Java recursive code for Backtracking Graph Coloring Algorithm 【发布时间】:2012-03-18 18:04:36 【问题描述】:

问题是使用递归为给定的图形着色最少的颜色,这样相邻的顶点不能有相同的颜色。函数签名是静态字符串穷举(整数颜色,字符串前缀),其中颜色是在该迭代中使用的颜色和前缀是由每个节点的颜色组成的字符串(例如,如果有 3 个节点,其中节点 0 用颜色 0 着色,节点 1 用颜色 1 着色,节点 2 用颜色 2 着色;那么前缀将是 012)。当所有节点都着色时,该函数返回字符串前缀。第一次调用是使用参数 (0,"") 进行的,这意味着尝试用 0 种颜色着色。 这是我写的代码。对于少于 34 个节点,它工作正常并返回正确答案,但对于大于 34 个节点,该函数不会返回到主节点。任何改进代码的想法将不胜感激。如果需要更多信息,请告诉我。

int n=36;
static int[] lastcolor = new int[n];    
static StringBuilder newprefix ;
String addprefix="";
static int node=0,j=0;
Graph.generateFixedSet(n);
verticies2 =Graph.getVerticies();

public static String exhaustive(int color,String prefix)

 

    newprefix = new StringBuilder(prefix);

        if(prefix.length()==verticies2.size())
            return prefix;
        else
        
             for(;j<=color;j++)
            
                lastcolor[node]=j;

                addprefix = Integer.toString(j);
            canColor =1;
            tempnode = (verticies2.get(node)).getEdges();
                for( h=0;h<tempnode.size();h++)
                
                     if((tempnode.get(h)).getColor() == j)
                
                    canColor =0;
                    break;
                

             

            if(canColor==1)
                
                        verticies2.get(node).setColor(j);              
                    node++;
                        j=0;
                newprefix.append(addprefix);
                        break;

                //end if canColor  
            //end for

        if(j!= 0)
            


                if(node==1)
                                           
                        color++;
                        j=0;
                        node=1;
                newprefix.delete(0,newprefix.length());
                newprefix.append("0");

                //end if node <=1
                else
                
                        verticies2.get(node).setColor(-1);
                        node--;
                        j=lastcolor[node]+1;
                        newprefix.setLength(node);
                    
            //end if j!=0
            prefix = newprefix.toString();
            return exhaustive(color,prefix);
            //end else
     //end exhaustive

【问题讨论】:

欢迎来到 Stack Overflow!让陌生人通过检查来发现代码中的错误是没有效率的。您应该使用调试器或打印语句来识别(或至少隔离)问题,然后再提出更具体的问题。 嗨@OliCharlesworth!你是对的,但程序没有显示任何错误。而且由于程序是递归的,对自己进行了数千次调用,我不确定如何跟踪问题。请指教。 @HighBit:如果程序永远不会返回到 main,这意味着它陷入了某种无限循环/递归。所以你应该能够在调试器中运行应用程序,然后在几秒钟后按 Ctrl-C(停止),调试器会显示你卡在哪里。 谢谢,我会尽快回复您。 【参考方案1】:

不要使用递归。如有必要,使用循环...和数组列表。

【讨论】:

我也不喜欢递归,只是这里需要使用递归,正如我在第一行中所说的那样。此外,我认为最好使用递归来实现回溯。还是有更好的办法? 没有明确说明您必须这样做。我很好奇为什么你需要使用递归。您可以在一小部分代码中使用递归,对吗?那能满足要求吗? 这是一个算法分析问题,目的是证明 NP 完全问题的指数复杂度 不太了解...我对NP完全的了解有限...我可以告诉您的是,以您拥有的形式使用递归是一个坏主意。有了你已经拥有的东西,你可以很容易地创建一个循环并且几乎没有性能损失,同时消除了过程中任何堆栈溢出的可能性。否则,我想不出使用递归的好解决方案。

以上是关于纠正用于回溯图着色算法的 Java 递归代码的主要内容,如果未能解决你的问题,请参考以下文章

递归和回溯求解8皇后问题

算法漫游指北(第十篇):泛型递归递归代码模板递归思维要点分治算法回溯算法

Java数据结构与算法——递归与回溯

Java数据结构—递归

7, java数据结构和算法: 八皇后问题分析和实现 , 递归回溯

7, java数据结构和算法: 八皇后问题分析和实现 , 递归回溯