概述
void work ( int i , int count ){if ( i > n )return ;for ( int j = 1 ; j <= n ; j ++)if ( x [ j ] == 0 ){x [ j ] = 1 ;work ( i + 1 , count + c [ i ][ j ]);x [ j ] = 0 ;}}
#include<iostream> using namespace std; int n,cost=0; int x[100],c[100][100]; void work(int i,int count){ if(i>n && count<cost){ cost = count; return ; } if(count<cost) for(int j=1;j<=n;j++) if(x[j] == 0){ x[j] = 1; work(i+1,count+c[i][j]); x[j] = 0; } } int main(){ cin>>n; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cin>>c[i][j]; x[j] = 0; } cost+=c[i][i]; } work(1,0); cout<<cost<<endl; system("pause"); return 0; }
//工作分配问题 /* 3 10 2 3 2 3 4 3 4 5 */ #include <iostream> #include <algorithm> using namespace std; int table[21][21],n,best,r[21]; int compute(int k) { int temp=0,i; for(i=1;i<=k;i++) temp+=table[i][r[i]]; return temp; } void search(int k) { if(k==n) { int temp=compute(n); if(temp<best) best=temp; return; } for(int i=k;i<=n;i++) { swap(r[i],r[k]); if(compute(k) < best) search(k+1); swap(r[i],r[k]); } } int main() { int i,j; while(cin>>n,n) { for(i=1;i<=n;i++) for(j=1;j<=n;j++) cin>>table[i][j]; for(i=1;i<=n;i++) r[i]=i; best=INT_MAX; search(1); cout<<best<<endl; } return 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)
- //=======================================================================
- //jobAssign.cpp
- //将n份作业分配给n个人完成,使得总花费时间最短,回溯法
- //by leo
- //5.13.2011
- //=======================================================================
- #include <iostream>
- #include<fstream>
- #include<string>
- using namespace std;
- //-----------------------------------------------------------------------
- #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);
- //-----------------------------------------------------------------------
- void main()
- {
- initData(task, bestSolution, job, njob, c);
- assign(1,0); //从任务1开始分配
- outputResult(mincost, njob,bestSolution);
- system("pause");
- }
- //-----------------------------------------------------------------------
- //读入工人、作业数njob,开销矩阵c[][N]
- //-----------------------------------------------------------------------
- void input(int& njob, int c[][N])
- {
- string str;
- cout << "Please input the input file name"
- << "(input_assign04_00.txt~input_assign04_05.txt):/n";
- cin >> str;
- ifstream fin(str.c_str());
- if(!fin)
- {
- cout << "no such file,please check the file name!" <<endl;
- exit(0);
- }
- fin>>njob;
- for(int i = 1; i <= njob; i++)
- for (int j = 1; j <= njob; j++)
- fin >> c[i][j];
- }
- //-----------------------------------------------------------------------
- //初始化task,bestSolution,job,读入工人、作业数njob,开销矩阵c[][N]
- //-----------------------------------------------------------------------
- void initData(int* task, int* bestSolution, int* job, int& njob, int c[][N])
- {
- input(njob,c);
- for(int k =0; k <= njob; k++)
- {
- job[k] = 0;
- task[k] = 0;
- bestSolution[k] = 0;
- }
- }
- //-----------------------------------------------------------------------
- //为工人k分配作业,cost:当前作业分配后的花费
- //-----------------------------------------------------------------------
- void assign(int k,unsigned int 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] = 1; task[k] = i;
- assign(k+1,cost+c[k][i]);
- job[i] = 0; task[k] = 0;
- }
- }
- }
- }
- //-----------------------------------------------------------------------
- //输出结果:mincost、作业分配情况
- //-----------------------------------------------------------------------
- void outputResult(int minCost,int njob, int* bestSolution)
- {
- cout<<"最小总费用:"<<mincost<<endl;
- for(int i=1; i<= njob;i++)
- cout<< "工人: "<< i <<" 执行任务: "<< bestSolution[i] <<endl;
- ofstream fout("output.txt");
- fout<<mincost<<endl;
- for(int j=1; j<= njob;j++)
- fout<< "工人: "<< j <<" 执行任务: "<< bestSolution[j] <<endl;
- }
- //=======================================================================
以下的代码稍作改变,用于c[i][j]表示作业i由工人j完成的情况
- //=======================================================================
- //jobAssign.cpp
- //将n份作业分配给n个人完成,使得总花费时间最短,回溯法
- //by leo
- //5.13.2011
- //=======================================================================
- #include <iostream>
- #include<fstream>
- #include<string>
- using namespace std;
- //-----------------------------------------------------------------------
- #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]执行
- worker[N]; //记录工人是否已被分配作业
- int njob; //实际工作、工人数
- //-----------------------------------------------------------------------
- //读入工人、作业数njob,开销矩阵c[][N]
- //-----------------------------------------------------------------------
- void input(int& njob, int c[][N])
- {
- string str;
- cout << "Please input the input file name"
- << "(input_assign02_00.txt~input_assign02_01.txt):/n";
- cin >> str;
- ifstream fin(str.c_str());
- if(!fin)
- {
- cout << "no such file,please check the file name!" <<endl;
- exit(0);
- }
- fin>>njob;
- for(int i = 1; i <= njob; i++)
- for (int j = 1; j <= njob; j++)
- fin >> c[i][j];
- }
- //-----------------------------------------------------------------------
- //读入工人、作业数njob,开销矩阵c[][N]
- //-----------------------------------------------------------------------
- void initData(int* task, int* bestSolution, int* worker, int& njob, int c[][N])
- {
- input(njob,c);
- for(int k =0; k <= njob; k++)
- {
- //设置每个人任务由不同工人承担时的费用及全局数组的初值
- worker[k] = 0;
- task[k] = 0;
- bestSolution[k] = 0;
- }
- }
- //-----------------------------------------------------------------------
- //测试:输出c[][N]
- //-----------------------------------------------------------------------
- void outputInitData(int c[][N])
- {
- for(int i = 1; i <= njob; i++)
- {
- for (int j = 1; j <= njob; j++)
- cout << c[i][j] <<" ";
- cout<<endl;
- }
- }
- //-----------------------------------------------------------------------
- //k: 当前要分配的任务,cost:当前作业分配后的花费
- //-----------------------------------------------------------------------
- void assign(int k,unsigned int 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++) //分配任务k
- {
- if(worker[i]==0 && cost+c[k][i])
- {
- worker[i] = 1; task[k] = i;
- assign(k+1,cost+c[k][i]);
- worker[i] = 0; task[k] = 0;
- }
- }
- }
- }
- //-----------------------------------------------------------------------
- //输出结果:mincost、任务分配情况
- //-----------------------------------------------------------------------
- void outputResult(int minCost,int njob, int* bestSolution)
- {
- cout<<"最小总费用:"<<mincost<<endl;
- for(int i=1; i<= njob;i++)
- cout<< "任务:"<< i <<" 由工人:"<< bestSolution[i] << "执行 " <<endl;
- }
- //-----------------------------------------------------------------------
- void main()
- {
- initData(task, bestSolution, worker, njob, c);
- assign(1,0); //从任务1开始分配
- outputResult(mincost, njob,bestSolution);
- for(int i = 1; i <= njob; i++)
- cout << bestSolution[i] << " ";
- cout <<endl;
- }
- //=======================================================================
最后
以上就是刻苦裙子为你收集整理的回溯法-工作分配的全部内容,希望文章能够帮你解决回溯法-工作分配所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复