分支限界法实验

题目描述

任务分配问题:任务分配问题要求把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;
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dearzcs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值