子集树和排列树
2016-01-04 09:44
381 查看
假设现在有一列数a[0],a[1], ...a[n-1]
①如果一个问题的解的长度不是固定的,并且解和元素顺序无关,即可以从中选择0个或多个,那么解空间的个数将是指数级别的,为2^n,可以用下面的子集树来表示所有的解
子集树的算法框架为:
void backtrack(int t) {//表示访问到第t层,t从0开始
if (t == n)
output(x);
else
for (int i = 0; i <= n; i++) {//表示选或不选a[t]
x[t] = i;
if(constraint(t) && bound(t))
backtrack(t + 1);
}
}
②如果解空间是由n个元素的排列形成,也就是说n个元素的每一个排列都是解空间中的一个元素,那么,最后解空间的组织形式是排列树
排列树算法的基本框架为:
void backtrack(int t)
{
if(t == n)
output(x);
else
for(inti = t; i < n; i++)
{
swap(x[t], x[i]); 1
if(constraint(t) && bound(t))
{
backtrack(t + 1); 2
swap(x[t], x[i]); 3
}
}
}
遇到子集树和排列数的回溯问题,几乎都可以用上面的模板来套。
注意: 序列A表示“前缀”序列,以便输出,S表示需要进行全排列的元素集合,以便依次选做第一个元素。
以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类似。
①如果一个问题的解的长度不是固定的,并且解和元素顺序无关,即可以从中选择0个或多个,那么解空间的个数将是指数级别的,为2^n,可以用下面的子集树来表示所有的解
子集树的算法框架为:
void backtrack(int t) {//表示访问到第t层,t从0开始
if (t == n)
output(x);
else
for (int i = 0; i <= n; i++) {//表示选或不选a[t]
x[t] = i;
if(constraint(t) && bound(t))
backtrack(t + 1);
}
}
②如果解空间是由n个元素的排列形成,也就是说n个元素的每一个排列都是解空间中的一个元素,那么,最后解空间的组织形式是排列树
排列树算法的基本框架为:
void backtrack(int t)
{
if(t == n)
output(x);
else
for(inti = t; i < n; i++)
{
swap(x[t], x[i]); 1
if(constraint(t) && bound(t))
{
backtrack(t + 1); 2
swap(x[t], x[i]); 3
}
}
}
遇到子集树和排列数的回溯问题,几乎都可以用上面的模板来套。
注意: 序列A表示“前缀”序列,以便输出,S表示需要进行全排列的元素集合,以便依次选做第一个元素。
void print_emu(序列 A, 集合S) { if(序列A满了) 输出序列A; else{ <strong>1.按照从小到大依次考虑S中的每一个元素v 2.print_emu(在A的末尾加上v后得到新的序列, S-{v})</strong> } }
以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类似。
相关文章推荐
- 基于java的PDF格式文件的生成
- SSH 保持连接 (解决Broken pipe)
- MySql语法大全(速成版)
- 同步请求和异步请求的区别
- <iOS>Alamofire的使用
- 最近在学flex做了计算器
- web.xml 模板和Servlet版本
- Cocos2D实现RPG游戏人物地图行走的跟随效果
- Cocos2D实现RPG游戏人物地图行走的跟随效果
- 《Java编程思想》学习笔记9——集合容器高级
- 受用不尽的Gradle使用方法与技巧
- JavaBean为什么要实现Serializable接口的原因
- Java设置模式_创建型_单例模式_只存在一个实例
- Cocos2D实现RPG游戏人物地图行走的跟随效果
- leetcode257---Binary Tree Paths
- 计算机组成原理,微机原理,计算机体系结构这三门课的区别和联系
- <iOS>CocoaPods使用过程
- 几个常用dns
- Eclipse 如何安装单独的一个jar插件
- NAGIOS API