回溯法的效率研究分析
算法设计与分析——批处理作业调度(回溯法)

算法设计与分析——批处理作业调度(回溯法)之前讲过⼀个相似的问题流⽔作业调度问题,那⼀道题最开始⽤动态规划,推到最后得到了⼀个Johnson法则,变成了⼀个排序问题,有兴趣的可以看⼀下本篇博客主要参考⾃⼀、问题描述给定n个作业的集合{J1,J2,…,Jn}。
每个作业必须先由机器1处理,然后由机器2处理。
作业Ji需要机器j的处理时间为t ji。
对于⼀个确定的作业调度,设Fji是作业i在机器j上完成处理的时间。
所有作业在机器2上完成处理的时间和称为该作业调度的完成时间和。
批处理作业调度问题要求对于给定的n个作业,制定最佳作业调度⽅案,使其完成时间和达到最⼩。
例:设n=3,考虑以下实例:看到这⾥可能会对这些完成时间和是怎么计算出来的会有疑问,这⾥我拿123和312的⽅案来说明⼀下。
对于调度⽅案(1,2,3)作业1在机器1上完成的时间是2,在机器2上完成的时间是3作业2在机器1上完成的时间是5,在机器2上完成的时间是6作业3在机器1上完成的时间是7,在机器2上完成的时间是10所以,作业调度的完成时间和= 3 + 6 + 10这⾥我们可以思考⼀下作业i在机器2上完成的时间应该怎么去求?作业i在机器1上完成的时间是连续的,所以是直接累加就可以。
但对于机器2就会产⽣两种情况,这两种情况其实就是上图的两种情况,对于(1,2,3)的调度⽅案,在求作业2在机器2上完成的时间时,由于作业2在机器1上还没有完成,这就需要先等待机器1处理完;⽽对于(3,1,2)的调度⽅案,在求作业2在机器2上完成的时间时,作业2在机器1早已完成,⽆需等待,直接在作业1被机器1处理之后就能接着被处理。
综上,我们可以得到如下表达式if(F2[i-1] > F1[i])F2[i] = F2[i-1] + t[2][i]elseF2[i] = F1[i] + t[2][i]⼆、算法设计类Flowshop的数据成员记录解空间的结点信息,M输⼊作业时间,bestf记录当前最⼩完成时间和,数组bestx记录相应的当前最佳作业调度。
回溯分析报告

回溯分析报告1. 概述回溯分析是一种常用的问题解决方法,在许多领域都有广泛的应用。
回溯分析是一种深度优先搜索的算法,通过尝试所有可能的解决方案来寻找问题的最优解。
在本文档中,我们将详细介绍回溯分析的原理和应用,以及如何使用回溯分析来解决问题。
2. 回溯分析原理回溯分析的基本原理是尝试所有可能的解决方案,并通过逐步迭代的方式来找到最优解。
回溯分析通常包括以下几个步骤:1.定义问题的解空间:确定问题的解空间,即问题的可能解决方案的集合。
2.筛选可行解:根据问题的约束条件筛选出满足条件的可行解。
3.遍历解空间:遍历解空间中的所有可能解,通常使用递归的方式来实现。
4.判断解的有效性:判断每个可能解是否满足问题的要求,如果不满足,则回溯到上一步继续尝试其他解。
5.找到最优解:通过不断地回溯和尝试,找到问题的最优解。
3. 回溯分析的应用回溯分析在许多领域都有广泛的应用,下面分别介绍了几个常见的应用场景:3.1 组合优化问题回溯分析可以用于解决组合优化问题,如旅行商问题(TSP)、背包问题等。
通过尝试所有可能的组合方式,找到最优解决方案。
3.2 图的遍历和搜索回溯分析可以用于图的遍历和搜索问题,如深度优先搜索(DFS)、广度优先搜索(BFS)等。
通过逐步地向前搜索,找到满足条件的解。
3.3 棋盘类问题回溯分析可以用于解决各种棋盘类问题,如八皇后问题、数独等。
通过逐步地摆放棋子或填写数字,找到满足条件的解。
3.4 解数独问题示例下面以解数独问题为例,介绍回溯分析的具体应用:def solve_sudoku(board):if not find_empty_location(board):return Truerow, col = find_empty_location(board)for num in range(1, 10):if is_safe(board, row, col, num):board[row][col] = numif solve_sudoku(board):return Trueboard[row][col] =0return False上面的代码通过递归的方式遍历数独中的每个空格,尝试填入数字,并判断是否满足数独的规则。
回溯法的效率分析

