第五章作业
一、 回溯法分析最小重量机器设计问题
问题描述
最小重量机器设计问题的基本场景:
一台机器由 n 个部件组成,每个部件都可以从 m 个不同的供应商处采购。设w_{ij}为第 $i$ 个部件从第 j 个供应商采购的重量,c_{ij} 为对应的成本。要求在总成本不超过给定上限 C 的前提下,设计一种采购方案,使得机器的总重量最小。
1.1 解空间
回溯法的解空间是所有可能的可行解的集合,该问题的解空间可以定义为满足约束条件的部件 - 供应商分配方案的集合。
-
解的表示
用一个长度为 n 的一维数组 x[1..n] 表示解,其中 x[i] = j 表示第 i 个部件选择第 j 个供应商 ( 1≤i≤n,1≤j≤m )。 -
约束条件
- 显式约束:每个部件只能选一个供应商,即x[i]∈{1,2,...,m}。
- 隐式约束:所有选中部件的总成本之和不超过上限 $C$,即∑ i=1 n c i,x[i] ≤C。
-
目标函数
最小化机器的总重量,即 min∑ i=1 n w i,x[i] 。 -
解空间的规模
不考虑成本约束时,每个部件有 m 种选择,解空间的总大小为 m^n,属于排列树类型(当 m=n 时退化为全排列树)。
1.2 解空间树
该问题的解空间树是一棵m 叉树,树的层数对应部件的编号,每个结点的分支对应供应商的选择。
-
树的结构定义
- 根结点:位于第 0 层,表示尚未选择任何部件。
- 第 i 层结点( 1≤i≤n ):表示已经确定了前 $i$ 个部件的供应商,正在处理第 i+1 个部件。
- 叶子结点:位于第 $n$ 层,表示所有 $n$ 个部件的供应商都已确定,对应一个完整的采购方案。
-
分支规则
每个非叶子结点有 m 个分支,第 k个分支表示当前部件选择第 k 个供应商。 -
示例(n=2, m=2)
- 根结点(第 0 层):无选择,分支为 1、2(对应部件 1 的供应商)。
- 第 1 层结点:每个结点对应部件 1 的一个供应商,再分支为 1、2(对应部件 2 的供应商)。
- 第 2 层叶子结点:共 2^2=4 个,对应 4 种采购方案:(1,1)、(1,2)、(2,1)、(2,2)。
-
剪枝策略
遍历解空间树时,若当前已选部件的总成本 ∑ k=1 i c k,x[k] 已经超过 C,则该结点的所有子树都不可能是可行解,直接剪枝,无需继续遍历。
1.3 遍历过程中每个结点的状态值
为了高效剪枝和计算目标函数,每个结点需要维护以下状态值,这些状态值是回溯法中“状态回溯”的核心数据:
- 当前部件编号 i
表示已经处理完前 i 个部件,下一步处理第 i+1 个部件,对应解空间树的层数。 - 当前总成本 cost
计算公式: cost=∑ k=1 i c k,x[k] 。
作用:判断是否满足成本约束,若 cost > C 则剪枝。 - 当前总重量 weight
计算公式: weight=∑ k=1 i w k,x[k] 。
作用:记录当前路径的重量,若到达叶子结点且为可行解,则与当前最优解比较,更新最优重量。 - 当前选择的供应商数组 x[1..i]
记录前 i 个部件的供应商选择,用于回溯时恢复状态(例如,尝试完 x[i]=j 后,将 $x[i]$ 重置,再尝试 x[i]=j+1)。 - 当前最优重量 best_w
这是全局状态值,记录遍历过程中找到的最小可行重量。若当前路径的 weight 已经大于等于 best_w,即使后续部件重量为 0,也无法得到更优解,可直接剪枝。
二、 对回溯算法的理解
回溯算法(Backtracking)是一种基于深度优先搜索(DFS)的穷举优化策略,核心思想是“试探 - 验证 - 回溯 - 剪枝”,适用于求解组合优化问题(如最小重量、最大价值)或存在性问题(如是否存在可行解)。
- 核心思想
回溯算法的本质是系统性地遍历解空间树,但不是盲目穷举:
- 试探:从根结点出发,沿着一条路径逐层深入,构建部分解。
- 验证:每走一步都检查当前部分解是否满足约束条件。
- 回溯:若当前路径无法得到可行解或最优解,则回退到上一层,尝试其他分支。
- 剪枝:提前排除不可能产生可行解或最优解的子树,大幅减少遍历次数。
-
基本特征
-
解空间的结构化
解空间必须能表示为一棵树(排列树、子集树、m 叉树等),树的结点对应部分解,叶子结点对应完整解。 -
状态的可回溯性
遍历过程中需要维护当前状态(如已选元素、当前目标函数值),尝试完一个分支后,必须恢复状态,才能尝试下一个分支。 -
剪枝的关键性
剪枝是回溯算法高效的核心,剪枝函数通常分为两类:- 约束函数:排除违反显式/隐式约束的路径(如最小重量机器设计中的成本上限)。
- 限界函数:排除无法得到最优解的路径(如当前重量已超过已知最优重量)。
-
适用场景
适用于解空间规模较大,但通过剪枝能大幅缩小搜索范围的问题,典型应用包括:- 排列组合问题:全排列、子集和、0-1 背包。
- 分配问题:工作分配、最小重量机器设计。
- 路径问题:八皇后、数独、旅行商问题(TSP)。
-
回溯法的一般步骤
-
定义解的表示:用数组或集合表示解的结构,明确每个元素的取值范围。
-
确定解空间树的类型:判断是子集树、排列树还是 $m$ 叉树。
-
设计状态变量:包括当前部分解、当前目标函数值、约束条件的中间值等。
-
实现递归回溯函数:
- 递归边界:到达叶子结点时,判断是否为可行解,更新最优解。
- 遍历分支:对当前结点的所有可能分支,依次尝试。
- 剪枝判断:若当前分支违反约束或无法得到更优解,跳过该分支。
- 状态回溯:尝试完一个分支后,恢复状态,继续下一个分支。
-
初始化:设置初始状态(如最优解为无穷大),调用回溯函数。
浙公网安备 33010602011771号