当前位置:   article > 正文

任务分配问题基于深度优先遍历的C++实现算法_c++工作分配问题

c++工作分配问题

 

1 课程设计题目与要求

1.1设计题目:任务分配问题

1.2设计要求

 问题描述:

//有N个任务需要分配给n个人执行,一个任务对应一个人(意思是说,每个任务只分配给一个人,每个人只分配一个任务)

//对于每一对i,j=1,2,3......n来说,将j个任务分配给第i个人的成本是C[I,J];找出总成本最小的分配方案      

2 总体设计

3 详细设计

3.1数据结构设计或类设计

本程序定义了一个主函数,用户可根据界面提示自行操作。由于要实现界面的回复,所以用了大量的函数调用,在控制用户的循环操作时采用了大量的for循环、do while语句、if  else语句、return语句、switch语句等,其中涉及到多个递归函数表达式。

数据成员主要有成本矩阵,贪心成本,最低成本等内容,用户只需要在首页填写矩阵的大小,每个人员分配任务的成本即可。

Arr[][];                                                                  成本矩阵

mincost;                                               每行最小值矩阵

greedcost[];                                                          贪心矩阵

temp[];                                      每种组合方法的成本之和

k;                                            temp数组中第k种成本

cost=0;                                                      当前成本之和

y[];                                              记录纵坐标前驱的数组

CreateArr();                                            初始化成本矩阵

StarMin();                                        初始化mincost[]数组

SetMin();                                            填充mincost[]数组

SumMin();                                            mincost[]数组求和

StarTemp();                                            temp[]数组初始化

StarGreed();                                           初始化贪心矩阵

SumOfGreed();   贪心法求Arr[][]数组的近似最低成本

Recursion();                                                   递归调用函数

Back();                                                                 回溯函数

3.2模块设计

3.2.1初始化成本矩阵函数,在整个程序开始运行之前,先构建一个二维数组,然后由用户输入具体的任务成本,等到整个循环结束,即可退出

3.2.2 初始化mincost[]矩阵函数,对于全局变量mincost[]函数,将Arr[]每一行先存入mincost[]数组中去,有利于后面的比较,并且找出最小值。

3.2.3 填充mincost[]数组函数,从Arr的每一行的第二个值开始比较,如果上一个的值比mincost[]对应的值小的话,就将mincost[]的值改为较小的数值。这样等到循环结束以后,mincost[]数组里面每一个对应的都是Arr每一行对应的最小值。即整个数组填充完毕。

3.2.4 mincost[]数组求和函数,就可以得出对应的成本下界。

3.2.5 temp[]数组初始化,temp数组是用于记录每一种可行的成本,即大于下界,且小于上界的人员分配方案。从而得到的结果存于temp数组中。第一个记录贪心矩阵所得的结果,即上界。

3.2.6初始化贪心矩阵函数,给贪心矩阵一个初始值。

3.2.7贪心法求Arr[][]数组的近似最低成本函数,在每一行选择出最合适的矩阵,作为放入贪心矩阵中,最后将贪心矩阵中的值相加,就可以得到贪心成本。

3.2.8递归调用函数,将Arr每一行的行数,人员数目,每一行所选的纵坐标作为参数传递进去,以是否全部寻找过全部元素作为出口,如果全部搜索了一遍,就可以到达出口。

3.2.9回溯函数,当递归函数的每一次往下搜寻失败的时候,利用回溯函数返回最近一个可执行行上去,继续进行搜寻。 

 

4运行结果

1、首先给出用户操作界面

2、用户根据提示选择相应功能

例如输入的人员为为4个人的话,则输入每个人员的任务成本,如图所示:

 

运行过后,我们可以得知整个成本矩阵的上界,下界,以及最优成本如下图所示:

 

