设计 任务书 文档 开题 答辩 说明书 格式 模板 外文 翻译 范文 资料 作品 文献 课程 实习 指导 调研 下载 网络教育 计算机 网站 网页 小程序 商城 购物 订餐 电影 安卓 Android Html Html5 SSM SSH Python 爬虫 大数据 管理系统 图书 校园网 考试 选题 网络安全 推荐系统 机械 模具 夹具 自动化 数控 车床 汽车 故障 诊断 电机 建模 机械手 去壳机 千斤顶 变速器 减速器 图纸 电气 变电站 电子 Stm32 单片机 物联网 监控 密码锁 Plc 组态 控制 智能 Matlab 土木 建筑 结构 框架 教学楼 住宅楼 造价 施工 办公楼 给水 排水 桥梁 刚构桥 水利 重力坝 水库 采矿 环境 化工 固废 工厂 视觉传达 室内设计 产品设计 电子商务 物流 盈利 案例 分析 评估 报告 营销 报销 会计
 首 页 机械毕业设计 电子电气毕业设计 计算机毕业设计 土木工程毕业设计 视觉传达毕业设计 理工论文 文科论文 毕设资料 帮助中心 设计流程 
垫片
您现在所在的位置:首页 >>理工论文 >> 文章内容
                 
垫片
   我们提供全套毕业设计和毕业论文服务,联系微信号:biyezuopin QQ:2922748026   
《算法设计与分析-分支限界法》上机实验报告
文章来源:www.biyezuopin.vip   发布者:毕业作品网站  
in = cost[i][j];

244、         }

245、         low += min;

246、     }

247、 }

248、

249、 //估值

250、 int get_lb(Node p)

251、 {

252、     int ret = p.sumv * 2;//路径上的点的距离的二倍

253、     int min1 = INF, min2 = INF;//起点和终点连出来的边

254、     for (int i = 1; i <= n; i++){

255、         if (!p.visited[i] && min1 > cost[i][p.s]){

256、             min1 = cost[i][p.s];

257、         }

258、     }

259、     ret += min1;

260、     for (int i = 1; i <= n; i++){

261、         if (!p.visited[i] && min2 > cost[p.e][i]){

262、             min2 = cost[p.e][i];

263、         }

264、     }

265、     ret += min2;

266、     for (int i = 1; i <= n; i++){

267、         if (!p.visited[i]){

268、             min1 = min2 = INF;

269、             for (int j = 1; j <= n; j++){

270、                 if (min1 > cost[i][j])

271、                     min1 = cost[i][j];

272、             }

273、             for (int j = 1; j <= n; j++){

274、                 if (min2 > cost[j][i])

275、                     min2 = cost[j][i];

276、             }

277、             ret += min1 + min2;

278、         }

279、     }

280、     return (ret + 1) / 2;

281、 }

282、

283、 int solve()

284、 {

285、     //贪心法确定上界

286、     get_up();

287、     //取每行最小的边之和作为下界

288、     get_low();

289、     //设置初始点,默认从1开始

290、     Node star;

291、     star.s = 1;//起点为1

292、     star.e = 1;//终点为1

293、     star.k = 1;//走过了1个点

294、     for (int i = 1; i <= n; i++)

295、     {

296、         star.visited[i] = false;

297、     }

298、     star.visited[1] = true;

299、     star.sumv = 0;//经过的路径距离初始化

300、     star.lb = low;//让目标值先等于下界

301、     int ret = INF;//ret为问题的解

302、     pq.push(star);//将起点加入队列

303、     while (pq.size()){

304、         Node tmp = pq.top(); pq.pop();

305、         //如果已经走过了n-1个点

306、         if (tmp.k == n - 1){

307、             //找最后一个没有走的点

308、             int p;

309、             for (int i = 1; i <= n; i++){

310、                 if (!tmp.visited[i]){

311、                     p = i;//让没有走的那个点为最后点能走的点

312、                     break;

313、                 }

314、             }

315、             int ans = tmp.sumv + cost[p][tmp.s] + cost[tmp.e][p];//已消耗+回到开始消耗+走到P的消耗

316、             //如果当前的路径和比所有的目标函数值都小则跳出

317、             if (ans <= tmp.lb){

318、                 ret = min(ans, ret);

319、                 break;

320、             }

321、             //否则继续求其他可能的路径和,并更新上界

322、             else{

323、                 up = min(up, ans);//上界更新为更接近目标的ans值

324、                 ret = min(ret, ans);

325、                 continue;

326、             }

327、         }

328、         //当前点可以向下扩展的点入优先级队列

329、         Node next;

330、         for (int i = 1; i <= n; i++){

331、             if (!tmp.visited[i]){

332、                 next.s = tmp.s;//沿着tmp走到next,起点不变

333、                 next.sumv = tmp.sumv + cost[tmp.e][i];//更新路径和

334、                 next.e = i;//更新最后一个点

335、                 next.k = tmp.k + 1;//更新走过的顶点数

336、                 for (int j = 1; j <= n; j++) next.visited[j] = tmp.visited[j];//tmp经过的点也是next经过的点

337、                 next.visited[i] = true;//自然也要更新当前点

338、                 next.lb = get_lb(next);//求目标函数

339、                 if (next.lb > up) continue;//如果大于上界就不加入队列

340、                 pq.push(next);//否则加入队列

341、             }

342、         }

343、     }

344、     return ret;

345、 }

