素数序列的回溯算法

时间:2012-04-11 01:09:14

标签: c++ backtracking

我在回溯时遇到了麻烦,并且不确定我正在做的事情是否正在回溯。

我的例子中有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

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

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

2 个答案:

答案 0 :(得分:3)

在这种情况下回溯的想法基本上是这样的:让我找到一个有效的整体事物的子序列(或前缀)的延续。如果我成功了,我会把那个延续告诉我的来电者。如果我运气不好,我会要求我的来电者尝试不同的前缀。

更确切地说:

// 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 ++中的直接实现会非常慢)但不是该序列是什么,但这很容易修改。

无论如何,回溯中的“后退”发生在递归调用运气不好的最后一行:这将提示调用实例尝试另一个前缀,所以控制流程有点逆转。

答案 1 :(得分:1)

您的功能(伪代码与否)不会产生任何效果。我实际上不确定它应该做什么。即。 u = 0;后紧跟if(u == 4);isPrime函数始终通过(Integers[0]+integers[0])

我相信你所说的回溯更恰当地称为递归函数(一种可以调用自身的函数)。对于递归函数可以表现出的特定行为,回溯是一个很差(模糊)的名称。

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

超级提示:对于您提供的小整数整数,请在stl next_permutation()中尝试< algorithm >,以便快速完成向量中可能的整数排列。