5.详细代码:

  1. #include<iostream>
  2. #include<cstdlib>
  3. using namespace std;
  4. #define Max 9999
  5. #define NUM 10000
  6. //有N个任务需要分配给n个人执行,一个任务对应一个人(意思是说,每个任务只分配给一个人,每个人只分配一个任务)
  7. //对于每一对i,j=1,2,3......n来说,将j个任务分配给第i个人的成本是C[I,J];找出总成本最小的分配方案
  8. int Arr[1000][1000]; //成本矩阵
  9. int mincost[1000]; //成本矩阵中每一行最小的成本
  10. int greedcost[1000]; //贪心矩阵
  11. int temp[NUM]; //每种组合方法的成本之和
  12. int k=0; //temp数组中第k种成本
  13. int cost=0; //当前成本之和
  14. int y[1000]; //记录纵坐标前驱的数组,y[i]
  15. void CreateArr(int number); //初始化成本矩阵
  16. void StarMin(int number); //初始化mincost[]数组
  17. void SetMin(int number); //填充mincost[]数组
  18. int SumMin(int number); //mincost[]数组求和
  19. void StarTemp(int number); //temp[]数组初始化
  20. void StarGreed(int number); //初始化贪心矩阵
  21. int SumOfGreed(int number); //贪心法求Arr[][]数组的近似最低成本
  22. void Recursion(int i1,int j0,int j1,int number); //递归调用函数
  23. int Back(int i,int j,int number); //回溯函数,清除本层痕迹,返回到上面最近的可执行的一行
  24. int main()
  25. {
  26. int number,i=0,j=0,SumLow=0,SumUp=0; //任务(人)数量
  27. cout << "请输入任务\\人员数量(n<=1000):" << endl;
  28. cin >> number;
  29. CreateArr(number); //创建二维成本矩阵
  30. StarMin(number); //初始化mincost[]数组
  31. SetMin(number); //填充mincost[]数组
  32. SumLow=SumMin(number); //mincost[]数组求和,成本的下界
  33. StarGreed(number); //初始化greedcost[]数组
  34. SumUp=SumOfGreed(number); //贪心法求Arr[][]数组的近似最低成本,即成本的上界
  35. for(int xy=0;xy<number;xy++) //给纵坐标初始化,贪心矩阵归0
  36. {
  37. y[xy]=0;
  38. greedcost[xy]=Max;
  39. }
  40. cost=Arr[0][0];
  41. greedcost[0]=Arr[0][0];
  42. Recursion(i,y[i],j,number); //递归调用函数
  43. int SuitCost=temp[0];
  44. for(int L=1;L<NUM;L++)
  45. {
  46. if(temp[L]==0) break;
  47. if(temp[L]<SuitCost)
  48. {
  49. SuitCost=temp[L];
  50. }
  51. }
  52. cout<<"成本上界是:"<<SumUp<<endl;
  53. cout<<"成本下界是:"<<SumLow<<endl;
  54. cout<<"最小成本是:"<<SuitCost<<endl;
  55. system("pause");
  56. return 0;
  57. }
  58. void CreateArr(int number) //构建二维成本矩阵
  59. {
  60. for(int i=0;i<number;i++) //生成number*number的二维数组,确定每个人的任务完成成本
  61. {
  62. for(int j=0;j<number;j++)
  63. {
  64. cout<<"Arr["<<i<<"]["<<j<<"]"<<"=";
  65. cin>>Arr[i][j];
  66. }
  67. }
  68. }
  69. void StarMin(int number) //初始化mincost[]数组
  70. {
  71. for(int n0=0;n0<number;n0++) //将mincost[]数组初始化
  72. {
  73. mincost[n0]=Arr[n0][0];
  74. }
  75. }
  76. void SetMin(int number) //填充mincost[]数组
  77. {
  78. for(int n1=0;n1<number;n1++) //将成本矩阵中每一行最小的数字存入mincost[]数组中
  79. {
  80. for(int n2=0;n2<number-1;n2++)
  81. {
  82. if(Arr[n1][n2+1]<mincost[n1])
  83. {
  84. mincost[n1]=Arr[n1][n2+1];
  85. }
  86. }
  87. }
  88. }
  89. int SumMin(int number) //mincost[]数组求和
  90. {
  91. int SumLow=0;
  92. for(int i0=0;i0<number;i0++) //SumLow为mincost数组里面的所有数之和,及成本矩阵中最小的数
  93. {
  94. SumLow=SumLow+mincost[i0];
  95. }
  96. return SumLow;
  97. }
  98. void StarTemp(int number) //temp数组初始化
  99. {
  100. for(int ii=0;ii<NUM;ii++)
  101. {
  102. temp[ii]=0;
  103. }
  104. }
  105. void StarGreed(int number) //初始化贪心矩阵,里面的每个值都归0
  106. {
  107. for(int igreed=0;igreed<number;igreed++)
  108. {
  109. greedcost[igreed]=0;
  110. }
  111. }
  112. int SumOfGreed(int number) //贪心法求Arr[][]数组的近似最低成本,即上界
  113. {
  114. StarTemp(number); //temp数组初始化
  115. int minsuit=Max,j1; //j1记录每一次每一行得到的最合适的值得纵坐标
  116. for(int i=0;i<number;i++)
  117. {
  118. minsuit=Max; //每次换行的时候将minsuit初始化成最大值
  119. for(int j=0;j<number;j++)
  120. {
  121. if(greedcost[j]!=0)
  122. {
  123. continue;
  124. }
  125. if(Arr[i][j]<minsuit)
  126. {
  127. minsuit=Arr[i][j];
  128. j1=j;
  129. }
  130. }
  131. greedcost[j1]=minsuit;
  132. temp[0]=temp[0]+greedcost[j1];
  133. }
  134. return temp[0];
  135. }
  136. void Recursion(int i,int j0,int j,int number) //递归调用函数,(0,0,0,4)
  137. {
  138. if(i==0 && y[i]==number) return ;
  139. if(cost<=temp[0])
  140. {
  141. if(i>=number-1)
  142. {
  143. k++;
  144. temp[k]=cost;
  145. i=Back(i,j,number);
  146. j=y[i];
  147. }
  148. else{
  149. i++;
  150. j=0;
  151. while(greedcost[j]!=Max)
  152. {
  153. j++;
  154. }
  155. cost=cost+Arr[i][j];
  156. y[i]=j;
  157. greedcost[y[i]]=Arr[i][j];
  158. }
  159. }
  160. else{
  161. if(y[i]>=number-1)
  162. {
  163. i=Back(i,j,number);
  164. j=y[i];
  165. }
  166. else{
  167. i=Back(i,j,number);
  168. j=y[i];
  169. }
  170. }
  171. Recursion(i,y[i],j,number);
  172. }
  173. int Back(int i,int j,int number) //回溯函数,清除本层痕迹,返回到上面最近的可执行的一行
  174. {
  175. if(i==0)
  176. { //如果该行为第一行
  177. if(y[i]==number-1)
  178. { //如果该元素是最后一个
  179. y[i]++;
  180. return i;
  181. }
  182. else{ //如果该元素不是最后一个
  183. cost=cost-Arr[i][y[i]];
  184. greedcost[y[i]]=Max;
  185. y[i]++;
  186. greedcost[y[i]]=Arr[i][y[i]];
  187. cost=cost+Arr[i][y[i]];
  188. return i;
  189. }
  190. }
  191. else{ //如果不是第一行
  192. y[i]=j;
  193. while(greedcost[j]!=Max)
  194. {
  195. j++;
  196. if(j>=number) break;
  197. }
  198. if(j<number)
  199. { //如果有空闲的位置,清除当行信息,往后挪动
  200. cost=cost-Arr[i][y[i]];
  201. greedcost[y[i]]=Max;
  202. y[i]=j;
  203. greedcost[y[i]]=Arr[i][y[i]];
  204. cost=cost+Arr[i][y[i]];
  205. return i;
  206. }else{
  207. //如果没有空位,清除当前痕迹;
  208. cost=cost-Arr[i][y[i]];
  209. greedcost[y[i]]=Max;
  210. y[i]=0;
  211. i--; //返回上一层;
  212. j=y[i];
  213. i=Back(i,j,number);
  214. return i;
  215. }
  216. }
  217. }

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/284759
推荐阅读
相关标签
  

闽ICP备14008679号