当所给问题是从n个元素的集合S中找出满足某种性质的子集时,解空间为 子集树。例如: 0-1背包问题
当所给问题是从n个元素的集合S中找出满足某种性质的排列时,解空间为 排列树。例如: 旅行售货员问题
回溯法搜索子集树算法描述为:
void backtrack(int t)
{
if(t>n)
output(x);
else
for(int i=0; i<=1; i++) //注意,这里的0,1 是X[i]的取值范围,t表示层数
{
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++) //这里的n表示层数,不要和子集树搞混了
{
swap(x[t], x[i]);
if(constraint(t) && bound(t)) backtrack(t+1);
swap(x[t], x[i]);
}
}
具体实例:
#include
#include
#define N 3
int x[N+1];
void Backtrace(int t)
{
if(t>N)
{
for(int i=1;i<=N;i++)
{
printf("%d ",x[i]);
}
printf("\n");
}
else
{
for(int i=0;i<=1;i++)
{
x[t]=i;
Backtrace(t+1);
}
}
}
int main()
{
memset(x,0,(N+1)*sizeof(int));
Backtrace(1);
}
--------------------------------------------------------------------------------------------------
#include
#include
#define N 3
int x[N+1]={0,1,2,3};
void swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
void Backtrace(int t)
{
if(t>N)
{
for(int i=1;i<=N;i++)
{
printf("%d ",x[i]);
}
printf("\n");
}
else
{
for(int i=t;i<=N;i++)
{
swap(x[t],x[i]);
Backtrace(t+1);
swap(x[t],x[i]);
}
}
}
int main()
{
Backtrace(1);
}
子集树实例:
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 using namespace std; 8 9 void printVector(vector array );10 11 void dfs(vector & array, int dep)12 {13 int size = array.size();14 if(dep == size)15 {16 printVector(array);17 return;18 }19 //dfs to the next level20 for(int i = 0; i < 2; i++)21 {22 array[dep] = i;23 dfs(array, dep+1);24 }25 26 }27 28 29 void printVector(vector array )30 {31 for(int i = 0; i
打印结果:
0 0 0 0 0
0 0 0 0 10 0 0 1 00 0 0 1 10 0 1 0 00 0 1 0 10 0 1 1 00 0 1 1 10 1 0 0 00 1 0 0 10 1 0 1 00 1 0 1 10 1 1 0 00 1 1 0 10 1 1 1 00 1 1 1 11 0 0 0 01 0 0 0 11 0 0 1 01 0 0 1 11 0 1 0 01 0 1 0 11 0 1 1 01 0 1 1 11 1 0 0 01 1 0 0 11 1 0 1 01 1 0 1 11 1 1 0 01 1 1 0 11 1 1 1 01 1 1 1 1