本实验要求基于算法设计与分析的一般过程(即待求解问题的描述、算法设计、算法描 述、算法正确性证明、算法分析、算法实现与测试),通过分支限界法(包括队列式和优先 队列式)的在实际问题求解实践中,加深理解其基本原理和思想以及求解步骤。求解的问题 为布线问题。
理解问题: 布线问题是指在电路板设计中,将电路板上所有的器件(如芯片、电阻等)按 照一定的规则通过连线互相连接,从而实现电路的功能。在实际设计中,通常需要在有限的 空间内布置尽可能多的器件,并且需要满足一定的电气性能要求,如信号传输速度、功耗 等。布线问题是一类 NP 完全问题,因此通常需要采用启发式算法进行求解。
算法策略与数据结构的选择: 分支限界法是一种常用的求解优化问题的方法。该方法通过将搜索空间分割成 一些小的子集(即分支),并对每个子集进行求解。同时,对于某些无法产生最优解的子 集,该方法会采用一些方法进行剪枝,从而减少搜索空间,提高求解效率。采用数组存储数 据。
算法描述:
1. 用一个数组 dist 来存储所有点之间的距离
2. 初始化最小路径长度 minDist 为无穷大
3. 定义一个队列 queue 用于存储扩展的结点
4. 将起点入队,并设置该结点的 lowerBound 为 0
5. 当队列不为空时,循环执行以下操作:
1) 取出队首结点 p,如果 p 的 lowerBound 已经大于 minDist,则跳过该结点
2) 如果 p 为终点,则更新 minDist 为 p 的路径长度
3) 否则,对于 p 的所有未扩展过的子节点 c,计算 c 的 lowerBound 值,并将 c 插入队列中
6. 输出 minDist
#include<iostream> #include<iomanip> #include<queue> using namespace std; const int length = 6; int m = length, n = length, grid[length+2][length + 2]; struct Position{ int row, col; }; void Print(){ for (int i = 1; i < length+1; i++){ for (int j = 1; j < length + 1; j++) cout << setw(3) << grid[i][j]; cout << endl; } cout << endl; } bool FindPath(Position start, Position finish, int& PathLen, Position*& path){ Position nextStep[4]; nextStep[0].row = 0;nextStep[0].col = 1;//右 nextStep[1].row = 1;nextStep[1].col = 0;//下 nextStep[2].row = 0; nextStep[2].col = -1;//左 nextStep[3].row = -1;nextStep[3].col = 0;//上 Position here, next; here.row = start.row; here.col = start.col; grid[start.row][start.col] = 1; queue<Position> Q; while (true){ //标记相邻可达方格 for (int i = 0; i < 4; i++){ //相邻四格 next.row = here.row + nextStep[i].row; next.col = here.col + nextStep[i].col; if (grid[next.row][next.col] == 0 && next.row != -1 && next.col != -1){ grid[next.row][next.col] = grid[here.row][here.col] + 1; if ((next.row == finish.row) && (next.col == finish.col)) break; Q.push(next); } } //截至条件 if ((next.row == finish.row) && (next.col == finish.col)) break; if (Q.empty()) return false; here = Q.front(); Q.pop(); } PathLen = grid[finish.row][finish.col]; path = new Position[PathLen]; //回溯 here = finish; for (int j = PathLen - 1; j >= 0; j--){ path[j] = here; //遍历四方向 for (int i = 0; i < 4; i++){ next.row = here.row + nextStep[i].row; next.col = here.col + nextStep[i].col; if (grid[next.row][next.col] == j){ break; } } here = next; } return PathLen; } int main(){ int countNum = 0; //阻碍 grid[2][3] = grid[3][4] = grid[3][5] = grid[4][2] = -1; Position start;//开始 cout<<"请输入起始坐标:"; cin>>start.row>>start.col; Position finish;//结束 cout<<"请输入结束坐标:"; cin>>finish.row>>finish.col; Position* path; FindPath(start, finish, countNum, path); cout << "最终结果是:" << endl; Print(); //最终结果 cout << "路径长度是:" << countNum - 1<< endl; for (int i = 1; i < countNum; i++){ cout <<"("<< path[i].row << "," << path[i].col <<")"<<"-"; } cout << endl; system("pause"); return 0; }