回溯算法

回溯算法

搜索与回溯是计算机解题中常用的算法,很多问题无法根据某种确定的计算法则来求解,可以利用搜索与回溯的技术求解。回溯是搜索算法中的一种控制策略。它的基本思想是:为了求得问题的解,先选择某一种可能情况向前探索,在探索过程中,一旦发现原来的选择是错误的,就退回一步重新选择,继续向前探索,如此反复进行,直至得到解或证明无解。

如迷宫问题:进入迷宫后,先随意选择一个前进方向,一步步向前试探前进,如果碰到死胡同,说明前进方向已无路可走,这时,首先看其它方向是否还有路可走,如果有路可走,则沿该方向再向前试探;如果已无路可走,则返回一步,再看其它方向是否还有路可走;如果有路可走,则沿该方向再向前试探。按此原则不断搜索回溯再搜索,直到找到新的出路或从原路返回入口处无解为止。

递归回溯法算法框架[一]

int Search(int k)

 {

 for (i=1;i<=算符种数;i++)

  if (满足条件)

     {

    保存结果

    if (到目的地) 输出解;

              else Search(k+1);

    恢复:保存结果之前的状态{回溯一步}

     }

 }

递归回溯法算法框架[二]

int Search(int k)

 {

   if  (到目的地) 输出解;

   else

    for (i=1;i<=算符种数;i++)

     if  (满足条件)

       {

        保存结果;

                     Search(k+1);

        恢复:保存结果之前的状态{回溯一步}

       }

 }

【例1】素数环:从1到20这20个数摆成一个环,要求相邻的两个数的和是一个素数。

【算法分析】

非常明显,这是一道回溯的题目。从1开始,每个空位有20种可能,只要填进去的数合法:与前面的数不相同;与左边相邻的数的和是一个素数。第20个数还要判断和第1个数的和是否素数。

【算法流程】

1、数据初始化;   2、递归填数:判断第i个数填入是否合法;

A、如果合法:填数;判断是否到达目标(20个已填完):是,打印结果;不是,递归填下一个;

B、如果不合法:选择下一种可能;

【参考程序】

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstdlib>
 4 #include<cmath>
 5 using namespace std;
 6 bool b[21]={0};
 7 int total=0,a[21]={0};
 8 int search(int);                           //回溯过程
 9 int print();                               //输出方案
10 bool pd(int,int);                          //判断素数
11 int main()
12 {
13     search(1);
14     cout<<total<<endl;                    //输出总方案数
15 }
16 int search(int t)
17 {
18     int i;
19     for (i=1;i<=20;i++)                     //有20个数可选
20      if (pd(a[t-1],i)&&(!b[i]))            //判断与前一个数是否构成素数及该数是否可用
21       {
22          a[t]=i;
23          b[i]=1;
24          if (t==20) { if (pd(a[20],a[1])) print();}
25              else search(t+1);
26          b[i]=0//一会儿变1一会儿变0.。。那么他的存在到底是干嘛的叻
27       }
28 }
29 int print()
30 {
31    total++;
32    cout<<"<"<<total<<">";
33    for (int j=1;j<=20;j++)
34      cout<<a[j]<<" ";
35    cout<<endl; 
36   }
37 bool pd(int x,int y)
38 {
39     int k=2,i=x+y;
40     while (k<=sqrt(i)&&i%k!=0) k++;
41     if (k>sqrt(i)) return 1;
42        else return 0;
43 }

***总结来说呢。。回溯好像就是一种递归,满足了我就继续走,不满足掉头重新走啦。据说(好像就是)他能和神马图的联系在一起,但是很sad我不会图论哇。。打算求助小哥哥。。毕竟我老人家连例一代码还有不懂的地方。。好sad我貌似汉诺塔还没弄明白。。。OMG我都做了些神马。。。sadsad。。。。

 

 

原文地址:https://www.cnblogs.com/rax-/p/8620574.html