大家好,欢迎来到IT知识分享网。
1.问题引入:
任务分配问题要求把n项任务分配给n个人,每个人完成每项任务的成本不同,要求分配总成本最小的最优分配方案。
设当前已对人员1~i分配了任务,并且花费了成本cur_cost,则限界函数可以定义:
lb=每个人对应的最小任务成本之和;
则最优解为:
bestcost=cur_cost)+lb;
任务和人员的编号均为1~n,解空间每一层对应一个人员的分配。
根结点对应人员0(虚结点),依次为人员1、2、…、n分配任务。
叶子结点对应人员n。
解向量为x:x[i]表示人员i分配任务编号。初始时所有元素值为0,表示没有分配。
临时标识数组work:work[i]=1表示任务i已经分配。初始时所有元素值为0,表示没有分配。
用best[Max]存放最优分配方案, bestcost(初始值为1e5)存放最优成本。
2.代码:
#include<bits/stdc++.h> using namespace std; #define Max 2000 int n; int cost[Max][Max]; int best[Max]; int bestcost=1e5; struct node{ int num; //已分配人数 int cur_cost; //已计算成本 int lb; //当前下界 int x[Max]; //第几个人分配第几个任务 int work[Max]; //任务是否分配 0为未分配; bool operator<(const node& s) const{//定义排序规则 return lb>s.lb; } }; void bound(node&x){//计算下界函数 int Min=0; for(int i=x.num+1;i<=n;i++){ int mini=Max; for(int j=1;j<=n;j++){ if(x.work[j]==0&&cost[i][j]<mini){ mini=cost[i][j]; } } Min+=mini; } x.lb=x.cur_cost+Min; } //注意:这里每一次计算完bound(y),并不能保证其最终取的cur_cost为lb,所以每一个扩展节点计算lb后就算它是最小的,也必须计算完所有的节点才能打印输出。 //(第一个达到叶子结点的并非全局最优解)与上题作业调度问题的区别是没有贪心计算下界,约束条件少一点。 void BFS(){ priority_queue<node> Q;//创建优先队列; node x,y; //初始化根节点 x.num=0; x.cur_cost=0; memset(x.x,0,sizeof(x.x)); memset(x.work,0,sizeof(x.work)); bound(x); Q.push(x); while(!Q.empty()){ node z=Q.top(); Q.pop(); //到达叶子结点,及时更新最优成本bestcost值 if(z.num==n){ if(z.cur_cost<bestcost){ bestcost=z.cur_cost; for(int j=1;j<=n;j++){ best[j]=z.x[j]; } } } //计算新节点的各个值 y.num=z.num+1; for(int i=1;i<=n;i++){ if(z.work[i]) continue; //计算y的x[]值 for(int j=1;j<=n;j++){ y.x[j]=z.x[j]; } y.x[y.num]=i; //计算y的work[]值 for(int k=1;k<=n;k++){ y.work[k]=z.work[k]; } y.work[i]=1; //计算y的cur_cost和lb值; y.cur_cost=z.cur_cost+cost[y.num][i]; bound(y); //判断并入队; if(y.lb<=bestcost){ Q.push(y); } } } } int main(){ cout<<"输入人员数/任务数大小: n"<<endl; cin>>n; printf("输入人员-任务值(%d x %d矩阵)\n",n,n); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cin>>cost[i][j]; } } BFS(); cout<<"最佳方案为:"<<endl; for(int i=1;i<=n;i++){ printf("第%d个人分配%d个任务\n",i,best[i]); } cout<<"总成本为="<<bestcost<<endl; return 0; }
3.运行截图:
菜鸟进化中…….
欢迎大家一起学习交流
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/152375.html