346、

347、 int main()

348、 {

349、     cin >> n;

350、     for (int i = 1; i <= n; i++){

351、         for (int j = 1; j <= n; j++){

352、             //对角线不可达

353、             if (i == j){

354、                 cost[i][j] = INF;

355、                 continue;

356、             }

357、             cin >> cost[i][j];

358、         }

359、     }

360、     cout << solve() << endl;

361、     return 0;

362、 }

四、运行输出结果:

1、 01背包问题 + 采药--1003

2、 TSP问题—1813+1814

五、调试和运行程序过程中产生的问题、采取的措施及获得的相关经验教训:

1、一开始我背包问题搞错了,把上界搞成贪心法求得的解了,导致一直有问题。后来经过胡杭天的提醒,我才意识到,背包问题要求的是最大价值,与之前作业里的不同,作业里要求的是最短运行时间,所以在这个问题里贪心法求得的解应该当作这个问题的下界。

,

《算法设计与分析-分支限界法》上机实验报告

目录

《算法设计与分析-分支限界法》上机实验报告

一、实验内容:

二、所用算法的基本思想及复杂度分析:

三、源程序及注释:

四、运行输出结果:

五、调试和运行程序过程中产生的问题、采取的措施及获得的相关经验教训:

一、实验内容:

分支限界法问题。

二、所用算法的基本思想及复杂度分析:

1、 01背包问题+采药1003

1) 基本思想

对于一个给定容量的背包,01背包问题就是要求这个背包能容纳的最大价值。首先我们先算出其上下界。对于其下界,我们可以用贪心法来求出其最大价值,而上界就是所有物品价值的累加和。由上界和下界组成最优值区间。之后我们就可以进行搜索剪枝了,对于物品1,我们选择放入和不放入分别估算其价值,如果不在最优值区间里的我们对他进行剪枝,而在最优值区间内的结果我们选取估值最小的那个进行进一步展开,如此反复,每次都选估值最小的进行展开(展开的时候放和不放两种情况都要)。

2、 TSP问题—1813+1814

1) 基本思想

原理基本与01背包问题相同,也是选上界和下界,然后不断地搜索估值,最后得到最优解。其中,这里用贪心法求得上界(因为要求的是最短路径,所以与01背包有些许不同),下界就比较简单了,直接取每行的最小值进行相加即可。然后呢,就是对每个点进行估值,如果超过最优值区间则剪枝否则取最小的那个继续展开进行估值,一致循环直到找到最优解。

三、源程序及注释:

1、 01背包问题 + 采药--1003

2、 /*

3、 测试数据:

4、 6 5

5、 3 25

6、 2 20

7、 1 15

8、 4 40

9、 5 50

10、 */

11、

12、 #include <iostream>

13、 #include <queue>

14、 #include <algorithm>

15、 using namespace std;

16、

17、 struct Node{

18、     Node(){

19、         value = 0;

20、         weight = 0;

21、         level = 0;

22、         parent = 0;

23、         bound = 0;

24、     }

25、     int value;           //搜索到该节点时的价值

26、     int weight;          //搜索到该节点时的总重量

27、     float bound;         //搜索以该节点为根的子树能达到的价值上界

28、     int level;           //该节点所处层次,从0开始

29、     struct Node *parent; //指向父节点

30、 };

