一种基于平均思想的任务分配算法

        假设现在有n个任务需要分配给m个审核员去完成,但是每个审核员手头上还有未完成的任务,且未完成的任务数不同。那么如何均匀的把这些任务分配给各个审核员呢?这里我提出了一种基于平均思想的任务分配算法(我称之为标杆算法)。

        算法的主要思想是:首先找出所有审核员中手头未完成任务数最大的审核员,然后其它审核员以该审核员的未完成任务数为标杆,计算自己可容纳的任务数,最后所有审核员可容纳的任务数之和即为总的可容纳任务数(ava_task)。

        这里有两种情况,第一种情况是:总的可容纳任务数小于或等于n个待分配的任务数,此时所有审核员以最大未完成任务数(max_task)为标杆,接收待分配的任务。如果刚好分配完,那么算法结束;如果还有剩下的任务未分配,那将剩下的任务抽取m个任务分配给每一个审核员,依次类推,直到剩下的未分配任务数小于m为止,然后再将这小于m的任务随机分配给相应数量的审核员。第二种情况是:总的可容纳任务数大于n个待分配的任务数,此时降低一个单位的标杆(max_task-1),然后循环计算可容纳的任务数,直到退出循环(循环终止条件为:ava_task - task_num <= lower_List.size(),lower_List.size()表示的是低于当前标杆的审核员数)。

        接下来,我们将通过一个简单的例子来说明算法的流程,由于第一种情况比较简单,因此,该例子是基于第二种情况的,,如图1所示。


图1

        假设有20个任务需要分配给8个审核员(对应8个条形图,实线条形图里的数字代表该审核员手头未完成的任务数)。首先找出这8个审核员中未完成任务数的最大值max_task=7,然后各审核员以max_task为标杆计算各自可容纳的任务数(对应虚线条形图里的数字),总的可容纳任务数为所有审核员可容纳的任务数之和,即ava_task=6+3+4+2+5+0+5+6=31,由图1可知,lower_List.size()=7,由于31-20>7,因此可降低一个单位的标杆,即max_task=max_task-1=6,如图2所示。


         那么,ava_task=5+2+3+1+4+0+4+5=24,lower_List.size()=7,由于24-20<7,因此循环终止。由于可容纳的任务数仍然大于待分配的任务数,因此需要再降低一个单位的标杆(一定要考虑这种情况),max_task=max_task-1=5,此时ava_task=4+1+2+0+3+0+3+4=17,lower_List.size()=6,剩余待分配任务数为20-17=3,然后将这3个任务随机分配给低于当前标杆的6个审核员中的3个,每个审核员分配一个。当然算法中还考虑了很多种情况,具体请参见如下代码。由于任务一般按审核员ID来分配,且ID一般为字符串。为了存储方便,我定义了一个二维字符串类型的数组rev_task[i][j]来存储数据,i表示第i个审核员,rev_task[i][0]存放的是第i个审核员的ID,rev_task[i][1]存放的是第i个审核员当前未完成的任务数,rev_task[i][2]存放的是第i个审核员应当被分配的任务数。

算法工具类-AlgorithmUtils.java

package com.yushen.allocationAlgorithm;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

