分支限界法的应用-布线等问题

        本实验要求基于算法设计与分析的一般过程(即待求解问题的描述、算法设计、算法描 述、算法正确性证明、算法分析、算法实现与测试),通过分支限界法(包括队列式和优先 队列式)的在实际问题求解实践中,加深理解其基本原理和思想以及求解步骤。求解的问题 为布线问题。

理解问题: 布线问题是指在电路板设计中,将电路板上所有的器件(如芯片、电阻等)按 照一定的规则通过连线互相连接,从而实现电路的功能。在实际设计中,通常需要在有限的 空间内布置尽可能多的器件,并且需要满足一定的电气性能要求,如信号传输速度、功耗 等。布线问题是一类 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;
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南城`烟雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值