斑马拼图 - C中的约束满足

时间:2015-10-19 16:04:45

标签: c artificial-intelligence constraint-satisfaction

我试图阅读约束满足问题,并尝试对其进行编码以解决一些示例问题。我遇到http://rosettacode.org/wiki/Zebra_puzzle#C.2B.2B来解决经典zebra puzzle.在rosetta代码网站中给出的C代码中,有以下函数。我只给了它几行。我不知道两个if语句的目的是什么以及它们是如何工作的。 有人可以解释一下吗?

int checkHouses(int ha[5][5])
{
...
    int c_add = 0, c_or = 0;
    int m_add = 0, m_or = 0;
    int d_add = 0, d_or = 0;
    int a_add = 0, a_or = 0;
    int s_add = 0, s_or = 0;

    for (int i = 0; i < 5; i++) {
        // Uniqueness tests.
        if (ha[i][C] >= 0) {
            c_add += (1 << ha[i][C]);
            c_or |= (1 << ha[i][C]);
        }
        if (ha[i][M] >= 0) {
            m_add += (1 << ha[i][M]);
            m_or |= (1 << ha[i][M]);
        }
        if (ha[i][D] >= 0) {
            d_add += (1 << ha[i][D]);
            d_or |= (1 << ha[i][D]);
        }
        if (ha[i][A] >= 0) {
            a_add += (1 << ha[i][A]);
            a_or |= (1 << ha[i][A]);
        }
        if (ha[i][S] >= 0) {
            s_add += (1 << ha[i][S]);
            s_or |= (1 << ha[i][S]);
        }
    }

    if ((c_add != c_or) || (m_add != m_or) || (d_add != d_or)
        || (a_add != a_or) || (s_add != s_or)) {
        return Invalid;
    }

    if ((c_add != 0b11111) || (m_add != 0b11111) || (d_add != 0b11111)
        || (a_add != 0b11111) || (s_add != 0b11111)) {

        return Underfull;
}

1 个答案:

答案 0 :(得分:1)

评论实际上解释了这一点:他们正在验证ha[0..4][ x ]之间的每个x值都没有重复值。

关于 它是如何做的:为每个值分配一个位位置,这样1<<ha[i][ x ]将产生一个只有该位置位的数字组。 x _or将是这些值的OR,而x _add是它们的总和。如果存在重复值,则不会对x _or(该位已设置)产生影响,但在x _add上;因此,他们会有所不同。