作业分配(回溯法)

本文介绍了一个使用回溯算法解决n个人完成n份作业的问题,以达到总花费时间最短的目标。通过C++实现,从文件中读取作业时间和完成情况,并采用回溯法寻找最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有n份作业分配给n个人去完成,每人完成一份作业。假定第i个人完成第j份作业需要花费cij时间, cij>0,1≦i,j≦n。试设计一个回溯算法,将n份作业分配给n个人完成,使得总花费时间最短。
C++实现:

/*
 * Author:  qinwu
 * Created Time:  2017/4/30 22:45:25
 * File Name: Solution.cpp
 */
#include <iostream>
#include <vector>
#include <limits.h>
#include <fstream>
#include <sstream>
using namespace std;
class Solution
{
    public:
        Solution():m_in("F:/gvim/jobassign/data.txt"), m_minCost(INT_MAX), m_njob(0){}
        void readDataFromTxt();//从data.txt中读取数据
        unsigned int getMinCost()//返回最小的开销
        {
            assign(0, 0);
            return m_minCost;
        }
        void reset();//重置成员变量
        ~Solution(){m_in.close();}
    private:
        void assign(int k, unsigned int cost);//回溯法求解作业分配问题
        //清除vector实际空间
        template<class T>
        void clearVector(vector<T>& vt) 
        {
            vector<T> temp; 
            temp.swap(vt);
        }
    private:
        ifstream m_in;
        int m_njob;//作业数
        unsigned int m_minCost;//最小开销
        vector<vector<int> > m_c;//存储每个工人完成每个作业的时间
        vector<bool> m_job;//标识作业是否被完成
};

void Solution::readDataFromTxt()
{
    string line;
    vector<int> temp;
    int value;
    while(!m_in.eof())
    {
        getline(m_in, line);
        if(line[0] != '*')
        {
            stringstream s(line);
            while(s >> value)
                temp.push_back(value);
            m_c.push_back(temp);
            temp.clear();
        }
        else
            break;
    }
    m_njob = m_c.size();
    m_job = vector<bool>(m_njob, false);
}

void Solution::reset()
{
    clearVector(m_job);
    clearVector(m_c);
    m_minCost = INT_MAX;
}

void Solution::assign(int k, unsigned int cost)
{
    if(k >= m_njob && cost < m_minCost)
        m_minCost = cost;//更新最小开销
    else
    {
        for(int i=0; i < m_njob; ++i)//对当前工人k进行的作业的选择
        {
            if(!m_job[i] && cost+m_c[k][i] < m_minCost)
            {
                m_job[i] = true;
                assign(k+1, cost+m_c[k][i]);//递归的对下一个工人进行作业选择
                m_job[i] = false;
            }
        }
    }
}

int main(void)
{
    //测试
    Solution t;
    for(int i=0; i < 5; ++i)
    {
        t.readDataFromTxt();
        cout << t.getMinCost() << endl;
        t.reset();
    }
}

data.txt中的实验数据:
五组测试数据
实验结果:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值