算法设计与分析 第五章作业

软工2201林泳敏 2022级 2023-12-03 13:08:44

1. 请用回溯法的方法分析“最小重量机器设计问题”

这道题属于求路径问题,是n后问题的一个变形,可以套用递归回溯法求n后问题的框架来解决。

1.1 说明“最小重量机器设计问题"的解空间

用解向量(x1, x2,....,xn)表示该问题的一个可能解,其中:

  • xi表示第i个零部件选择的供应商,共n个零部件,故这是一个n维向量
  • xi的取值范围为1-m,即每个零部件都有m个可选择的供应商
  • 由这些解向量构成该问题的解空间

1.2 说明 “最小重量机器设计问题"的解空间树

这是一颗有n+1层的m叉树,每一个结点都有m个后继

1.3 在遍历解空间树的过程中,每个结点的状态值是什么

每个结点都对应有三个状态:

  1. x[t],记录该结点对应哪个供应商;
  2. tepw,记录走到该结点后的总重量,每次执行tepw += w[t][i];回溯时执行tepw -= w[t][i];
  3. tepc,记录走到该结点后的总价格,每次执行tepc += c[t][i];回溯时执行tepc += c[t][i];

1.4 如何利用限界函数进行剪枝

  • 约束函数:题目要求总价格不超过d,则最终tepc<=d,若在遍历某一分支的过程中发现tepc > d就剪枝;
  • 限界函数:题目要求最小重量,则设置bestw记录当前最优值,若在遍历某一分支的过程中发现tepw >= bestw就剪枝;
  • 则最终可以得到以下的剪枝函数:
    bool place (int t) {
         if (tepc > d || tepw >= w)
             return false;
         return true;
    }

2. 你对回溯算法的理解

回溯法是一种组织得井井有条得穷举式搜索法,适用于求解一些组合数相当大的问题。我的理解是先尝试走该分支,不可行就回头试另一个分支。

  • 回溯法的基本步骤
  1. 针对所给的问题,定义问题的解空间;
  2. 确定易于搜索的解空间结构,通常组织成树或图的形式;
  3. 采用深搜遍历,并用剪枝函数剪去避免无效搜索。目前遇到的剪枝函数大概有如下几类:

与最优值比较。每一步都将当前状态与最优值比较,根据题目要求进行判断:若已经大于或小于最优值了则进行剪枝;

宽松限界。不考虑约束条件,将剩余的所有都加起来,若得到的值仍然比最优值大或小,则进行剪枝;

严格限界。采用贪心算法,精确计算上界。引用上界函数后,在到达一个叶结点时不必再检查该叶结点是否优于当前最优解,因为上界函数使算法搜索到的每个叶结点都是迄今为止找到的最优解。

  • 3类典型的解空间树

子集树(2叉树)

(1) 适用于求子集问题,即从n个元素的集合S种找出满足某个性质的子集

(2) 解向量为n维向量(x1, x2,...,xn),xi可以取0或1,表示选或不选

(3) 通常有2^n个叶结点,时间复杂度O(2^n) 

(4) e.g. 0-1背包问题

(5) 算法框架如下

void backtrack (int t) {
     if (t > n) {
     output(x);
     return;
     }
     //选,进入左子树
     if (...) {
        x[t] = 1;
        backtrack(t+1);
     }
     //不选,进入右子树
     if (...) {
        x[t] = 0;
        backtrack(t+1);}
}

排列树 

(1) 适用于求排列问题,即确定n个元素的满足某种性质的排列

(2) 解向量为n维向量(x1,x2,...,xn),x1~xn全排列对应的解向量组成解空间

(3) 通常有n!个叶结点,时间复杂度O(n!)

(4)  e.g. 旅行售货员问题

(5) 算法框架如下:

void backtrack(int t) {
     if (t > n) {
         output(x);
         return;
     }
     //x[1]~x[t-1]已经确定,要获得x[t]~x[n]的不同组合
     for (int i = t; i <= n; i++) {
         if (...) {
            swap (x[t],x[i]);
            backtrack(t+1);
            swap(x[t], x[i]);
         }
     }
}

k叉树  

(1) 适用于求路径问题,即找到一条路径就可以得到解

(2) 解向量n维向量(x1,x2,...,xn),xi取1~m任意一个

(3) 每个结点都有k个后继,通常有k^(n+1)-1个结点,时间复杂度O(k^n),n为解的路径长度

(4) e.g. n后问题

(5) 算法框架如下:

void backtrack(int t) {
     if (t > n) {}
     else {
         //第t个选哪个?都试一遍
         for (int i = 1; i <= m; i++) {
             x[t] = i;
             if (place(t))
                 backtrack(t+1);
         }
     }
}
...全文
57 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

434

社区成员

发帖
与我相关
我的任务
社区描述
广东外语外贸大学信息科学与技术学院
算法 高校
社区管理员
  • brisksea
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