public class AlgorithmUtils {
    public static void taskAllocation(int task_num, int rev_num, String[][] rev_task) {

        Random rd = new Random();
        List<Integer> rdList = new ArrayList<>();
        int temp;

        //获得审核人员中的最大未完成任务数
        int max_task = Integer.parseInt(rev_task[0][1]);
        for(int i = 1; i < rev_num; i++){
            if(max_task < Integer.parseInt(rev_task[i][1]))
                max_task = Integer.parseInt(rev_task[i][1]);
        }

        //以最大待审核任务数为标杆,判断第一轮可容纳的任务数
        int ava_task = 0;
        List<Integer> lower_List = new ArrayList<>();
        for(int i=0;i<rev_num;i++){
            if((max_task-Integer.parseInt(rev_task[i][1])) > 0){
                ava_task += (max_task-Integer.parseInt(rev_task[i][1]));
                lower_List.add(i);
            }
        }

        int task_rest;
        int task_avg;
        //第一种情况:第一轮可容纳的任务数小于待分配的任务数
        if(ava_task - task_num <= 0) {
            for(int i = 0; i < rev_num; i++) {
                rev_task[i][2] = String.valueOf(max_task-Integer.parseInt(rev_task[i][1]));
            }
            task_rest = task_num-ava_task;
            task_avg = task_rest/rev_num;
            if(task_rest != 0) {
                while(task_avg > 0) {
                    for(int i = 0; i < rev_num; i++) {
                        rev_task[i][2] = String.valueOf(Integer.parseInt(rev_task[i][2])+task_avg);
                    }
                    task_rest -= rev_num*task_avg;
                    task_avg = task_rest/rev_num;
                }
                rdList.removeAll(rdList);
                while(rdList.size() < (task_rest+1)){
                    temp = rd.nextInt(rev_num);
                    if(!rdList.contains(temp)){
                        rdList.add(temp);
                    }
                }
                for(int i = 0; i < task_rest; i++) {
                    rev_task[rdList.get(i)][2] = String.valueOf(Integer.parseInt(rev_task[rdList.get(i)][2])+1);
                }
            }
        }else {//第二种情况:第一轮可容纳的任务数大于待分配的任务数,此时降低一个单位的标杆(max_task-1),然后循环计算可容纳的任务数,直到退出循环
            while(ava_task - task_num > lower_List.size()) {
                max_task--;
                ava_task = 0;
                lower_List.removeAll(lower_List);
                for(int i=0;i<rev_num;i++){
                    rev_task[i][2] = "0";
                    if((max_task-Integer.parseInt(rev_task[i][1])) > 0){
                        rev_task[i][2] = String.valueOf(max_task-Integer.parseInt(rev_task[i][1]));
                        ava_task += Integer.parseInt(rev_task[i][2]);
                        lower_List.add(i);
                    }
                }
            }
            if(ava_task - task_num > 0) {//如果可容纳的任务数大于待分配的任务数,那么需要再再降低一个单位的标杆
                max_task--;
                ava_task = 0;
                lower_List.removeAll(lower_List);
                for(int i=0;i<rev_num;i++){
                    if((max_task-Integer.parseInt(rev_task[i][1])) >= 0){
                        rev_task[i][2] = String.valueOf(max_task-Integer.parseInt(rev_task[i][1]));
                        ava_task += Integer.parseInt(rev_task[i][2]);
                        lower_List.add(i);
                    }
                }
                task_rest = task_num - ava_task;
                rdList.removeAll(rdList);
                while(rdList.size() < (task_rest+1)){
                    temp = rd.nextInt(rev_num);
                    if((!rdList.contains(temp))&&(lower_List.contains(temp))){
                        rdList.add(temp);
                    }
                }
                for(int i = 0; i < task_rest; i++) {
                    rev_task[rdList.get(i)][2] = String.valueOf(Integer.parseInt(rev_task[rdList.get(i)][2])+1);
                }
            }else {
                task_rest = task_num-ava_task;
                if(task_rest != 0) {
                    rdList.removeAll(rdList);
                    while(rdList.size() < (task_rest+1)){
                        temp = rd.nextInt(rev_num);
                        if((!rdList.contains(temp))&&(lower_List.contains(temp))){
                            rdList.add(temp);
                        }
                    }
                    for(int i = 0; i < task_rest; i++) {
                        rev_task[rdList.get(i)][2] = String.valueOf(Integer.parseInt(rev_task[rdList.get(i)][2])+1);
                    }
                }
            }
        }

        //记录被分配的任务数
        for(int i=0;i<rev_num;i++){
            rev_task[i][1] = String.valueOf(Integer.parseInt(rev_task[i][1])+Integer.parseInt(rev_task[i][2]));
        }
    }
}
算法测试类-TestAlgorithm.java
package com.yushen.allocationAlgorithm;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

public class TestAlgorithm {

	public static void main(String[] args) {
		
	    Scanner sc=new Scanner(System.in);
	    System.out.println("请输入任务数:");
	    int task_num = sc.nextInt();
	    System.out.println("请输入审核人员的当前未完成任务数组,整数数字输入时用英文逗号隔开:");
	    String inputString=sc.next().toString();
	    String stringArray[]=inputString.split(",");
	    
	    int rev_num = stringArray.length;//审核人员总数
	    String[][] rev_task =new String[rev_num][3];
	    Random rd = new Random();
	    List<Integer> rdList = new ArrayList<>();
	    rdList.removeAll(rdList);
	    int temp;
	    while(rdList.size() < (rev_num+1)){
	    	temp = rd.nextInt(100);
                if(!rdList.contains(temp)){
		    rdList.add(temp);
                }  
            }
	    
	    System.out.println("算法前的任务分配:");
	    for(int i=0;i<rev_num;i++){
	    	rev_task[i][0] = String.valueOf(rdList.get(i) + 1);
	    	rev_task[i][1]= stringArray[i];
	    	rev_task[i][2] = "0";
	    	System.out.print(rev_task[i][0]+","+rev_task[i][1]+" ");
	    }
	    System.out.println();
	     
            AlgorithmUtils.taskAllocation(task_num, rev_num, rev_task);//调用算法工具类
            System.out.println("算法后的任务分配:");    
            for(int i=0;i<rev_num;i++){    
                System.out.print(rev_task[i][0]+","+rev_task[i][1]+" ");  
            } 
        }
}
运行结果:
请输入任务数:
20
请输入审核人员的当前未完成任务数组,整数数字输入时用英文逗号隔开:
1,4,3,5,2,7,2,1
算法前的任务分配:
72,1 63,4 73,3 49,5 74,2 43,7 100,2 20,1 
算法后的任务分配:
72,5 63,5 73,5 49,6 74,5 43,7 100,6 20,6

