0

次のプログラムをコーディングして、4 色マップ定理 (簡単に言えば、隣接する領域が同じ色になることなく、マップを 4 色だけで色付けできます) を再帰的に実装しました。すべてがコンパイルされますが、私の出力には誤ったデータが表示されます (今のところ値 0-3 ではなく、各領域の色に対して -1)。私の最大の疑問は、出力が正しくない理由です。

疑問に思っている方のために説明すると、入力ファイルは次のような隣接行列です。

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();
    }
}
4

1 に答える 1

1

あなたはcinを使用していませんが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

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

その隣のいずれかがすでに で色付けされている0場合 ( を使用したことがないため、その行に到達した場合cは常にin に割り当てます)、戻り後、色を に割り当てる前にすぐに戻ります。私はあなたの入力グラフが接続されていると仮定しているので、 の呼び出しは色付きの隣人を見つけ、すぐに戻るので他のものに設定さえしないか、 inの割り当てのみを受け取ります0map[r]map[r] = i;falsercolorTheMap(map, matrix, r, c)r0map[r]if(!acceptable(map, matrix, r, i)) return false;q = false

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

map[r] = -1;ループに続く行の色付けを元に戻します。


別の注意: 貪欲な色付けを実装しようとしていたと思いますが、それは最適ではありません。つまり、この方法では色付けされていない領域になる可能性があります。4 色の問題は、単純な「すべての色を隣接する色のいずれにも割り当てられていない色で塗りつぶせばよい」よりもはるかに複雑です。そうでなければ、4 色で十分であることを証明するのに 1 世紀もかからなかったでしょう。現れます。これは、二次時間を取る正しいアルゴリズムの概要のように見えるものです (リンクが失われた場合の引用: Neil Robertson、Daniel P. Sanders、Paul Seymour、Robin Thomas. 1996. Efficiently four-coloring plane graphs. In Proceedingsコンピューティング理論に関する第 28 回年次 ACM シンポジウム (STOC '96). Association for Computing Machinery, New York, NY, USA, 571–575. DOI:https://doi.org/10.1145/237814.238005 )。4 つの彩色平面グラフが常に可能であることが証明されてから、さらに 20 年後に登場しました。

于 2015-09-18T09:01:44.133 に答える