桶之间的加权分配没有预见

时间:2016-09-26 16:19:02

标签: algorithm random average distribution weighted

我有N个需要处理传入批量数据的工作人员。每个工作人员都经过配置,以便知道它是X"的工作人员N

每个传入的一批数据都具有随机唯一ID(随机,均匀分布),并且具有不同的大小;处理时间与大小成正比。尺寸可能会有很大差异。

当一批新数据可用时,所有N个工作人员都可以立即看到它,但我只想要一个实际处理它,没有它们之间的协调。现在,每个工人计算ID % N == X,并且它是真的,工人自行分配批次,而其他工人则跳过它。这样可以正常工作,并确保每个工作人员平均处理相同数量的批次。遗憾的是,它没有考虑批量大小,因此一些工作人员可以比其他人更晚完成处理,因为他们可能会自行分配非常大的工作。

如何更改算法,以便每个工作人员以同样考虑批次大小的方式自行分配批次,这样平均而言,每个工作人员将自行分配相同的工作总量(来自不同的批次)?

3 个答案:

答案 0 :(得分:0)

//Using a queue to store the workers
//This way we can dequeue and reenqueue workers when they accept jobs
var _queue = new Queue<Worker>[numOfWorkers];

void Setup() {
  for (int i = 0;i<numOfWorkers -1;i++) {
      _queue.Enqueue(new Worker());
  }
}

//Assigns the job to the next worker in line and puts it at the end of queue
void AcceptJob(Job j) {
    var w = FindNextAvailableWorker();
    w.AssignNewJob(j);
    _queue.Enqueue(_queue.RemoveAt(_queue.PositionOf(w)));
}

//Finds the first free worker or returns the front of queue
Worker FindNextAvailableWorker() {
    var w = _queue.front();

    while (int i=0;i<_queue.length-1<i++) {
        if (_queue[i].isWorking==false){
            w = _queue[i];
            exit loop;
        }  
    }

    return w; 
}

答案 1 :(得分:0)

总体思路:  所有节点为每个节点保留到目前为止所做的工作,这会影响他将得到的工作。它以确定的方式完成,因此所有节点都将得到相同的结果,并且不需要通信。我们仍然做模数但是,工作量较少的节点具有较大的数字范围。

算法:

所有工人都做同样的计算。 每个节点都包含一个数组,其中包含所有节点ID的元素,以及此节点到目前为止完成的工作的父节点,与所有节点的总工作量相比(占总工作量的5%,35%......)我们将此节点称为比例

此数组按(100-nodeProportion)+ 0.001 * Node_ID排序。 当批次到达时,我们做一个HASH模数100并得到一个数字1-100拨打这个数字K.

我们遍历排序的数组并开始减去(100-nodeProportion),直到我们得到零或更少。我们将工作交给该节点。

所有节点执行相同的计算,因此无需说话。

答案 2 :(得分:0)

好的,一些注意事项:

  • 您不希望任何元数据持有者,节点通信等。因此,唯一的好方法是某些功能X = distributor( arguments )
  • 您已经拥有非常简单的X = ID % N类型的功能,但显然大小很重要
  • 函数不能仅依赖于大小S,因为那么相同(大)的大小将被分配给同一个工作者。我们正在寻找类似X = F(S, ID) % N
  • 的内容
  • 函数应该产生统一的结果,因此最终的模运算将提供均匀的负载

最简单的尝试功能

X = hash( ID * S ) % N

一些好的散列函数,乘法ID*S将产生字节数组作为散列的典型输入,相同大小的作业将被均等地分配。试试吧......