C方法应该自己递归两次,但似乎没有这样做

时间:2015-01-11 15:52:57

标签: c recursion

我对C比较新,我遇到了以下问题:
我正在尝试使用DPLL算法构建Satsolver。 我想你不必知道算法或问题来回答我的问题。

DPLL方法尝试了一些东西,并在最后调用自己两次:

return (DPLL(newarray[0], variables, &newclauses))
        || (DPLL(newarray2[0], variables, &newclauses2));

它的想法是,最后有两个新阵列。一个获得一个新值,另一个获得否定值。

我的问题是:算法似乎没有检查第二个方法调用

DPLL(newarray2[0], variables, &newclauses2

因为整个算法返回0,如果

(DPLL(newarray[0], variables, &newclauses2)

为0.如果第一次调用为1,则返回1,这很好。

从我的主要方法调用DPLL:

    if (DPLL(phi, variables, &claues))
    {
        printf("%s\n", "SATISFIABLE");
    }
    else
    {
        printf("%s\n", "UNSATISFIABLE");
    }

在c中甚至可以做这样的递归调用吗?

3 个答案:

答案 0 :(得分:3)

第二次通话可能不会发生的原因是short circuit evaluation。如果第一个调用返回true值,则整个表达式为true,因此无需计算第二个调用。如果你想保证两者都被调用,你可以这样做:

int r1 = DPLL(newarray[0], variables, &newclauses);
int r2 = DPLL(newarray2[0], variables, &newclauses2);
return r1 || r2;

在这种情况下,在返回中发生任何短路之前,两个呼叫都已完成。但是,在您给出的示例中,短路评估是一个很好的优化。

答案 1 :(得分:1)

我认为问题是短路 - 在a || b类型的表达式中,b仅在a为假时才会被评估。这是C ++规则(标准)规定的。

在您的情况下,如果第一次呼叫DPLL返回true,则不会执行第二次呼叫。

您需要将代码重构为:

bool a1 = DPLL(newarray[0], variables, &newclauses);
bool a2 = DPLL(newarray2[0], variables, &newclauses2);
return a1 || a2;

答案 2 :(得分:0)

感谢您的回答!

但这并不是很有效。看起来,算法只是达到了第一个算法的全部深度,无论那个算法是什么。我尝试像你提议的那样做,但它给了我一个0,预计1。有趣的是,当我转向函数调用时,所以返回1的调用首先出现,它可以工作。但是它不再适用于ohter文件了。