为什么回溯以其方式工作?
-
16-10-2019 - |
题
我最近刚刚开始在CS环境中学习简单递归功能,以及组合应用程序以及诸如Backtracking and Divide ET Impera之类的技术。
我为我的问题选择的示例问题是n皇后问题(给定皇后区和*n棋盘,您如何将皇后定位,以免彼此攻击?)。我知道,基本思想是生成所有可能的位置(通过生成笛卡尔产品),然后在它们无效(通过验证功能)时简单地丢弃它们。
这是我的示例实现:
int valid (int k)
{
for (int i = 1; i < k; i++)
{
if (sol[i] == sol[k]) return 0;
if (abs(sol[i] - sol[k]) == abs(i - k)) return 0;
}
return 1;
}
void print ()
{
for (int i = 1; i <= n; i++)
{
cout << sol[i];
}
cout << endl;
how++;
}
void backtrack (int k)
{
if (k == n+1) print();
else
{
sol[k] = 0;
while (sol[k] < n)
{
sol[k]++;
if (valid(k)) backtrack(k+1);
}
}
}
- 为什么在验证函数中,通过用k,2用K等检查1逐渐检查解决方案的检查。我认为该解决方案可以成对正确,但总体上是错误的(例如,相对于3个相对于3个相对于2的第1和2个相对于2个相对于2个相对于2的放置)吗?
解决方案
例如,相对于3相对于3的1和2正确放置,但相对于2的1相对于2的放置错误地放置了错误吗?
您已经测试了1和2正确放置,否则您不会打电话 backtrack(3)
.
回顾 sol[i] = j
意味着$ i $中的女王将其放在行$ j $上。通过打电话 backtrack(k+1)
您已经验证了$ 1 dots k $中的每个女王都正确放置(非填料)。
不隶属于 cs.stackexchange