1、概念
回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。
回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
许多复杂的,规模较大的问题都可以使用回溯法,有“通用解题方法”的美称。
2、基本思想
在包含问题的所有解的解空间树中,按照深度优先搜索的策略,从根结点出发深度探索解空间树。当探索到某一结点时,要先判断该结点是否包含问题的解,如果包含,就从该结点出发继续探索下去,如果该结点不包含问题的解,则逐层向其祖先结点回溯。(其实回溯法就是对隐式图的深度优先搜索算法)。
若用回溯法求问题的所有解时,要回溯到根,且根结点的所有可行的子树都要已被搜索遍才结束。
而若使用回溯法求任一个解时,只要搜索到问题的一个解就可以结束。
3、用回溯法解题的一般步骤:
(1)针对所给问题,确定问题的解空间:
首先应明确定义问题的解空间,问题的解空间应至少包含问题的一个(最优)解。
(2)确定结点的扩展搜索规则
(3)以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。
4、算法应用示例:
八皇后问题的递归实现
分书问题:
有编号为 A、B、C、D、E 的 5 本书,以及 5 个人,每本书可以分给每一个对该书有兴趣的人阅读,且每个人都只能分到一本自己
感兴趣的书。问当给定 5 个人对 5 本书的感兴趣情况时,怎样分配这 5 本书才能让每个人都开始阅读。
思路:每次都尝试给第 p 个人从 5 本书中分出他感兴趣的一本,若不能构成最终解,则撤销回溯到上一个人(即第 p – 1 个人)的分配。
我们如下确定:
int bookCounts 表示书的总数量,与总人数相等
int like [p] [b] = 1 表示第 p 个人喜欢读第 b 本书,即具体的问题初始条件;
int given [b] = p 表示第 b 本书分给了第 p 个人,即保存解的标识数组;
注:在这里 p ,b (即下标)都从 0 开始,算法实现如下:
/**
* 回溯法求解分书问题
* @author haolloyin
*/
public class AllacateBooks {
// 书的总数量,与总人数相等
private int bookCounts = 5;
// like[p][b]=1 表示第 p 个人喜欢读第 b 本书
private int[][] like = new int[bookCounts][bookCounts];
// given[b] = p 表示将第 b 本书分配给第 p 个人
private int[] given = new int[bookCounts];
// 初始化标识数组 given[] 和传入各人喜欢书的情况数组
private void init(int like[][]) {
for (int i = 0; i < bookCounts; i++) {
given[i] = -1; // -1 表示第 i 本书还没分配出去
}
this.like = like;
}
// 尝试给每一个人分配一本书
public void allocateBook(int person) {
for (int bookNum = 0; bookNum < bookCounts; bookNum++) {
if (like[person][bookNum] == 1 && given[bookNum] == -1) {
given[bookNum] = person;
if (person == bookCounts - 1) {
// 打印结果
for (int i = 0; i < bookCounts; i++) {
System.out.println("人 " + (given[i]+1) + " <---> 书 " + ((char)(i + 'A')));
}
System.out.println();
} else {
// 为下一个人分配一本书
allocateBook(person + 1);
}
// 失败,回溯重新寻找解
given[bookNum] = -1;
}
}
}
// 测试
public static void main(String[] args) {
// 构造一个问题规模
int[][] like = new int[][]{
{ 0, 0, 1, 1, 0 },
{ 1, 1, 0, 0, 1 },
{ 0, 1, 1, 0, 1 },
{ 0, 0, 0, 1, 0 },
{ 0, 1, 0, 0, 1 }};
AllacateBooks allocateBooks = new AllacateBooks();
allocateBooks.init(like);
allocateBooks.allocateBook(0);
}
}
对应于所给的问题规模,所得的解如下:
人 2 <---> 书 A
人 3 <---> 书 B
人 1 <---> 书 C
人 4 <---> 书 D
人 5 <---> 书 E
人 2 <---> 书 A
人 5 <---> 书 B
人 1 <---> 书 C
人 4 <---> 书 D
人 3 <---> 书 E
[实验目的]
综合运用数组、递归等数据结构知识,掌握、提高分析、设计、实现及测试程序的综合能力。
[实验内容及要求]
以一个M×N的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。
(1)根据二维数组,输出迷宫的图形。
(2)探索迷宫的四个方向:RIGHT为向右,DOWN向下,LEFT向左,UP向上,输出从入口到出口的行走路径。
[测试数据]
左上角(1,1)为入口,右下角(8,9)为出口。
0
|
0
|
1
|
0
|
0
|
0
|
1
|
0
|
0
|
0
|
1
|
0
|
0
|
0
|
1
|
0
|
0
|
0
|
1
|
0
|
1
|
1
|
0
|
1
|
0
|
1
|
1
|
1
|
0
|
0
|
1
|
0
|
0
|
0
|
0
|
1
|
0
|
0
|
0
|
0
|
0
|
1
|
0
|
0
|
0
|
1
|
0
|
1
|
0
|
1
|
1
|
1
|
1
|
0
|
0
|
1
|
1
|
1
|
0
|
0
|
0
|
1
|
0
|
1
|
1
|
1
|
0
|
0
|
0
|
0
|
0
|
0
|
[实现提示]
可使用回溯方法,即从入口出发,顺着某一个方向进行探索,若能走通,则继续往前进;否则沿着原路退回,换一个方向继续探索,直至出口位置,求得一条通路。假如所有可能的通路都探索到而未能到达出口,则所设定的迷宫没有通路。
分享到:
相关推荐
回溯算法是一种常用的搜索算法,它可以用于解决许多复杂的问题。回溯算法的基本思想是,通过不断地尝试和回溯来找到问题的解。它可以看作蛮力法穷举搜索的改进,能够避免搜索所有可能的解,从而提高搜索效率。 在...
回溯算法是一种重要的搜索策略,尤其在解决组合优化问题中广泛应用。它通过尝试所有可能的解决方案路径,并在遇到无效或不满足条件的情况时回溯,以寻找其他可能的解。回溯法通常与数据结构结合使用,如数组、栈、...
常用算法介绍,及其几道算法题,常见算法包括排序算法、搜索算法、动态规划、贪心算法、回溯算法、分治算法等
回溯算法常用于求解组合优化问题,如八皇后问题和N皇后问题,它通过尝试所有可能的解决方案并适时回溯来找到可行解。 最后,分支限界法是解决整数规划和约束满足问题的有效手段,通过剪枝操作减少搜索空间,提高...
通过回溯算法,我们可以逐步尝试每个皇后的位置,当发现冲突时,回溯到前一个皇后的位置并改变其位置,直到找到所有皇后都符合要求的解。 另一个例子是最大k乘积问题,该问题要求将一个整数分成k段,并求出这k段...
回溯法是一种重要的算法策略,尤其适用于解决复杂的问题,如组合优化问题和约束满足问题。它基于深度优先搜索,通过尝试不同的解决方案并适时回溯来找到有效解或所有解。以下将详细介绍回溯法的基本概念、思想以及...
回溯算法是一种在解决问题时通过尝试所有可能的解来寻找问题解决方案的方法,它适用于约束满足问题和搜索问题。在回溯算法中,我们通常构建一个决策树,沿着这个树进行深度优先搜索,直到找到所有可能的解或确定无解...
《常用算法程序集-徐士良》是一本深入探讨计算机科学中常见算法的书籍,作者徐士良在书中详尽地介绍了多种实用算法,并通过实际的程序代码来帮助读者理解和应用这些算法。这本书旨在提高读者的编程技能和解决实际...
《常用算法程序集》第6版是一本涵盖了广泛算法实现的宝贵资源,旨在帮助程序员提升在实际编程中解决复杂问题的能力。这本书包含了多种经典和现代的算法,通过代码实例进行详细解析,使得读者能深入理解并掌握这些...
本压缩包文件“C常用算法程序集”显然是一份包含了多种常见算法的代码集合,旨在帮助程序员理解和实践这些算法。 首先,我们来探讨一些基础的C语言算法。C语言中的基本算法包括排序算法、查找算法、递归算法、字符...
回溯法是一种常用的算法策略,主要应用于解决那些需要通过尝试所有可能的解决方案来找到问题答案的问题。它通常与深度优先搜索(DFS)相结合,用于遍历或搜索问题的解空间树。在解空间树中,每个节点代表问题的一个...
四、回溯算法思想实现 回溯算法是一种搜索算法,它可以解决许多问题,例如八皇后问题、旅行商问题等。回溯算法可以使用递归算法来实现。 在JavaScript中,回溯算法可以使用递归算法来实现,然后使用数组来存储中间...
学习电脑信息五大常用算法之四:回溯法,算法数据结构 五大常用算法
《常用算法程序集(C 语言描述)第四版》是由徐士良编著的一本深入探讨C语言实现算法的书籍,特别适合于那些希望在实际工程中应用算法的读者。这本书精心组织了各种常用且高效的算法,旨在帮助读者理解和掌握算法的...
VB常用算法大全涵盖了多种在编程实践中经常遇到的算法,这些算法在处理数据、优化代码效率、解决逻辑问题等方面起着关键作用。以下是VB常用的一些重要算法及其详细解释: 1. **排序算法**: - 冒泡排序:通过重复...
《电子计算机常用算法》这本书是算法学习的重要参考资料,它涵盖了计算机科学中许多核心的算法,旨在帮助读者理解和掌握这些算法的原理与应用。算法在计算机科学中扮演着基础且关键的角色,它们是解决问题和设计高效...
学习电脑信息五大常用算法之四:回溯法
本文将深入探讨C++中的一些常用算法,尤其是与数据存储相关的实例。 1. **排序算法**: - **冒泡排序**:是最基础的排序算法之一,通过不断交换相邻的不正确顺序元素实现排序。虽然效率较低,但易于理解。 - **...
《VB常用算法大全》是一本专注于Visual Basic编程语言中常用算法的资源集合,它涵盖了从基础到高级的各种算法实现,旨在帮助VB程序员提升算法理解和应用能力。在这个压缩包中,可能包含了详细的算法介绍、示例代码...
在计算机科学领域,算法是解决问题的关键工具,其中贪婪算法、回溯法和动态规划是三种常用的优化策略。本文将深入探讨这些算法的概念、原理及应用。 首先,贪婪算法是一种求解最优解的策略,它在每一步选择中都采取...