回溯法子集树与排列树

当所给问题是从n个元素的集合S中找出满足某种性质的子集时,解空间为子集树。
 
  当所给问题是从n个元素的集合S中找出满足某种性质的排列时,解空间为排列树。
 
      回溯法搜索子集树算法描述为:
     void backtrack(int  t)
    {
       if(t>n)   output(x);
       else
          for(int i=0; i<=1; i++)
          {
             x[t] = i;
             if(constraint(t) && bound(t))      backtrack(t+1);
          }  
    }
   
      回溯法搜索排列树的描述为:
     void backtrack(int  t)
    {
       if(t>n)   output(x);
       else
          for(int i=t; i<n; i++)
          {
             swap(x[t], x[i]);
             if(constraint(t) && bound(t))      backtrack(t+1);
             swap(x[t], x[i]);
          }  
    }

void Backtrack(int t,int *x)

{

      int i;

      if(t>n)

      {

             cout<<“全排列的结果:”;……………………………………  ④

             Output(x);

      }

      else

      {

             for(i=t;i<=n;i++)

             {

                    swap(x[t],x[i]); ………………………………………………①

                    Backtrack(t+1,x); ……………………………………………②

                    swap(x[i],x[t]);  ………………………………………………③

             }

      }

}

 

以n=3 为例说明递归的执行过程:

初始化x[]={1,2,3}

开始时:t=1,n=3;

    进入Backtrack(1) 此时t=1,i=1,执行①此时x[1]=1与x[1]=1交换,然后执行②进入t=1,i=1的Backtrack(2)执行t=2,i=2的①x[2]=2与x[2]=2交换,然后执行②进入t=2,i=2的Backtrack(3)执行t=3,i=3的①x[3]=3与x[3]=3交换,然后执行②进入Backtrack(4)输出x序列(1,2,3)。返回到Backtrack(3)层执行t=3,i=3的③x[3]=3与x[3]=3(即还原成原序列),返回到t=2,i=2的Backtrack(2)层执行③x[2]=2与x[2]=2交换,至此t=2,i=2执行完成。

下面开始执行t=2,i=3执行①此时x[2]=2与x[3]=3交换然后执行②进入t=2,i=3的Backtrack(3)执行t=3,i=3的①x[3]=3与x[3]=3交换,然后执行②进入Backtrack(4)输出x序列(1,3,2)。返回到Backtrack(3)层执行t=3,i=3的③x[3]=3与x[3]=3(即还原成原序列1,3,2),返回到t=2,i=2的Backtrack(2)层执行③x[2]=3与x[3]=2(即还原成原序列1,2,3)交换,至此t=2,i=3执行完成。

至此t=1,i=1执行完成,

   下面关于执行t=1,i=2和t=1,i=3的过程与t=1,i=1类似。

 

代码:

#include”iostream”
using namespace std;
int n,m;
void Output(int *x)
{
 for(int i=1;i<=m;i++)
  cout<<x[i]<<ends;
 cout<<endl;
}
void swap(int &a,int&b)//要用引用
{
 int p;
 p=a;
 a=b;
 b=p;
}
void Backtrack(int t,int *x)
{
 int i;
 if(t>m)
 {
  //cout<<“全排列的结果:”;
  Output(x);
 }
 else
 {
  for(i=t;i<=n;i++)
  {
   swap(x[t],x[i]);
  // cout<<“i=”<<i<<“,”<<“t=”<<t<<“交换后的结果:”;
          // Output(x);
   Backtrack(t+1,x);
   swap(x[i],x[t]);
  }
 }
}
void main()
{
 int *x;
 cin>>n>>m;
 x=new int[n+1];
 for(int i=1;i<=n;i++)
  x[i]=i;
 Backtrack(1,x);
 delete []x;
}

    原文作者:回溯法
    原文地址: https://blog.csdn.net/believejava/article/details/8423834
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