回溯法概述与穷举的“笨拙”搜索相较,回溯法那么是一种“伶俐”的求解效益更高的搜索法。
下面介绍回溯设计及其应用,体会回溯法相关于穷举的特点与优势。
回溯的概念有许多问题,当需要找出它的解集或要求回答什么解是知足某些约束条件的最正确解时,往往利用回溯法。
回溯法是一种试探求解的方式:通过对问题的归纳分析,找出求解问题的一个线索,沿着这一线索往前试探,假设试探成功,即取得解;假设试探失败,就慢慢往回退,换其他线路再往前试探。
因此,回溯法能够形象地归纳为“向前走,碰鼻转头”。
回溯法的大体做法是试探搜索,是一种组织得井井有条的、能幸免一些没必要要搜索的穷举式搜索法。
回溯法在问题的解空间树中,从根结点动身搜索解空间树,搜索至解空间树的任意一点,先判定该结点是不是包括问题的解;若是确信不包括,那么跳过对该结点为根的子树的搜索,逐层向其父结点回溯;不然,进入该子树,继续搜索。
从解的角度明白得,回溯法将问题的候选解按某种顺序进行列举和查验。
当发觉当前候选解不可能是解时,就选择下一个候选解。
在回溯法中,舍弃当前候选解,寻觅下一个候选解的进程称为回溯。
倘假设当前候选解除不知足问题规模要求外,知足所有其他要求时,继续扩大当前候选解的规模,并继续试探。
若是当前候选解知足包括问题规模在内的所有要求时,该候选解确实是问题的一个解。
与穷举法相较,回溯法的“伶俐”的地方在于能适时“转头”,假设再往前走不可能取得解,就回溯,退一步另找线路,如此可省去大量的无效操作。
因此,回溯与穷举相较,回溯更适宜于量比较大,候选解比较多的问题。
5.1.2 回溯描述1.回溯的一样方式下面简要论述回溯的一样方式。
回溯求解的问题P,通常要能表达为:关于已知的由n元组(x1,x2,…,x n)组成的一个状态空间E={(x1,x2,…,x n)|x i∈s i,i=1,2,…,n},给定关于n元组中的一个分量的一个约束集D,要求E中知足D的全数约束条件的所有n元组。
回溯法详解

回溯法详解回溯法(Backtracking)是一种解决问题的算法,也称为试探法。
它是一种基于深度优先策略的搜索方法,用于在一个大型的搜索空间中找到所有可能的解。
回溯法常用于解决组合问题、优化问题、排列问题、路径问题等等。
回溯法的实现方法是:从一个初始状态开始,不断地向前搜索,直到找到一个合法的解或者所有的搜索空间都被遍历结束。
在搜索的过程中,如果发现当前的搜索路径不可能得到合法的解,就会回溯到上一个状态,继续向其他方向搜索。
回溯法仍然是一种穷举算法,但它通过剪枝操作排除大部分不必要的搜索路径,从而减少了搜索的时间和空间复杂度。
回溯法的实现过程中,我们需要完成以下三个步骤:1. 选择基于当前的状态,选择一个可能的方向,继续向前搜索。
这意味着我们需要对问题进行建模,找到一些限制条件或者选择条件,来指导我们如何选择下一个状态。
2. 约束在选择方向之后,我们需要考虑当前方向是否可行。
这称为约束条件。
如果当前的方向违反了某些约束条件,那么我们需要回溯到上一个状态,重新选择一个合法的方向。
3. 回溯如果当前方向无法得到一个合法解,我们就需要回溯到上一个状态,并尝试其他的方向。
回溯操作的核心是恢复状态,也就是将当前状态的改变撤回。
这意味着我们需要记录每一个状态的改变,从而能够正确地回溯。
回溯法的优点在于它的适用范围比较广泛,在解决复杂问题时能够得到很好的效果。
但同时回溯法也存在一些缺点,例如在搜索效率方面并不是最优的,在搜索空间比较大的情况下,时间和空间复杂度也会非常高。
因此,在实践中,我们需要结合具体问题来选择合适的算法。
文献回溯法

