文章目录
问题描述
某一机器由 n
个部件组成,每种部件可以从 m
个不同的供应商处购得。设
w
i
j
w_{ij}
wij 是从供应商 j
处购得的部件 i
的重量,
c
i
j
c_{ij}
cij是相应的价格。试设计一个算法,给出总价格不超过 d
的最小重量机器设计。
输入格式
- 第 1 行包含 3 个正整数
n
、m
和d
,表示部件数、供应商数以及总价格限制。 - 接下来
2n
行,每行包含m
个数。前n
行是c
(价格),后n
行是w
(重量)。
输出格式
输出计算出的最小重量,以及每个部件的供应商。
输入样例
3 3 4
1 2 3
3 2 1
2 2 2
1 2 3
3 2 1
2 2 2
输出样例
4
1 3 1
1 回溯法分析“最小重量机器设计问题”
1.1 说明“最小重量机器设计问题"的解空间
解空间是所有可能的部件供应商组合。在此问题中,我们需要为每个部件选择一个供应商,且每个供应商都有不同的价格和重量。给定 n
个部件和 m
个供应商,问题的解空间由以下元素组成:
- 每个部件有
m
个选择。 - 因此,总的选择数为
m^n
。
解空间中的每个解是一个由 n
个部件选择组成的数组,其中每个元素表示一个部件的供应商编号。解空间可以通过一个 n
维数组来表示,其中每个维度的取值为从1到 m
(对应每个部件的供应商)。
1.2 说明 “最小重量机器设计问题"的解空间树
解空间树的每个结点表示一个状态,包含部分选择的信息。树的根表示还没有做任何选择,树的叶子结点表示所有部件的选择已经做完。每个结点的子结点表示选择某个部件的不同供应商。
对于 n
个部件的情况下,解空间树的层数为 n
。在每一层上,从根到叶子,每个结点都表示当前部件的供应商选择。对于每个部件,从1到 m
都有可能的供应商选择。树的最大深度为 n
,每个结点的分支因子为 m
。
例如,假设有3个部件(n=3
)和3个供应商(m=3
),解空间树的层次结构如下:
Root
/ | \
(1) (2) (3)
/ | \ / | \ / | \
(1) (2) (3)(1) (2) (3)(1) (2) (3)
/|\\ /|\\ /|\\
(1)(2)(3)(1)(2)(3)(1)(2)(3) . . .
每个叶子结点代表了一个部件供应商的选择组合。
1.3 在遍历解空间树的过程中,每个结点的状态值是什么
在遍历解空间树时,每个结点的状态值包括当前已选择的部件供应商,并且记录当前已经选择的部件对应的总成本和总重量。
选择的供应商
:记录已经为哪些部件做出了供应商选择。当前成本
:已选择部件的总价格。当前重量
:已选择部件的总重量。
每个结点的状态值就是当前部件的选择信息以及相应的总成本和总重量。通过这些信息,可以决定是否继续向下遍历树的子结点(即选择下一个部件的供应商)。
1.4 如何利用限界函数进行剪枝
限界函数的作用是判断当前路径是否值得继续扩展。如果当前已选择的供应商组合所对应的价格超过了总预算 d
,则可以立即剪枝,不再向下遍历该路径。
具体来说,限界函数检查:
- 如果当前部件选择的供应商所导致的总价格已经超过预算
d
,则剪枝。 - 如果当前部件选择的供应商所导致的重量已经大于已知最小重量,则剪枝。
- 否则,继续尝试下一个部件的供应商选择。
这种剪枝可以大大减少不必要的搜索,避免进入不符合约束条件的解空间区域。
2 回溯算法的理解
回溯算法是一种通过试探法寻找问题的所有解的算法,适用于组合问题、排列问题等。它通过递归搜索所有可能的解,并根据某些条件判断当前选择是否合理,若不合理则回退到上一层继续选择其他可能性。回溯法的核心思想是:
- 从一个候选解开始,递归地选择下一个可能的解。
- 如果当前选择已经不满足问题的约束条件,则回退并尝试其他选择。
- 通过递归和回退的方式探索解空间,直到找到满足所有条件的解或遍历完所有解。
回溯法的基本步骤:
- 选择:在当前状态下选择一个候选项。
- 检查:判断当前选择是否符合约束条件。
- 递归:如果当前选择符合条件,则继续递归,进行下一步选择。
- 回溯:如果当前选择不符合条件或已经到达解的边界,则回退到上一层选择,继续尝试其他可能性。
回溯算法的效率和成功与否,往往取决于问题的解空间大小以及剪枝的有效性。通过合理的剪枝策略,可以显著减少搜索空间,提高算法的效率。