回溯法 解 作业分配问题

运行环境: Windows XP,(开发环境:VC6.0)
运行过程说明: jobAssignBacktrack.exe
输入源数据文件路径+文件名
在同目录下可以查看输出文件output.txt
★问题描述 有n份作业分配给n个人去完成,每人完成一份作业。假定第i个人完成第j份作业需要花费cij时间,cij>0,1≦i,j≦n。试设计一个回溯算法,将n份作业分配给n个人完成,使得总花费时间最短。
★格式输入 由文件input.txt给出输入数据。第一行有1 个正整数n (1≤n≤100)。
接下来的n行,每行n个数,表示工作费用。
★格式输出 将计算出的结果输出到文件output.txt。
★示例输入输出 5
50 87 62 56 92
43 22 98 57 36
1 5 97 96 43
58 62 27 73 27
60 71 38 71 95

144
工人: 1 执行任务: 4
工人: 2 执行任务: 2
工人: 3 执行任务: 1
工人: 4 执行任务: 5
工人: 5 执行任务: 3
★算法设计(包括算法设计过程中相关内容的说明、数据结构的选择、 算法详细描述及算法分析):
●1.设计说明:
算法中使用job[i]记录作业i是否已被分配,若被分配则置1,不必再搜索其分支;、
assign(int k,unsigned int cost) cost用来记录当前作业分配的开销,作为参数传递给下一层递归调用。
●2.算法设计:
●2.1数据结构:
#define N 100 //N表示最大任务数和工人数
int c[N][N]; //c[i][j] 表示工人i执行作业j所用的时间
unsigned int mincost = 65535; //设置的初始值,大于可能的费用
int task[N], //当前作业分配情况: 工人i执行task[i]
bestSolution[N], //最优作业分配情况: 工人i执行作业bestSolution[i]
job[N]; //记录作业是否已被分配给工人,1表示已分配,0为分配
int njob; //实际工作、工人数
主要操作:
void input(int& njob, int c[][N]); //读入工人、作业数njob,开销矩阵c[][N]
//初始化task,bestSolution,job,读入工人、作业数njob,开销矩阵c[][N]
void initData(int* task, int* bestSolution, int* job, int& njob, int c[][N]);
void assign(int k,unsigned int cost); //为工人k分配作业,cost:当前作业分配后的花费
//输出结果:mincost、作业分配情况
void outputResult(int minCost,int njob, int* bestSolution);
●2.2算法描述:
void assign(int k,unsigned int cost) //为工人k分配作业,cost:当前作业分配后的花费
{
int i;
if(k > njob && cost < mincost) //搜索至叶节点,判断是否更优
{
mincost = cost;
for(i=1; i<=njob; i++)
bestSolution[i] = task[i];
}
else
{
for(i=1;i<=njob;i++)
{
if(job[i]==0 && cost+c[k][i])//约束函数,job[i]==0则为被分配
{
job[i] = 1; task[k] = i;
assign(k+1,cost+c[k][i]);
job[i] = 0; task[k] = 0;
}
}
}
}
●2.3算法分析
本算法的最坏时间复杂度为:O(n!)
最坏空间复杂度为:O(n)

 

 

 

以下的代码稍作改变,用于c[i][j]表示作业i由工人j完成的情况

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值