递归回溯拼图

时间:2015-11-09 19:34:53

标签: java arrays recursion backtracking recursive-backtracking

使用JAVA,我需要读取包含这样的n×n表的文本文件(虽然大小可能会有所不同):

0110
1000
1001
0010

假设n是一群人。该表描述了人(行)和另一个人(col)之间的关系。如果表值为1,则两者为朋友;如果为0,他们不是朋友。例如,(0,1)是1;因此,1和2是朋友。我需要为表格中的每个人分配一定数量的字母(在这个特定表格的情况下:2)。如果两个人是朋友,他们必须收到不同的信件。人们不被视为自己的朋友。使用RECURSIVE BACKTRACKING我需要找到这个难题的解决方案并打印出来或确定无法解决问题。

编辑:朋友之友不被视为朋友,除非在表格中明确说明。例如,在此表中,1是2和3的朋友;但是2和3不是朋友。 1和3是朋友,3和4是朋友,但1和4不是朋友。我还应该注意,我的编号是自然的,而在实践中,表索引从0开始。

我不知道从哪里开始这个问题。我确实知道表格从(0,0)到(n,n)有一条对称线,因为如果(1,2)是朋友(2,1)也是朋友,没有人是他们自己的朋友( n,n)总是为0.

编辑:为了直观地展示它,在我看来,只需要大胆的信息来解决问题。

0 110
10 00
100 1
0010

似乎总是将人员1分配给字母A,然后查看行并为值为1的地方分配不同的字母似乎是合理的。我不确定如何准确地执行此操作并且没有必要分配2此时有3个不同的字母(回溯将在稍后处理)。

编辑:我可以使用以下内容为一个人分配一个随机数(稍后将转换为一个字母)。然后可以将该数字添加到排除列表中,该列表将排除这些数字分配给值为1(朋友)的行中的人。

public static int getRandomWithExclusion(Random rnd, int start, int end, List<Integer> exclude) {
    int random = start + rnd.nextInt(end - start + 1 - exclude.size());
    for (int ex : exclude) {
        if (random < ex) {
            break;
        }
        random++;
    }
    return random;

编辑:

到目前为止我有这个代码;但是,我似乎无法找到如何使用回溯来做到这一点。此外,我不确定这将适用于更大的表。在我看来,我需要修改我的排除实施。

    public static void assignLetter(int[][] table, int number_of_letters) {
    int[] assignments = new int[table.length];
    Random rnd = new Random();
    List<Integer> exclude = new ArrayList<>();
    // Person 1 is always assigned 1
    assignments[0]= 1;
    // Add 1 to exclusion list
    exclude.add(1);
    int row;
    int col;
    int nextAssignment;

    // Loop through each row
    for(row = 0; row <= table.length; row++) {
        //Loop through each column in each row
        for (col = row + 1; col < table.length; col++) {
            // If column value in row 1 equals 1, assigned number cannot be 1
            if (table[row][col] == 1) {
                // Generate random number within parameters excluding 1
                nextAssignment = getRandomWithExclusion(rnd, 1, number_of_letters, exclude);
                assignments[col] = nextAssignment;
            }
            // If column value in row 1 equals 0, assign person any number within parameters
            if (table[row][col] == 0 && row == 0) {
                // Generate random number within parameters, no exclusions
                nextAssignment = rnd.nextInt(number_of_letters) + 1;
                assignments[col] = nextAssignment;
            }
            // If a value in a subsequent row is 1 and the corresponding assignments are equal,
            // the assignments must be altered per the specifications
            if (table[row][col] == 1 && row > 0 && assignments[row] == assignments[col]) {
                // If the exclude list is equal to the number of letters, there is no solution
                if (exclude.size() == number_of_letters) {
                    System.out.println("There is no solution");
                }
                // If the value in row 1 of the table is not 1, it can be assigned 1
                if (table[0][col] != 1) {
                    nextAssignment = 1;
                    assignments[col] = nextAssignment;
                }
            }
        }
    }
    for (int i = 0; i < assignments.length; i++) {
        int person = i + 1;
        int letterNum = assignments[i];
        char[] alphaArray = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
                'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
        char letter = alphaArray[letterNum-1];
        System.out.println(person + " : " + letter);
    }
}

你有什么建议可以帮助我走上正确的道路吗?

谢谢!

0 个答案:

没有答案