31、

32、 struct cmp{

33、     bool operator()(Node *a, Node *b){

34、         return a->bound < b->bound;

35、     }

36、 };

37、

38、 //物品

39、 struct Goods{

40、     int id;

41、     int w=0;

42、     int v=0;

43、     double v_perw=0;

44、 };

45、

46、 bool GoodCmp(Goods good1, Goods good2){

47、     return good1.v_perw > good2.v_perw;

48、 }

49、

50、

51、 Goods good[101];

52、 int c, n;

53、

54、 //限界函数

55、 float maxBound(Node *node, Goods good[], int c){

56、     //求以该节点为根的子树能达到的价值上界

57、     float maxValue;

58、     int restCapacity; //扩展到该节点时的剩余容量

59、     int i;

60、

61、     maxValue = node->value;

62、     restCapacity = c - node->weight;

63、     i = node->level;

64、     while (i < n && restCapacity > good[i].w){

65、         maxValue += good[i].v;

66、         restCapacity -= good[i].w;

67、         i++;

68、     }

69、     if (restCapacity != 0){

70、         maxValue += restCapacity * good[i].v_perw;

71、     }

72、     return maxValue;

73、 }

74、

75、 //bfs

76、 int searchCount = 0;

77、 int branchAndBound(Goods good[], int c){

78、     int x[n+1] = {0};

79、     int maxValue;                                    //保存当前搜索到的最大价值

80、     int maxSize = 0;

81、     Node *maxNode = new Node();                           //保存当前最大价值节点(叶节点)

82、     priority_queue<Node *, vector<Node *>, cmp> maxQueue; //最大价值优先队列

83、     Node *firstNode, *curNode;

84、

85、     searchCount = 1;

86、     firstNode = new Node();

87、     firstNode->bound = maxBound(firstNode, good, c);

88、     firstNode->parent = NULL;

89、     maxQueue.push(firstNode); //入队第一个结点

90、     maxValue = 0;

91、     maxNode = firstNode;

92、     while (!maxQueue.empty())

93、     {

94、         curNode = maxQueue.top();

95、         maxQueue.pop();

96、         //扩展左孩子结点

97、         if (curNode->weight + good[curNode->level].w <= c){

98、             //最大重量限界

99、             Node *leftNode = new Node();

100、             leftNode->value = curNode->value + good[curNode->level].v;

101、             leftNode->weight = curNode->weight + good[curNode->level].w;

102、             leftNode->level = curNode->level + 1;

103、             leftNode->parent = curNode;

104、             leftNode->bound = curNode->bound;

105、             if (leftNode->level < n){

106、                 maxQueue.push(leftNode);

107、                 searchCount++;

108、             }

109、             if (maxValue < leftNode->value){

110、                 maxValue = leftNode->value;

111、                 maxNode = leftNode;

112、             }

113、         }

114、         //扩展右孩子结点

115、         if (maxBound(curNode, good, c) > maxValue){

116、             //最大价值上界限界

117、             Node *rightNode = new Node();

118、             rightNode->value = curNode->value;

119、             rightNode->weight = curNode->weight;

120、             rightNode->level = curNode->level + 1;

121、             rightNode->parent = curNode;

122、             rightNode->bound = maxBound(rightNode, good, c);

123、             if (rightNode->level < n){

124、                 maxQueue.push(rightNode);

125、                 searchCount++;

126、             }

127、         }

128、         //跟踪队列大小

129、         if (maxQueue.size() > maxSize)

130、             maxSize = maxQueue.size();

131、     }

132、     curNode = maxNode;

133、     while (curNode){

134、         int tempValue = curNode->value;

135、         curNode = curNode->parent;

136、         if (curNode && curNode->value != tempValue)

137、             x[good[curNode->level].id] = 1;

138、     }

139、     return maxValue;

140、 }

141、

142、 int main()

143、 {

144、     cin >> c >> n;

145、     for (int i = 0; i < n; ++i){

146、         cin >> good[i].w >> good[i].v;

147、         good[i].id = i;

148、         good[i].v_perw = (float)good[i].v / good[i].w;

149、     }

150、     sort(good, good + n, GoodCmp); //按单位价值排序

151、     cout << branchAndBound(good, c) << endl;

152、     return 0;

153、 }

