Algorithm 循环分配的再平衡算法

Algorithm 循环分配的再平衡算法,algorithm,round-robin,Algorithm,Round Robin,我有一个具有以下属性的系统: 有些工人在工作。可以添加或删除工人。每个工人可以同时运行多个作业 有工作。这些作业将永远运行(无限期),并分配给工人。可以添加或删除作业 我正在使用循环分配工作给工人在启动和这项工作相当好 但是,我希望在添加和删除工人以及添加和删除工作时重新平衡分配给工人的工作 虽然在发生上述任何更改时,可以使用循环算法重新分配所有内容,但它所做的更改将超过所需的数量 换句话说,是否有任何循环再平衡算法会导致分配差异/变化最小?我假设,您的循环方法以以下方式分配作业: W1 W

我有一个具有以下属性的系统:

  • 有些工人在工作。可以添加或删除工人。每个工人可以同时运行多个作业

  • 有工作。这些作业将永远运行(无限期),并分配给工人。可以添加或删除作业

  • 我正在使用循环分配工作给工人在启动和这项工作相当好

    但是,我希望在添加和删除工人以及添加和删除工作时重新平衡分配给工人的工作

    虽然在发生上述任何更改时,可以使用循环算法重新分配所有内容,但它所做的更改将超过所需的数量


    换句话说,是否有任何循环再平衡算法会导致分配差异/变化最小?

    我假设,您的循环方法以以下方式分配作业:

    W1   W2   W3   W4
    -----------------
    J1   J2   J3   J4
    J5   J6   J7   J8
    J9
    
    添加新作业非常简单。您只需记住分配了上一个作业的工作人员(循环算法的状态,在下文中称为“最后一个工作人员”),然后将新作业分配给下一个工作人员。增加最后一个工人

    W1   W2   W3   W4   W5
    ----------------------
    J1   J2   J3   J4   J8
    J5   J6   J9
    
    如果要删除作业(如上例中的
    J7
    ),请执行以下操作:首先,删除作业:

    W1   W2   W3   W4
    -----------------
    J1   J2   J3   J4
    J5   J6        J8
    J9
    
    然后选择最后一个工作人员的最后一个工作,并将其重新分配给失去工作的工作人员(除非已擦除的工作是最后一个工作):

    减少最后一个工人

    如果要添加工作人员,请执行以下操作:选择最后一个工作人员的最后一个作业并将其分配给新工作人员,直到新工作人员的作业数等于或小于第一个工作人员的作业数

    W1   W2   W3   W4   W5
    ----------------------
    J1   J2   J3   J4   J8
    J5   J6   J9
    
    相应地更新最后一个工作进程

    如果您已经具备了上述所有功能,那么删除一个工人是非常简单的:只需获取其所有作业,然后一次添加一个即可。例如,如果删除
    W2

    W1   W3   W4   W5
    ----------------------
    J1   J3   J4   J8
    J5   J9   J2   J6
    

    根据数据的大小,您应该使用适当的数据结构来提高效率。但是我相信你知道应该使用什么结构。

    减少或优化工作变动的数量:

    创建成对(
    worker
    numOfJobsAssigned
    )的列表(例如,
    worker
    ),并分别维护当前变量
    maxJobsToAnySingleWorker

    达到平衡状态后(即所有
    工人
    拥有相同数量的工作),将
    maxJobsToAnySingleWorker
    增加1,然后添加新工作

    Start with maxJobsToAnySingleWorker = 0
    
    For addition of a Job:
        Set Done to false
        for each worker in workers 
            if numOfJobsAssigned < maxJobsToAnySingleWorker
                Increase worker.numOfJobsAssigned by 1
                Set Done to true
                break
        if Done is false (equilibrium state)
            increase maxJobsToAnySingleWorker by 1
            Increase FirstWorker.numOfJobsAssigned by 1
    
    
    For removal of a Job from a worker, say myWorker:
        Done = false
        Remove Job
        if myWorker.numOfJobsAssigned == maxJobsToAnySingleWorker-1
             Do nothing
        else
            for each worker in workers 
                if (numOfJobsAssigned > 1) and (numOfJobsAssigned == maxJobsToAnySingleWorker)
                    Delegate Job from worker to myWorker
                    Decrease worker.numOfJobsAssigned by 1
                    Done = true
                    break
            if worker is lastWorkerInList
                Decrease maxJobsToAnySingleWorker by 1
    
    以maxJobsToAnySingleWorker=0开始
    要添加作业,请执行以下操作:
    将Done设置为false
    工人中的每个工人
    如果numOfJobsSigned1)和(numOfJobsSigned==maxJobsToAnySingleWorker)
    将工作从worker委派给myWorker
    将worker.numOfJobsAssigned减少1
    完成=正确
    打破
    如果worker是LastWorkerList
    将maxJobsToAnySingleWorker减少1
    

    按照上述逻辑,可以通过一个接一个地从离开工人中移除一份工作+将一份工作添加到留下的工人中来完成工人的移除。

    一个工人如何能够同时在多个工作上工作?在你的描述中还有一个隐含的假设,即一个工人可以中断他的工作,而另一个工人可以恢复这个中断的工作。这是一个已经解决的问题,还是您希望问题的答案能够解决这个问题?一个工人可以同时从事多个工作,因为每个工作都是按常规启动的。换句话说,每个作业都可以看作一个线程(尽管go例程不是线程)。这项工作相对简单:将数据库中的消息推送到消息总线中,因此将一项工作切换到另一个工作人员是很简单的。一项工作可以同时分配给多个工作人员吗?@SauravSahu否。每个工作只能分配给一个工作人员。在某些情况下,您的解决方案不是很理想,从某种意义上说,可以通过更少的工作调动来保持同样良好的平衡。例如,在从
    W3
    中删除作业
    J7
    后,如上面的示例所示,接下来让我们从
    W2
    中删除
    J6
    。您的算法现在将作业
    J8
    W4
    转移到
    W2
    以保持平衡,而将作业分配保持原样(就所需转移的数量而言)将更有效,而不是重新排序工人,以便将
    W2
    移动到工人列表的末尾。在第一种情况下,假设我们有多达
    J7
    个作业(没有
    J8
    J9
    ),然后
    J6
    被删除。那么你不认为把
    J7
    移动到
    W2
    会有不必要的开销吗?你们都是对的。我并不是说这是一个完美的解决方案。合并工人重新排序应该非常容易(例如,将当前工人的工作数量与第一个工人的工作数量进行比较)。不过,批量插入和删除是一个完全不同的故事。