文献回溯法
文献回溯法是一种将以前发表的其他文献于当前时间进行比较,
以检查其相关性和有效性的方法。
这种方法可以用来确定研究的质量,以及在研究中使用的方法的可靠性和效率。
例如,如果一项研究认为
环境污染会导致病毒感染,可以采用文献回溯法来证实这一论点的正
确性,或者证明这一结论是否已经历时多年,也可以使用文献回溯法
来检查。
文献回溯法的主要步骤包括确定要检查的文献、分析这些文献中
所提供的数据和结论,包括研究的框架、研究方法、收集的数据等,
然后对文献中提出的结果进行评估。
该步骤的目的是确定某些文献的
可信度,以判断某些文献的客观性,以及根据研究方法的变化而获得
的数据的可靠性和可信度。
最后,文献回溯法还可以有助于发现更多完整的文献,以便深入
研究。
例如,如果研究者发现一篇文献中有重要的遗漏,可以通过回
溯法来进一步搜索相关文献,以挖掘更多的相关信息。
这些文献可能
会遗漏许多相关信息,因此文献回溯法可以有助于解决这种错误,改
善研究的可靠性。
总之,文献回溯法是一种重要的研究方法,可以帮助研究者准确
地分析和比较以前发表的文献,以确保研究的准确性和可靠性。
通过
文献回溯法,研究者可以避免因缺乏足够的实验数据而导致的错误结果,并确保更准确、可靠地进行研究。
回溯法的实验报告

