素数序列的回溯算法

Backtracking algorithm for prime sequence

本文关键字:回溯算法      更新时间:2023-10-16

我在回溯时遇到问题,不确定我正在做的是否完全是回溯。

我的例子有 n 个整数,它将是 [5,6,7,8]。

从这些整数中,我需要找到素数序列是否存在以及它是否确实显示它。

此示例的素数序列为 7,6,5,8,因为 7+6=13 6+5=11 5+8=13

为了得到答案,我可以遍历每个n,然后尝试查看它是否是素数序列。

从 5 开始:

  • 5,6[7,8]
  • 5,6,7[8]

因为 7+8 不是素数。转到下一个整数。

因为 5+7 不是素数。转到下一个整数。

  • 5,8,[6,7]
由于 8+

6 或 8+7 不是素数。您已完成 5。

从 6 点开始:

  • 6,5[7,8]
  • 6,5,8[7]

因为 7+8 不是素数。转到下一个整数。

  • 6,7[5,8]
因为 7+

5 或 7+8 不是素数。转到下一个整数。

因为 6+8 不是素数。你完成了 6。

从 7 点开始:

  • 7,6[5,8]
  • 7,6,5[8]
  • 7,6,5,8

结束,因为你找到了素数序列。

那么我该如何通过回溯来解决这个问题呢?

在这种情况下,回溯的想法基本上是这样的:让我找到整个工作事物的子序列(或前缀)的延续。如果我成功了,我会将该延续返回给我的调用者。如果我运气不好,我会让我的来电者尝试不同的前缀。

更准确地说:

// call initially as Backtrack(epsilon, all numbers)
Backtrack(Sequence fixedPrefix, Set unbound) {
  if (unbound is empty) {
    return check(fixedPrefix);
  }
  for all (element in unbound) {
    if (Backtrack(concat(fixedPrefix,element), setminus(unbound,element))
      return true;
  }
  return false;
}

请注意,此算法只会告诉您一个序列是否存在(并且在C++中的直接实现会非常慢),但不会告诉您该序列是什么,但这很容易修改。

无论如何,回溯中的"后退"发生在递归调用不走运的最后一行:这将提示调用实例尝试另一个前缀,因此控制流有点颠倒。

你的函数(无论是否伪代码)没有做任何富有成效的事情。我实际上不确定它应该做什么。 u = 0;紧跟if(u == 4);,您的isPrime函数总是传递(Integers[0]+integers[0])

我相信你所说的回溯更恰当地称为递归函数(一个可以调用自己的函数)。回溯是递归函数可能表现出的特定行为的糟糕(模糊)名称。

如果你想要一个这样的递归函数,你需要放弃它并重新开始。用简单的英语(或其他语言)写出函数应该做什么。然后,一旦你知道你需要传递给它什么,失败和成功之间的区别,以及失败或成功时返回的内容(失败时需要如何修改向量),就编码到它。

超级提示:对于少量的整数选择,例如您介绍的整数,请尝试在 stl < algorithm >next_permutation(),以快速浏览向量中整数的可能排列。