回溯法

Time : 2020.01.16

/************************************************************************
功能: 将n个作业分配给n个人完成,使得总花费时间最短(回溯法)
值得注意的是:作业数和人数都是有要求的——相同。
************************************************************************/
#include "stdio.h"
#include <iostream>
#include<fstream>
#include<string>

using namespace std;
//-----------------------------------------------------------------------
#define N 64                  //N表示最大作业数和工人数
int c[N][N];                  //c[i][j] 表示工人i执行作业j所用的时间(下标从1开始)
unsigned int mincost = 65535; //设置的费用初始值
int	isAssigned[N];            //记录作业是否已被分配给工人,1表示已分配,0为未分配
int currSolution[N];          //当前作业分配情况:工人i 执行作业currSolution[i]
int	bestSolution[N];          //最优作业分配情况: 工人i执行作业bestSolution[i]
int njob;                     //作业、工人数
//-----------------------------------------------------------------------


/************************************************************************
** 功能:初始化操作
** 输入参数:工人、作业数njob
**			花费矩阵c[n][n]
**			同时初始化isAssigned, currSolution, bestSolution数组
************************************************************************/

void initData(int* isAssigned, int* currSolution, int* bestSolution)
{
    int b=50,a=10;
    njob=5;
    for(int i = 1; i <= njob; i++){
        for (int j = 1; j <= njob; j++){
           c[i][j]=rand()%(b-a)+a;
           cout<<"c["<<i<<"]"<<"["<<j<<"]"<<c[i][j]<<endl;
        }
    }
    //初始化数组
    for(int k =0; k <= njob; k++){
        isAssigned[k] = 0;
        currSolution[k]   = 0;
        bestSolution[k]   = 0;
    }
}
/************************************************************************
** 功能:回溯法分配作业
** 参数:k工人编号
** cost为分配当前作业后的花费
************************************************************************/
void assignJob(int k,unsigned int cost)
{
    int i;
    if(k > njob){
        mincost = cost;
        for(i=1; i<=njob; i++)
            bestSolution[i] = currSolution[i];
    }
    else{
        for(i=1;i<=njob;i++){
            if(isAssigned[i]==0 && cost+c[k][i] < mincost){
                isAssigned[i] = 1; currSolution[k] = i;
                assignJob(k+1,cost+c[k][i]);
                isAssigned[i] = 0; currSolution[k] = 0;
            }
        }
    }
}

/************************************************************************
** 功能:输出结果
** 参数:minCost最小花费
**		 njob工人作业数
**		 bestSolution分配方案
************************************************************************/
void printResult(int minCost,int njob, int* bestSolution)
{
    cout<<"最小总费用为: "<<mincost<<endl;
    cout<<"分配方案为:"<<endl;
    for(int i=1; i<= njob;i++)
    cout<< "工人: "<< i <<" -> 分配作业: "<< bestSolution[i]  <<endl;
    ofstream fout("output_assign04_01.dat");
    fout<< "最小总费用为: " <<mincost<<endl;
    for(int j=1; j<= njob;j++)
    fout<< "工人: "<< j <<" -> 分配作业: "<< bestSolution[j]  <<endl;

}

int main()
{
    //从文件读入工人作业数njob和花费矩阵c(https://blog.csdn.net/llw01/article/details/8829097)
    //同时初始化isAssigned, currSolution, bestSolution数组
    initData(isAssigned, currSolution, bestSolution);
    assignJob(1,0);
    printResult(mincost, njob,bestSolution);//输出
    system("pause");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值