一、实验目的1. 理解回溯法的概念和原理;2. 掌握回溯法的基本算法设计思想;3. 通过实例验证回溯法的正确性和效率;4. 深入了解回溯法在实际问题中的应用。
二、实验内容1. 实验一:八皇后问题2. 实验二:0/1背包问题3. 实验三:数独游戏三、实验原理回溯法是一种在解空间树中搜索问题解的方法。
其基本思想是:从问题的起始状态开始,通过尝试增加约束条件,逐步增加问题的解的候选集,当候选集为空时,表示当前路径无解,则回溯到上一个状态,尝试其他的约束条件。
通过这种方法,可以找到问题的所有解,或者找到最优解。
四、实验步骤与过程1. 实验一:八皇后问题(1)问题描述:在一个8x8的国际象棋棋盘上,放置8个皇后,使得任意两个皇后都不在同一行、同一列和同一斜线上。
(2)算法设计:- 定义一个数组,用于表示棋盘上皇后的位置;- 从第一行开始,尝试将皇后放置在第一行的每一列;- 检查当前放置的皇后是否与之前的皇后冲突;- 如果没有冲突,继续将皇后放置在下一行;- 如果冲突,回溯到上一行,尝试下一列;- 重复上述步骤,直到所有皇后都放置完毕。
(3)代码实现:```pythondef is_valid(board, row, col):for i in range(row):if board[i] == col or abs(board[i] - col) == abs(i - row):return Falsereturn Truedef solve_n_queens(board, row):if row == len(board):return Truefor col in range(len(board)):if is_valid(board, row, col):board[row] = colif solve_n_queens(board, row + 1):return Trueboard[row] = -1return Falsedef print_board(board):for row in board:print(' '.join(['Q' if col == row else '.' for col in range(len(board))]))board = [-1] 8if solve_n_queens(board, 0):print_board(board)2. 实验二:0/1背包问题(1)问题描述:给定一个背包容量为W,n件物品,每件物品的重量为w[i],价值为v[i],求在不超过背包容量的前提下,如何选取物品,使得总价值最大。
回溯研究法

回溯研究法回溯研究法是一种常用的科学研究方法,它通过回顾、分析和总结已有的文献、数据和实验结果,以解决科学问题或验证科学假设。
回溯研究法不仅可以帮助研究者了解某个研究领域的历史发展和现状,还可以为新的研究提供理论和实证的支持。
回溯研究法主要分为两个步骤:文献回顾和数据分析。
在文献回顾阶段,研究者需要收集、筛选和整理与研究主题相关的文献资料。
这些文献资料可以是已发表的学术论文、研究报告、专著、会议论文等。
通过综合分析这些文献资料,研究者可以了解该领域的研究现状、存在的问题和尚未解决的难题。
在数据分析阶段,研究者需要对已有的实验数据进行统计和分析。
这些实验数据可以是自己的实验结果,也可以是其他研究者公开的数据集。
通过对这些数据的分析,研究者可以发现数据之间的关联性、趋势和规律。
同时,他们还可以验证自己的研究假设或推翻已有的理论观点。
回溯研究法具有许多优点。
首先,通过回顾已有的文献和数据,研究者可以快速了解该领域的研究进展,避免重复研究。
其次,回溯研究法可以帮助研究者发现新的问题和研究方向,促进科学的发展。
此外,回溯研究法还可以提供理论和实证的支持,加强研究的可信度和说服力。
然而,回溯研究法也存在一些局限性。
首先,回溯研究法依赖于已有的文献和数据,如果这些文献和数据存在错误或偏见,可能会导致研究结论的不准确性。
其次,回溯研究法只能观察和分析已有的信息,无法改变已有的研究设计和实验方法。
因此,研究者需要谨慎选择合适的文献和数据,并结合自身的研究目标和条件进行分析和解释。
在使用回溯研究法时,研究者需要注意一些关键步骤和技巧。
首先,他们应该明确研究的目的和问题,以便有针对性地收集和分析相关的文献和数据。
其次,他们应该进行全面和系统的文献搜索,包括使用不同的检索词和检索工具,以确保获取尽可能多的文献资料。
此外,研究者还应该对收集到的文献和数据进行质量评估,筛选出高质量和可靠的信息进行分析和总结。
回溯研究法是一种重要的科学研究方法,它通过回顾、分析和总结已有的文献、数据和实验结果,以解决科学问题或验证科学假设。
算法分析与设计实验报告--回溯法

算法分析与设计实验报告--回溯法实验目的:通过本次实验,掌握回溯法的基本原理和应用,能够设计出回溯法算法解决实际问题。
实验内容:1.回溯法概述回溯法全称“试探回溯法”,又称“逐步退化法”。
它是一种通过不断试图寻找问题的解,直到找到解或者穷尽所有可能的解空间技术。
回溯法的基本思路是从问题的某一个初始状态开始,搜索可行解步骤,一旦发现不满足求解条件的解就回溯到上一步,重新进行搜索,直到找到解或者所有可能的解空间已经搜索完毕。
2.回溯法的基本应用回溯法可用于求解许多 NP 问题,如 0/1 背包问题、八皇后问题、旅行商问题等。
它通常分为两种类型:一种是通过枚举所有可能的解空间来寻找解;另一种则是通过剪枝操作将搜索空间减少到若干种情况,大大减少了搜索时间。
3.回溯法的解题思路(1)问题分析:首先需要对问题进行分析,确定可行解空间和搜索策略;(2)状态表示:将问题的每一种状况表示成一个状态;(3)搜索策略:确定解空间的搜索顺序;(4)搜索过程:通过逐步试探,不断扩大搜索范围,更新当前状态;(5)终止条件:在搜索过程中,如果找到了满足要求的解,或者所有的可行解空间都已搜索完毕,就结束搜索。
4.八皇后问题八皇后问题是指在一个 8x8 的棋盘上放置八个皇后,使得任意两个皇后都不在同一行、同一列或同一对角线上。
通过回溯法可以求解出所有的可能解。
实验过程:回溯法的实现关键在于搜索空间的剪枝,避免搜索无用的解;因此,对于八皇后问题,需要建立一个二维数组来存放棋盘状态,以及一个一维数组来存放每行放置的皇后位置。
从第一行开始搜索,按照列的顺序依次判断当前的空位是否可以放置皇后,如果可以,则在相应的位置标记皇后,并递归到下一行;如果不能,则回溯到上一行,重新搜索。
当搜索到第八行时,获取一组解并返回。
代码实现:```pythondef is_valid(board, row, col):for i in range(row):if board[i] == col or abs(board[i] - col) == abs(i - row):return Falsereturn True实验结果:当 n=4 时,求得的所有可行解如下:```[[1, 3, 0, 2],[2, 0, 3, 1]]```本次实验通过实现回溯法求解八皇后问题,掌握了回溯法的基本原理和应用,并对回溯法的核心思想进行了深入理解。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
回溯法的效率分析————————————————————————————————作者:————————————————————————————————日期:2回溯法概述与穷举的“笨拙”搜索相比,回溯法则是一种“聪明”的求解效益更高的搜索法。
下面介绍回溯设计及其应用,体会回溯法相对于穷举的特点与优势。
回溯的概念有许多问题,当需要找出它的解集或者要求回答什么解是满足某些约束条件的最佳解时,往往使用回溯法。
回溯法是一种试探求解的方法:通过对问题的归纳分析,找出求解问题的一个线索,沿着这一线索往前试探,若试探成功,即得到解;若试探失败,就逐步往回退,换其他路线再往前试探。
因此,回溯法可以形象地概括为“向前走,碰壁回头”。
回溯法的基本做法是试探搜索,是一种组织得井井有条的、能避免一些不必要搜索的穷举式搜索法。
回溯法在问题的解空间树中,从根结点出发搜索解空间树,搜索至解空间树的任意一点,先判断该结点是否包含问题的解;如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其父结点回溯;否则,进入该子树,继续搜索。
从解的角度理解,回溯法将问题的候选解按某种顺序进行枚举和检验。
当发现当前候选解不可能是解时,就选择下一个候选解。
在回溯法中,放弃当前候选解,寻找下一个候选解的过程称为回溯。
倘若当前候选解除了不满足问题规模要求外,满足所有其他要求时,继续扩大当前候选解的规模,并继续试探。
如果当前候选解满足包括问题规模在内的所有要求时,该候选解就是问题的一个解。
与穷举法相比,回溯法的“聪明”之处在于能适时“回头”,若再往前走不可能得到解,就回溯,退一步另找线路,这样可省去大量的无效操作。
因此,回溯与穷举相比,回溯更适宜于量比较大,候选解比较多的问题。
5.1.2 回溯描述1.回溯的一般方法下面简要阐述回溯的一般方法。
回溯求解的问题P,通常要能表达为:对于已知的由n元组(x1,x2,…,x n)组成的一个状态空间E={(x1,x2,…,x n)|x i∈s i,i=1,2,…,n},给定关于n元组中的一个分量的一个约束集D,要求E中满足D的全部约束条件的所有n元组。
其中s i是分量x i的定义域,且|s i|有限,i=1,2,…,n。
称E中满足D的全部约束条件的任一n元组为问题P的一个解。
解问题P的最朴素的方法就是穷举法,上面已经作了介绍,即对E中的所有n元组逐一地检验其是否满足D的全部约束,若满足,则为问题P的一个解。
显然,其计算量是相当大的。
对于许多问题,所给定的约束集D具有完备性,即i元组(x1,x2,…,x i)满足D中仅涉及到x1,x2,…,x i的所有约束,意味着j(j<i)元组(x1,x2,…,x j)一定也满足D中仅涉及到x1,x2,…,x j的所有约束,i=1,2,…,n。
换句话说,只要存在0≤j≤n-1,使得(x1,x2,…,x j)违反D中仅涉及到x1,x2,…,x j的约束之一,则以(x1,x2,…,x j)为前缀的任何n元组(x1,x2,…,x j,x j+1,…,x n)也一定违反D中仅涉及到x1,x2,…,x j的一个约束,n≥i>j。
因此,对于约束集D具有完备性的问题P,一旦检测断定某个j元组(x1,x2,…,x j)违反D中仅涉及x1,x2,…,x j的一个约束,就可以肯定,以(x1,x2,…,x j)为前缀的任何n元组(x1,x2,…,x j,x j+1,…,x n)都不会是问题P的解,因而就不必去搜索它们,即省略了对部分元素(x j+1,…,x n)的操作与测试。
回溯法正是针对这类问题,利用这类问题的上述性质而提出来的比穷举法效率更高的算法。
2. 4皇后问题的回溯实施为了具体说明回溯的实施过程,先看一个简单实例。
如何在4×4的方格棋盘上放置4个皇后,使它们互不攻击,即任意两个皇后不允许处在同一横排,同一纵列,也不允许处在同一与棋盘边框成45°角的斜线上。
图5-1所示为应用回溯的实施过程,其中方格中的×表示试图在该方格放置一个皇后,但由于受前面已放置的皇后的攻击而放弃的位置。
图5-1 4皇后问题回溯实施求解图(a)为在第1行第1列放置一个皇后的初始状态。
图(b)中,第2个皇后不能放在第1、2列,因而放置在第3列上。
图(c)中,表示第3行的所有各列均不能放置皇后,则返回第2行,第2个皇后需后移。
图(d)中,第2个皇后后移到第4列,第3个皇后放置在第2列。
图(e)中,第4行的所有各列均不能放置皇后,则返回第3行;第3个皇后后移的所有位置均不能放置皇后,则返回第2行;第2个皇后已无位可退,则返回第1行;第1个皇后需后移。
图(f)中,第1个皇后后移至第2格。
图(g)中,第2个皇后不能放在第1,2,3列,因而放置在第4列上。
图(h)中,第3个皇后放在第1列;第4个皇后不能放置1,2列,于是放置在第3列。
这样经以上回溯,得到4皇后问题的一个解:2413。
继续以上的回溯探索,可得4皇后问题的另一个解:3142。
3.回溯算法框架描述(1) 回溯描述对于一般含参量m,n的搜索问题,回溯法框架描述如下:输入正整数n,m,(n≥m)i=1;a[i]=<元素初值>;while (1){for(g=1,k=i-1;k>=1;k--)if( <约束条件1> ) g=0; // 检测约束条件,不满足则返回if(g && <约束条件2>)printf(a[1-m]); // 输出一个解if(i<n && g) {i++;a[i]=<取值点>;continue;}while(a[i]==<回溯点> && i>1) i--; // 向前回溯if(a[i]==n && i==1) break; // 退出循环,结束else a[i]=a[i]+1;}具体求解问题的试探搜索范围与要求不同,在应用回溯设计时,需根据问题的具体实际确定数组元素的初值、取值点与回溯点,同时需把问题中的约束条件进行必要的分解,以适应上述回溯流程。
其中实施向前回溯的循环while(a[i]==<回溯点> && i>1) i--;是向前回溯一步,还是回溯两步或更多步,完全根据a[i]是否达到回溯点来确定。
例如,回溯点是n,i=6,当a[6]=n时回溯到i=5;若a[5]=n时回溯到i=4;依此类推,到a[i]达到回溯点则停止。
图5-1所示的4皇后问题迭代回溯过程描述为:n=4;i=1;a[i]=1;while (1){g=1;for(k=i-1;k>=1;k--)if(a[i]=a[k] && abs(a[i]-a[k])=i-k)g=0; // 检测约束条件,不满足则返回if(g && i==4)printf(a[1-4]); // 输出一个解if(i<n && g) {i++;a[i]=1;continue;}while(a[i]==n && i>1) i--; // 向前回溯if(a[i]==n && i==1) break; // 退出循环结束else a[i]=a[i]+1;}以上回溯体现在迭代式i=i-1,因而又称为迭代回溯。
此外,递归也能实现回溯。
(2)递归回溯int put(int k){ int i,j,u;if( k<=问题规模 ){ u=0;if( <约束条件> )u=1; // 当k时不可操作if(u==0) // 当k时可操作{ if(k==规模) // 若已满足规模,则打印出一个解printf( <一个解> );else put(k+1); // 调用 put(k+1)}}}在调用put(k)时,当检测约束条件知不可操作(记u=1),即再往前不可能得解,此时当然不可能输出解,也不调用put(k+1),而是回溯,返回调用put(k)之处。
这就是递归回溯的机理。
如果是主程序调用put(1),最后返回到主程序调用put(1)的后续语句,完成递归。
图5.1所示的4皇后问题迭代回溯过程描述为:int put(int k){ int i,j,u;if(k<=4){ for(i=1;i<=4;i++) // 探索第k行从第1格开始放皇后{ a[k]=i;for(u=0,j=1;j<=k-1;j++)if(a[k]==a[j] || abs(a[k]-a[j])==k-j )u=1; // 若第k行第i格放不下,则置u=1if(u==0) // 若第k行第i格可放,则检测是否满4行{ if(k==4) // 若已放满到4行时,则打印出一个解{ s++; printf(" ");for (j=1;j<=4;j++)printf("%d",a[j]);}else put(k+1); // 若没放满4行,则放下一行 put(k+1)}}}}4. 回溯法的效益分析应用回溯设计求解实际问题,由于解空间的结构差异,很难精确计算与估计回溯产生的结点数,因此回溯法的复杂度是分析回溯法效率时遇到的主要困难。
回溯法产生的结点数通常只有解空间结点数的一小部分,这也是回溯法的计算效率大大高于穷举法的原因所在。
回溯求解过程实质上是一个遍历一棵“状态树”的过程,只是这棵树不是遍历前预先建立的。
回溯算法在搜索过程中,只要所激活的状态结点满足终结条件,应该把它输出或保存。
由于在回溯法求解问题时,一般要求输出问题的所有解,因此在得到结点后,同时也要进行回溯,以便得到问题的其他解,直至回溯到状态树的根且根的所有子结点均已被搜索过为止。
组织解空间便于算法在求解集时更易于搜索,典型的组织方法是图或树。
一旦定义了解空间的组织方法,这个空间即可从开始结点进行搜索。
回溯法的时间通常取决于状态空间树上实际生成的那部分问题状态的数目。
对于元组长度为n 的问题,若其状态空间树中结点总数为n!,则回溯算法的最坏情形的时间复杂度可达O(p(n)n!);若其状态空间树中结点总数为2n ,则回溯算法的最坏情形的时间复杂度可达O(p(n)2n),其中p(n)为n 的多项式。
对于不同的实例,回溯法的计算时间有很大的差异。
对于很多具有大n 的求解实例,应用回溯法一般可在很短的时间内求得其解,可见回溯法不失为一种快速有效的算法。
对于某一具体实际问题的回溯求解,常通过计算实际生成结点数的方法即蒙特卡罗方法(Monte carlo )来评估其计算效率。
蒙特卡罗方法的基本思想是在状态空间树上随机选择一条路径(x 0,x 1,…,x n-1),设X 是这一路径上部分向量(x 0,x 1,…,x k-1)的结点,如果在X处不受限制的子向量数是m k ,则认为与X 同一层的其他结点不受限制的子向量数也都是m k 。