由运行结果可知,20个任务均衡的分配给了每个审核人员,达到了平均分配的目的!
本人才疏学浅,如有疏漏,请各位大虾不吝赐教!

  • 14
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
### 回答1: 基于蒙特卡洛算法实现无人机任务分配模型是一种基于概率和随机性的方法。该模型通过模拟大量随机样本来评估不同任务分配方案的效果,并选择效果最佳的方案进行无人机任务分配。 在使用蒙特卡洛算法实现无人机任务分配模型时,可以考虑以下步骤: 1. 定义问题:确定无人机任务的目标和约束条件,例如任务数量、任务要求、无人机数量等。 2. 确定决策变量:将无人机任务分配问题转化为数学模型,确定决策变量,例如无人机与任务的配对情况。 3. 构建目标函数:根据无人机任务的目标,构建目标函数,例如最小化任务执行时间、最大化任务完成质量等。 4. 确定约束条件:确定无人机任务分配的约束条件,例如无人机的能力限制、任务的紧急程度等。 5. 实施蒙特卡洛模拟:根据定义好的问题、决策变量、目标函数和约束条件进行蒙特卡洛模拟。模拟过程中,随机生成多个样本,每个样本对应一种无人机任务分配方案。 6. 评估样本结果:根据目标函数和约束条件,评估每个样本的优劣。 7. 选择最佳方案:根据评估结果,选择效果最佳的无人机任务分配方案作为最终结果。 通过上述步骤,基于蒙特卡洛算法实现的无人机任务分配模型能够在考虑随机性的情况下,找到最佳的任务分配方案。为了实现该模型,可以使用MATLAB编程语言进行实现,通过编写代码来模拟和评估多个样本,并选择最佳方案。在MATLAB中,可以利用随机数生成函数来生成样本数据,并结合优化算法来求解目标函数最优解,从而实现无人机任务分配模型的蒙特卡洛算法实现。 ### 回答2: 基于蒙特卡洛算法实现无人机任务分配模型的核心思想是通过随机采样来模拟大量可能的任务分配方案,并通过统计分析找到最优解。 以下是基于matlab实现无人机任务分配模型的简述: 首先,我们需要定义任务的属性,例如任务数量、任务位置和任务的紧急程度等。然后,我们需要确定无人机的属性,如无人机数量、无人机速度和无人机的最大航程等。接着,我们可以使用蒙特卡洛方法生成一系列可能的任务分配方案。 在每次迭代中,我们随机分配无人机到任务,并计算任务完成的总时间。然后,我们可以根据分配方案的效果,调整无人机的分配策略。例如,可以增加无人机的数量,优化无人机的路径规划算法等。 通过多次迭代,我们可以收集足够的数据来进行统计分析。我们可以计算每个任务被分配到的次数,以及任务完成时间的平均值和标准差等。通过分析这些数据,我们可以找到最优的任务分配方案。 在matlab中,我们可以使用随机数生成函数`rand`来生成随机的任务和无人机分配。然后,我们可以使用循环结构来进行多次迭代,并记录每次迭代中任务完成时间的数据。最后,我们可以使用统计分析函数来计算任务的分配概率和任务完成时间的统计特征。 以上是基于蒙特卡洛算法实现无人机任务分配模型的简要描述,具体的实现需要根据具体需求进行调整和优化。 ### 回答3: 基于蒙特卡洛算法的无人机任务分配模型,旨在利用蒙特卡洛模拟技术来优化无人机的任务分配策略。该模型的实现可以通过以下步骤进行: 1. 确定任务和无人机的特征参数,包括任务的位置、时间要求、价值等信息,以及无人机的速度、航程、载荷容量等参数。 2. 建立数学模型,利用蒙特卡洛模拟技术来生成随机的任务需求和无人机状态。通过设定任务需求和无人机的状态分布,可以使用随机数生成算法来模拟这些分布,并生成大量的随机样本。 3. 根据生成的任务需求和无人机状态样本,利用蒙特卡洛算法生成一系列可能的任务分配方案。蒙特卡洛算法通过不断随机抽样,并对每个样本进行模拟和评估来得出最佳方案。 4. 利用评价函数对每个任务分配方案进行评估,该评价函数可包括对任务完成时间、总体效益、成本等方面的考虑。 5. 选择评估得分最高的任务分配方案作为最佳方案,并用MATLAB进行实现和验证。MATLAB是一种强大的数值计算和数学建模软件,其功能丰富的编程语言和工具箱可以用于实现蒙特卡洛算法以及评估和优化算法。 6. 利用MATLAB中的随机数生成函数、模拟函数、评估函数等功能来实现蒙特卡洛算法的模拟和评估过程。可以通过编写MATLAB脚本来自动化任务分配过程,并进行多次模拟以获得更准确的结果。 7. 最后,根据模拟结果来优化无人机的任务分配策略。根据蒙特卡洛模拟的结果,可以对无人机任务分配模型进行调整和改进,以优化任务完成时间、效益等指标。 综上所述,基于蒙特卡洛算法的无人机任务分配模型可以通过以上步骤在MATLAB中实现,并可以根据模拟结果进行优化和改进。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值