154、 TSP问题—1813+1814

155、 /*

156、 测试数据:

157、 5

158、 3 1 5 8

159、 3 6 7 9

160、 1 6 4 2

161、 5 7 4 3

162、 8 9 2 3

163、

164、 4

165、 3 6 7

166、 5 2 3

167、 6 4 2

168、 3 7 5

169、

170、 10

171、         42  160   34  136  134   94   78   18  196

172、    42       166   66  106   87   11  122  195   32

173、   160  166         4   98  198    3  154   75  121

174、    34   66    4       187  112   52   94   36  144

175、   136  106   98  187        12   64   45   46   48

176、   134   87  198  112   12       154  109  196  131

177、    94   11    3   52   64  154        11   79   80

178、    78  122  154   94   45  109   11        13   86

179、    18  195   75   36   46  196   79   13       162

180、   196   32  121  144   48  131   80   86  162

181、 */

182、

183、 #include<iostream>

184、 #include<algorithm>

185、 #include<cstdio>

186、 #include<queue>

187、 const int INF = 100000;

188、 const int MAX_N = 22;

189、 using namespace std;

190、 //n*n的一个矩阵

191、 int n;

192、 int cost[MAX_N][MAX_N];//最少3个点,最多MAX_N个点

193、 struct Node

194、 {

195、     bool visited[MAX_N];//标记哪些点走了

196、     int s;//第一个点

197、     int s_p;//第一个点的邻接点

198、     int e;//最后一个点

199、     int e_p;//最后一个点的邻接点

200、     int k;//走过的点数

201、     int sumv;//经过路径的距离

202、     int lb;//目标函数的值(目标结果)

203、     bool operator <(const Node& p)const{

204、         return p.lb < lb;//目标函数值小的先出队列

205、     }

206、 };

207、

208、 priority_queue<Node> pq;//创建一个优先队列

209、 int low, up;//下界和上界

210、 bool dfs_visited[MAX_N];//在dfs过程中搜索过

211、

212、 //确定上界,利用dfs(属于贪心算法),贪心法的结果是一个大于实际值的估测结果

213、 //当前节点,目标节点,已经消耗的路径

214、 int dfs(int u, int k, int l){

215、     if (k == n) return l + cost[u][1];//如果已经检查了n个节点,则直接返回路径消耗+第n个节点回归起点的消耗

216、     int minlen = INF, p;

217、     for (int i = 1; i <= n; i++){

218、         //取与所有点的连边中最小的边

219、         if (!dfs_visited[i] && minlen > cost[u][i]){

220、             minlen = cost[u][i];//找出对于每一个节点,其可达节点中最近的节点

221、             p = i;

222、         }

223、     }

224、     dfs_visited[p] = true;//以p为下一个节点继续搜索

225、     return dfs(p, k + 1, l + minlen);

226、 }

227、

228、 //取上界

229、 void get_up(){

230、     dfs_visited[1] = true;//以第一个点作为起点

231、     up = dfs(1, 1, 0);

232、 }

233、

234、 //取下界

235、 void get_low()

236、 {

237、     //取每行最小值之和作为下界

238、     low = 0;

239、     for (int i = 1; i <= n; i++){

240、         int min = INF;

241、         for(int j=1; j<=n; ++j){

242、             if(cost[i][j]<min)

243、                 m   全套毕业设计论文现成成品资料请咨询微信号:biyezuopin QQ:2922748026     返回首页 如转载请注明来源于www.biyezuopin.vip  

                 

打印本页 | 关闭窗口
本类最新文章
基于人工智能的智能语音识别系统设 大数据舆情分析系统的设计与实现 “上帝的归上帝,凯撒的归凯撒”:
平板单元(Mindlin板)的热 AIGC的著作权归属问题:基于成 带有随机场变量结构的动力特性分析
| 关于我们 | 友情链接 | 毕业设计招聘 |

Email:biyeshejiba@163.com 微信号:biyezuopin QQ:2922748026  
本站毕业设计毕业论文资料均属原创者所有,仅供学习交流之用,请勿转载并做其他非法用途.如有侵犯您的版权有损您的利益,请联系我们会立即改正或删除有关内容!