Task allocation problem (backtracking method)

algorithm design

Problem Description

There are n (n ≥ 1) tasks that need to be assigned to n people for execution. Each task can only be assigned to one person, and each person can only perform one task.
The cost for the i-th person to perform the j-th task is c[i][j] (1≤i, j≤n). Find the allocation plan that minimizes total cost
Insert image description here

Problem-solving ideas

The general steps of backtracking problem solving
(1) Determine the solution space tree of the problem for a given problem. The solution space tree of the problem should contain at least one solution or the optimal solution of the problem.
(2) Determine the extended search rules for nodes
(3) Search the solution space tree in a depth-first manner, and use the branch reduction function to avoid invalid searches during the search process. Among them, the depth-first method can choose recursive backtracking or iterative (non-recursive) backtracking.

By appropriately transforming the problem, the solution space tree is obtained as a permutation tree. Each complete path in this tree represents a possible solution. Search the tree depth-first, enumerate every possible solution, and find the minimum cost result. Among them, a constraint function is constructed to delete some impossible solutions, thereby greatly improving program efficiency.

Algorithm Description

(1) Solution space
The solution space is {x1, x2, x3, x4..., xn}, where xi=1, 2, 3, 4...n, indicating the tasks arranged by the i-th person
(2) Solution space tree
Insert image description here
Insert image description here
Insert image description here

#include<iostream>
#include<cstring>

using namespace std;
#define MAXN 20
#define INF 9999

//定义问题
int n=4;
int a[MAXN][MAXN]={
    
    {
    
    0,0,0,0,0},{
    
    0,9,2,7,8},{
    
    0,6,4,3,7},{
    
    0,5,8,1,8},{
    
    0,7,6,9,4}}; 
//存储结果
int temp[MAXN];		//临时解 
int temp_cost=0;	//临时成本 
int best[MAXN];		//最优解 
int best_cost=INF;	//最优成本 
bool worker[MAXN];	//任务是否分配 
//深度优先遍历算法
void dfs(int i)
{
    
    
	if(i>n)							//遍历到叶子节点 
	{
    
    
		if(temp_cost<best_cost)		//临时成本<最优成本 
		{
    
    
			best_cost=temp_cost;	//更新最优成本 
			for(int j=1;j<=n;j++)
				best[j]=temp[j];	//更新最优解 
		}
	}
	else
	{
    
    
		for(int j=1;j<=n;j++)		//遍历任务 
			if(!worker[j])			//如果任务没有被选择,执行以下语句 
			{
    
    
				worker[j]=true;		//任务被选择 
				temp[i]=j;			//j任务分配给i人员 
				temp_cost+=a[i][j];	//临时成本 
				dfs(i+1);			//下一个人员分配任务		执行dfs(2),判断worker[1]=true已经被分配,执行j=2,第2个任务分配,直到i=4分配完成 
				worker[j]=false;	// ①执行worker[4]=false	② 
				temp[j]=0;			//①temp[4]=0 
				temp_cost=temp_cost-a[i][j];	//①减去第四个人员成本 
			}		
	}
 } 
 int main()
 {
    
    
 	memset(worker,0,sizeof(worker));//worker初始化为false 
 	dfs(1);							//从人员1开始 
 	for(int k=1;k<=n;k++)
		printf("第%d个人安排任务%d\n",k,best[k]);
	printf("总成本%d\n",best_cost);
	return 0;
 }

Insert image description here

Guess you like

Origin blog.csdn.net/qq_52108058/article/details/133905195