四色定理递归回溯算法

时间:2015-09-18 02:10:37

标签: java algorithm recursion backtracking recursive-backtracking

我编写了以下程序来实现四色图定理(任何地图都可以用4种颜色着色而没有任何相邻区域是相同的颜色,简而言之)递归地。一切都编译,但我的输出给了我错误的数据(每个区域的颜色为-1而不是现在的值0-3)。我最大的问题是为什么输出不正确。

对于那些想知道的人,输入文件是一个邻接矩阵,其内容如下:

0 1 0 1  
1 0 1 0  
0 1 0 1  
1 0 1 0  

这是我的代码:

public class FourColorMapThm 
{
    public static boolean acceptable(int[] map, int[][] matrix, int r, int c)
    {
        for(int i = 0; i < map.length; i++)
        {
            if(matrix[r][i] == 1)
            {
                if(map[i] == c) return false;
            }
        }
        return true;
    }

    public static boolean colorTheMap(int[] map, int[][] matrix, int r, int c)
    {
        boolean q = false;
        int i = 0;

        if(!acceptable(map, matrix, r, i)) return false;

        map[r] = i;
        boolean done = true;

        for(int j = 0; j < map.length; j++)
        {
            if(map[j] == -1)
            {
                done = false;
            }
        }
        if(done) return true;

        do
        {
            i++;
            q = colorTheMap(map, matrix, r+1, i);
            if(q) return true;
        }
        while(i <= 3);

        map[r] = -1;
        return false;
    }

    public static void main(String[] args) throws IOException
    {
        Scanner in = new Scanner(System.in);
        String snumRegions, fileName;
        int numRegions;

        System.out.print("Enter the number of regions: ");
        snumRegions = in.nextLine();
        numRegions = Integer.parseInt(snumRegions);

        System.out.print("\nEnter filename for adjacency matrix: ");
        fileName = in.nextLine();
        in.close();

        Scanner inFile = new Scanner(new FileReader(fileName));
        PrintWriter outFile = new PrintWriter("coloredMap.txt");
        int[][] matrix = new int[numRegions][numRegions];
        int[] map = new int[numRegions];

        //initializing matrix from file
        for(int row = 0; row < matrix.length; row++)
        {
            for(int col = 0; col < matrix.length; col++)
            {
                matrix[row][col] = inFile.nextInt();
            }
        }
        inFile.close();

        //initialize map vals to -1
        for(int i = 0; i < map.length; i++)
        {
                map[i] = -1;
        }

        colorTheMap(map, matrix, 0, 0);

        outFile.println("Region\t\tColor");
        for(int i = 0; i < map.length; i++)
        {
            outFile.println(i+1 + "\t\t" + map[i]);
        }
        outFile.close();
    }
}

1 个答案:

答案 0 :(得分:1)

您未在c中使用colorTheMap,而您可能想要这样做。

您获得map所有条目-1的原因是:

    int i = 0;
    if(!acceptable(map, matrix, r, i)) return false;
    map[r] = i;
    .
    .
    .
    do
    {
        i++;
        q = colorTheMap(map, matrix, r+1, i);
        if(q) return true;
    }
    while(i <= 3);
    map[r] = -1;

colorTheMap(map, matrix, r+1, i)的每次通话都会在false点击<{1}}。

    int i = 0;
    if(!acceptable(map, matrix, r, i)) return false;

如果其任何邻居已使用0着色(因为您从未使用c,则始终会0map[r]分配给map[r] = i;如果你到达那一行),那么在返回之后,我们会立即返回false,然后再为r分配任何颜色。我假设您的输入图是已连接的,因此colorTheMap(map, matrix, r, c)的任何调用都会找到r的邻居,其中0为彩色,并且甚至不会将map[r]设置为任何内容否则if(!acceptable(map, matrix, r, i)) return false;会立即返回,或者只接收<{p}}中q = false的作业

    do
    {
        i++;
        q = colorTheMap(map, matrix, r+1, i);
        if(q) return true;
    }
    while(i <= 3);

并撤消循环后面的行map[r] = -1;中的着色。

另一个注意事项:我假设你试图实现贪婪的着色,但这并不是最佳的,即你可能会以这种方式结束无色区域。四色问题比一个简单的颜色更复杂,只是颜色,所有颜色都没有被分配给你的邻居并且你很好&#34;否则它不会超过一个世纪以证明四种颜色足以出现。 Here看起来像是一个采用二次时间的正确算法的轮廓。在证明四个着色平面图总是可能的证据之后又出现了20年。