算法设计--电路布线问题(分支限界法求解)

cout<<“start=finish”<<endl;

return true;

} //start=finish

//设置方格阵列“围墙”

//初始化图,-1为未访问

for(int i=1; i<9; i++)

{

for(int j=1; j<9; j++)

grid[i][j]=-1;

}

//添加阻挡点

grid[2][3]=-2;

for(int i=0; i<= m+1; i++)

grid[0][i]=grid[n+1][i]=-2; //顶部和底部

for(int i=0; i<= n+1; i++)

grid[i][0]=grid[i][m+1]=-2; //左翼和右翼

//初始化相对位移

cout<<“完整图”<<endl;

showPath();

Position offset[4];

offset[0].row=0;

offset[0].col=1;//右

offset[1].row=1;

offset[1].col=0;//下

offset[2].row=0;

offset[2].col=-1;//左

offset[3].row=-1;

offset[3].col=0;//上

int NumOfNbrs=4;//相邻方格数

Position here,nbr;

here.row=start.row;

here.col=start.col;

grid[start.row][start.col]=0;

//标记可达方格位置

cout<<“布线前图”<<endl;

showPath();

queue Q;

do //标记相邻可达方格

{

for(int I=0; I<NumOfNbrs; I++)

{

nbr.row=here.row + offset[I].row;

nbr.col=here.col+offset[I].col;

if(grid[nbr.row][nbr.col]==-1)

{

//该方格未被标记

//cout<<grid[nbr.row][nbr.col]<<endl;//显示路标值

grid[nbr.row][nbr.col]=grid[here.row][here.col]+1;

//cout<<nbr.col<<" "<<nbr.row<<endl;//显示坐标

}

if((nbr.rowfinish.row) &&(nbr.colfinish.col)) break; //完成布线

Q.push(nbr);

}

//是否到达目标位置finish?

if((nbr.rowfinish.row)&&(nbr.colfinish.col)) break;//完成布线

//活结点队列是否非空?

if(Q.empty()) return false;//无解

here = Q.front();

//cout<<here.col<<" "<<here.row<<endl;

Q.pop();//取下一个扩展结点

indexcount++;

// cout<<“下一节点”<<indexcount<<endl;

}

while(true);

//构造最短布线路径

PathLen=grid[finish.row][finish.col];

path=new Position[PathLen];

//从目标位置finish开始向起始位置回溯

here=finish;

for(int j=PathLen-1; j>=0; j–)

{

path[j]=here;

//找前驱位置

for(int i=0; i<NumOfNbrs; i++)

{

nbr.row=here.row+offset[i].row;

nbr.col=here.col+offset[i].col;

if(grid[nbr.row][nbr.col]==j)

{

// cout<<j<<endl;

break;

}

}

here=nbr;//向前移动

}

return PathLen;

}

int main()

{

Position start;

start.col=1;

start.row=1;

cout<<“布线起点”<<endl;

cout<<start.col<<" "<<start.row<<endl;

Position finish;

finish.row=3;

finish.col=4;

cout<<“布线结束点”<<endl;

cout<<finish.col<<" "<<finish.row<<endl;

int PathLen=0;

Position *path;

FindPath(start,finish,PathLen,path);

cout<<“布线后路径图”<<endl;

showPath();

cout<<“路径”<<endl;

for(int i=0; i<PathLen; i++)

{

cout<<path[i].col<<" "<<path[i].row<<endl;

}

cout << “布线问题完毕!” << endl;

system(“pause”);

return 0;

总结

其实要轻松掌握很简单,要点就两个:

  1. 找到一套好的视频资料,紧跟大牛梳理好的知识框架进行学习。
  2. 多练。 (视频优势是互动感强,容易集中注意力)

你不需要是天才,也不需要具备强悍的天赋,只要做到这两点,短期内成功的概率是非常高的。

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。下面资料部分截图是我花费几个月时间整理的,诚意满满:特别适合有3-5年开发经验的Android程序员们学习。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

-1714679594446)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 22
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是使用C++实现的0-1背包问题的分支限界算法: ```c++ #include <iostream> #include <queue> #include <algorithm> using namespace std; // 物品结构体 struct Item { int weight; // 物品重量 int value; // 物品价值 int level; // 物品层级 double bound; // 当前状态下的上界 }; // 用于比较两个物品的上界大小 struct cmp { bool operator()(Item a, Item b) { return a.bound < b.bound; } }; // 用于存储当前最优解 int max_value = 0; // 用于计算当前状态下的上界 double upper_bound(int capacity, int weight, int value, int num, Item items[]) { double bound = value; int i = num; // 从当前状态的下一个物品开始计算 while (weight < capacity && i < n) { if (weight + items[i].weight <= capacity) { weight += items[i].weight; bound += items[i].value; } else { int remain = capacity - weight; bound += items[i].value * ((double) remain / items[i].weight); break; } i++; } return bound; } // 分支限界算法 void knapsack(int capacity, int weight, int value, int num, Item items[]) { // 创建优先队列,用于存储待扩展的节点 priority_queue<Item, vector<Item>, cmp> pq; Item root = {0, 0, 0, 0}; root.bound = upper_bound(capacity, weight, value, 0, items); pq.push(root); while (!pq.empty()) { Item node = pq.top(); pq.pop(); // 如果当前节点的上界小于当前最优解,则直接跳过 if (node.bound < max_value) continue; // 如果已经到达叶子节点,则更新最优解并返回 if (node.level == n) { max_value = node.value; continue; } // 分别扩展左右子节点 Item left = {weight + items[node.level].weight, value + items[node.level].value, node.level + 1, 0}; left.bound = upper_bound(capacity, left.weight, left.value, left.level, items); Item right = {weight, value, node.level + 1, 0}; right.bound = upper_bound(capacity, right.weight, right.value, right.level, items); // 如果左子节点的上界大于当前最优解,则入队 if (left.bound >= max_value) pq.push(left); // 如果右子节点的上界大于当前最优解,则入队 if (right.bound >= max_value) pq.push(right); } } int main() { // 读入数据 int capacity, n; cin >> capacity >> n; Item items[n]; for (int i = 0; i < n; i++) { cin >> items[i].weight >> items[i].value; } // 按照价值密度排序 sort(items, items + n, [](Item a, Item b) { return a.value * b.weight > b.value * a.weight; }); // 调用分支限界算法求解 knapsack(capacity, 0, 0, 0, items); // 输出最优解 cout << max_value << endl; return 0; } ``` 其中,`Item`结构体表示一个物品,包含物品的重量、价值、层级和当前状态下的上界。`cmp`结构体用于比较两个物品的上界大小,以便优先队列能够按照上界从大到小的顺序出队。`upper_bound`函数用于计算当前状态下的上界,这里使用贪心策略计算。 在`knapsack`函数中,我们首先创建一个优先队列,并将根节点压入队列中。然后不断地从队列中取出节点进行扩展,直到队列为空。在扩展节点时,我们首先判断当前节点的上界是否小于当前最优解,如果是,则直接跳过该节点;否则,如果当前节点已经到达叶子节点,则更新最优解并返回;否则,我们分别扩展当前节点的左右子节点,并计算它们的上界。如果左子节点的上界大于当前最优解,则将其入队;如果右子节点的上界大于当前最优解,则将其入队。这样,我们就能够逐步扩展状态空间树,直到找到最优解或者搜索完整个状态空间树。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值