繁体   English   中英

寻求资源分配算法

[英]Resource Allocation Algorithm Sought

对于我的一个项目(不,不是一项家庭作业或考试问题,尽管我认为这会做得很好),但我需要一种算法。 这个问题看起来足够熟悉和笼统,以至于我很确信它已经在文献中得到了解决,但是我手头上没有算法书,也不清楚用什么术语来描述它,因此使用谷歌搜索是有限的。

除去多余的细节,问题如下:为您提供了一组资源{R_1,R_2,... R_n}和一组任务{T_1,T_2,... T_m}。 可以使用资源替代集TR_m = {{R_1m1,R_1m2,...},{R2m1,R_2m2,...},...}中的任何一个来完成每个任务。 每个资源一次只能由一个任务使用。 问题在于查看是否可以同时完成所有任务,或者,如果不可能,则可以同时完成最大数量的任务(从T_1开始)。

仅仅为每个任务分配第一组可用资源的幼稚算法有时会不必要地失败:考虑TR_1 = {{R_1,R_2},{R_1}}和TR_2 = {{R_1},{R_2}}。 T_1会抓住R_1,R_2和T_2会失败,而TR_1可能刚刚抓住R_1,TR_2可能已经抓住R_2。

我正在寻找一种算法,最好是优雅且简单的算法,它将做得更好。

就其重要性而言,资源主要由可互换的子集组成,并且任务通常只需要每个集合中的一个或多个资源,因此幼稚算法通常会成功,但并非总是如此。

而且,通常任务和资源少于十个,并且问题(当前在Python 3中编码)不是实时的,因此蛮​​力通常是可以接受的解决方案,但我正在寻找更好的解决方案。

有什么建议或链接吗?

假设所有任务都相同。

那么您的问题等同于已知的NP-完全最大集包装问题

因此,您的问题当然是NP难题,您不太可能为此找到完美的算法。

使用可以使用Branch和Bound

您可能会分支到“对于任务i ,我该选择哪个集合?”,首先选择最大的集合以使树中的故障尽可能多地发生,以节省工作量。 对于初始解决方案,您可以将其翻转以快速找到一个合理的(但不是最佳的)解决方案,最终可以通过稍后在实际搜索中进行更多的修剪来节省工作。

您还可以在以下模型的s[q,t]上分支,该模型最接近0.5(以某种方式“最不肯定”的选择)。

边界可以基于此ILP模型的线性松弛:

maximize sum of x[t] over all t

variables:
0 <= x[t] <= 1  ; x[t] decides whether task t is scheduled or not
0 <= r[i,t] <= 1 ; r[i,t] decides whether task t uses resource i
0 <= s[q,t] <= 1 ; s[q,t] decides whether set q of task t is used

constraints:
1. for all tasks t: (sum s[q,t] over all valid q) - x[t] = 0
2. for all sets s[q,t]: (sum r[i,t] over all i in the set) - size_of_set * s[q,t] >= 0
3. for all resources i: sum r[i,t] over all t <= 1
  1. 强制恰好有一组资源与所选任务相关联。
  2. 强制通过选择任务t的集合q使用的资源由​​任务t使用(> = 0,因为集合可能重叠)
  3. 强制不超过一次使用所有资源。

我可能在模型中犯了错误,但不确定其性能如何。 无论如何,可以使用线性编程来解决它(毫无疑问,有一个适用于Python的库),然后进行几次Gomory切割以取得良好的效果(它们看起来很吓人,但它们实际上很简单),虽然不是很多,仅使用Gomory割线来尝试获得全整数的解决方案通常会非常缓慢地收敛。 做其中一些是改进解决方案的廉价方法。

这将为您提供一个估计值,使您可以修剪一些搜索空间。 它实际修剪的量取决于它与实际解决方案的距离。 我预测它将倾向于选择一个因数介于0和1之间的任务的多个集合,因为选择一个“仅一点”的集合就可以将相同的资源用于多个任务。 然后,它必须选择多个集合,因为每个任务必须总共使用1个集合,但这也意味着它拥有更多的资源选择,因此可以做到这一点。 从某种意义上说,线性编程是一种偷偷摸摸的方法,从某种意义上说,它总是想给你最讨厌的答案

当然,在此模型中,您将排除不再可能的任何可能性(已分配的资源和包含这些资源的集合以及可能具有零个可能集合的任务),并跳过已安排的任务。

如果这太复杂,则可以这样计算出一个更简单的界限:对于所有任务t ,取其最小集合s[t]的大小。 检查直到总大小大于未分配资源的数量为止可以使用的数量(因此,请选择最小的资源,再添加下一个最小的资源,依此类推-对它们进行排序或使用最小堆)。

当然,如果到目前为止已经分配了资源,那么那么多任务现在都没有任何可能的总和(包括已经安排好的任务),那么到目前为止您将无法获得最好的解决方案,而您可以放弃当前的最佳解决方案。递归树的分支。

对于最初的解决方案,您可以尝试使用所描述的贪婪算法,但要进行一次更改:采用仅包含未分配资源的最小集合。 通过这种方式,它试图“避开”其他任务,尽管显然您可以构造出比选择第一个可能的情况差的情况。

编辑:当然,如果某个任务的集合中有一个集合是该集合中另一个集合的超集,则只需删除它即可。 使用该超集再好不过了。 碰巧可以修复OP中给出的示例,但通常不会。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM