题目描述
任务分配问题:任务分配问题要求把n项任务分配给n个人,每个人完成每项任务的成本不同,求分配总成本最小的最优分配方案。用分支限界法求解任务分配问题,随机生成成本矩阵,矩阵中元素的取值范围为1~10,任务数目n可以由用户输入。记录程序运行时间,做出曲线图,横坐标为n,纵坐标为运行时间。
运行结果
蛮力法未加优化时间复杂度为O(n!)
分支限界的解空间树相对于蛮力法要优化很多,但是最坏情况也为O(n!)
代码
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<time.h>
using namespace std;
const int N = 1e3 + 10;
typedef struct its
{
string num;
int cost,line;
bool operator < (const its &w) const
{
return cost < w.cost;
}
} Its;
int st[N][N];
int n;
Its qt[N];
bool pt[N];
int LOW[N];
int up ;
int low;
int anrs;
bool pt2[N];
int eva(int t)
{
int ans = 0;
for(int i = t; i <= n ; i ++ )
ans += LOW[i];
return ans;
}
bool check(int t)
{
if(t < low || t > up) return false;
return true;
}
void test()
{
for(int i = 1 ; i <= n ; i ++)
{
for(int j = 1 ; j <= n; j ++)
cout << st[i][j] <<" ";
cout <<endl;
}
}
void dfs(int u,int t)
{
if(u == n+1)
{
anrs = min(anrs, t);
return;
}
for(int i = 1; i <= n ; i ++ )
{
if(!pt2[i])
{
pt2[i] = true;
dfs(u+1,t+st[u][i]);
pt2[i] = false;
}
}
}
int main()
{
for( n = 1 ; n <= 7 ; n ++ )
{
clock_t x1,y1,x2,y2;
anrs = N;
up = 0;
low = 0;
memset(pt,0,sizeof pt);
memset(pt2,0,sizeof pt2);
for(int i = 1 ; i <= n ; i ++ )
{
int mins = N;
int y2;
int mins2 = N;
for(int j = 1 ; j <= n ; j++ )
{
st[i][j] = rand() % 10 + 1;
mins = min(st[i][j],mins);
if(!pt[j]&&mins2 > st[i][j])
{
y2 = j;
mins2 = st[i][j];
}
}
up+=mins2;
pt[y2] = true;
low += mins;
LOW[i] = mins;
}
int tt = 0;
int hh = -1;
x1 = clock();
vector<Its>a;
for(int i = 1 ; i <= n; i ++ )
{
int e = eva(2);
int ans = st[1][i] + e;
string r = "";
r+=i + '0';
if(check(ans))
{
a.push_back({r,ans-e,2});
}
}
sort(a.begin(),a.end());
for(int i = 0; i < a.size() ; i++ )
{
qt[++hh] = a[i];
}
while(tt<=hh)
{
Its t = qt[tt++];
int i = t.line;
vector<Its>b;
for(int j = 1 ; j <= n ; j ++ )
{
string nums = t.num;
int wi = t.cost;
char ss = j + '0';
bool it = true;
for(int i = 0; i < nums.size() ; i ++ )
if(nums[i] == ss)
it = false;
if(it)
{
int e = eva(i+1);
int ans = wi + st[i][j] + e;
nums+=j+'0';
if(check(ans))b.push_back({nums,ans - e, i + 1});
}
}
sort(b.begin(),b.end());
for(int k = 0; k < b.size() ; k ++ )
{
qt[++hh] = b[k];
}
}
int cs = N;
int css = 0;
for(int i = hh ; i >= 0 ; i -- )
{
if(qt[i].cost <cs && qt[i].num.size() == n)
{
cs = qt[i].cost;
css = i;
}
}
y1 = clock();
x2 = clock();
dfs(1,0);
y2 = clock();
cout << endl;
cout << "任务情况为:"<< endl;
test();
string s1 = qt[css].num;
for(int i = 0 ; s1[i] ; i ++ )
{
cout << "第 " << i + 1 << "个工人做第 " << s1[i] << "个任务"<< endl;
}
cout <<"分支限界的花费是: " << cs <<" 时间花费是 : "<< y1 - x1<<endl;
cout <<"蛮力的花费是: " << anrs<<" 时间花费是 : "<< y2 - x2<<endl;
}
return 0;
}
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<time.h>
using namespace std;
const int N = 1e3 + 10;
typedef struct its
{
string num;
int cost,line;
bool operator < (const its &w) const
{
return cost < w.cost;
}
} Its;
int st[N][N];
int n;
Its qt[N];
bool pt[N];
int LOW[N];
int up ;
int low;
int anrs;
bool pt2[N];
int eva(int t)
{
int ans = 0;
for(int i = t; i <= n ; i ++ )
ans += LOW[i];
return ans;
}
bool check(int t)
{
if(t < low || t > up) return false;
return true;
}
void test()
{
for(int i = 1 ; i <= n ; i ++)
{
for(int j = 1 ; j <= n; j ++)
cout << st[i][j] <<" ";
cout <<endl;
}
}
void dfs(int u,int t)
{
if(u == n+1)
{
anrs = min(anrs, t);
return;
}
for(int i = 1; i <= n ; i ++ )
{
if(!pt2[i])
{
pt2[i] = true;
dfs(u+1,t+st[u][i]);
pt2[i] = false;
}
}
}
int main()
{
for( n = 1 ; n <= 7 ; n ++ )
{
clock_t x1,y1,x2,y2;
anrs = N;
up = 0;
low = 0;
memset(pt,0,sizeof pt);
memset(pt2,0,sizeof pt2);
for(int i = 1 ; i <= n ; i ++ )
{
int mins = N;
int y2;
int mins2 = N;
for(int j = 1 ; j <= n ; j++ )
{
st[i][j] = rand() % 10 + 1;
mins = min(st[i][j],mins);
if(!pt[j]&&mins2 > st[i][j])
{
y2 = j;
mins2 = st[i][j];
}
}
up+=mins2;
pt[y2] = true;
low += mins;
LOW[i] = mins;
}
int tt = 0;
int hh = -1;
x1 = clock();
vector<Its>a;
for(int i = 1 ; i <= n; i ++ )
{
int e = eva(2);
int ans = st[1][i] + e;
string r = "";
r+=i + '0';
if(check(ans))
{
a.push_back({r,ans-e,2});
}
}
sort(a.begin(),a.end());
for(int i = 0; i < a.size() ; i++ )
{
qt[++hh] = a[i];
}
while(tt<=hh)
{
Its t = qt[tt++];
int i = t.line;
vector<Its>b;
for(int j = 1 ; j <= n ; j ++ )
{
string nums = t.num;
int wi = t.cost;
char ss = j + '0';
bool it = true;
for(int i = 0; i < nums.size() ; i ++ )
if(nums[i] == ss)
it = false;
if(it)
{
int e = eva(i+1);
int ans = wi + st[i][j] + e;
nums+=j+'0';
if(check(ans))b.push_back({nums,ans - e, i + 1});
}
}
sort(b.begin(),b.end());
for(int k = 0; k < b.size() ; k ++ )
{
qt[++hh] = b[k];
}
}
int cs = N;
int css = 0;
for(int i = hh ; i >= 0 ; i -- )
{
if(qt[i].cost <cs && qt[i].num.size() == n)
{
cs = qt[i].cost;
css = i;
}
}
y1 = clock();
x2 = clock();
dfs(1,0);
y2 = clock();
cout << endl;
cout << "任务情况为:"<< endl;
test();
string s1 = qt[css].num;
for(int i = 0 ; s1[i] ; i ++ )
{
cout << "第 " << i + 1 << "个工人做第 " << s1[i] << "个任务"<< endl;
}
cout <<"分支限界的花费是: " << cs <<" 时间花费是 : "<< y1 - x1<<endl;
cout <<"蛮力的花费是: " << anrs<<" 时间花费是 : "<< y2 - x2<<endl;
}
return 0;
}