解决存储问题的最佳方法

Sir*_*ing 8 algorithm heuristics

在可能的日子里找到最合适的团队组成。一组n位参与者(k天),一个团队有m个位置。参与者指定他想加入多少天以及他有空的时间。

结果约束:

  1. 参加者参加的活动不得超过他们想要的时间
  2. 参与者不得在没有空的日子里安排。
  3. 算法应尽力包括尽可能多的唯一参与者。
  4. 如果当天的参与者少于m人,则不会安排一天。

我发现自己每周都会为足球队的调度工作手动解决此问题,并且我确定有一种聪明的程序化方法可以解决此问题。目前,我们认为每周只有2天,而同事要写下他们想参加的一天的名字,结果每天都有很多大名单,不可能取悦所有人。

我考虑了一种新方法,其中每个同事都写下自己的名字,每周要玩的时间以及有空的日子,例如以下示例:

Kane 3 1 2 3 4 5
Run Code Online (Sandbox Code Playgroud)

上一行表示,凯恩本周想参加3次比赛,并且周一至周五都可以上班。第一个数字代表比赛天数,第二个数字代表可用天数(1到7,周一至周日)。

参加人数少于m(在我的情况下,m = 12)的日子将无法安排。什么是解决此问题的最佳方法,以便找到一种解决方案,使每个参与者至少参与一次,并考虑他们的愿望(何时玩,玩多少)。

我可以进行编程,我只需要知道要实现哪种算法,并可能对选择进行简短的逻辑解释即可。

结果约束:

  1. 参加者的比赛不得超过他们想要的
  2. 参与者不得在不想参加的日子里安排
  3. 算法应尽力包括尽可能多的参与者。
  4. 如果当天的参与者少于m人,则不会安排一天。

Dav*_*tat 2

日程安排问题可能会变得相当棘手,但实际上你的问题还不错。(好吧,至少在你推出第一个自动化时间表并且人们抱怨它并且你开始添加侧面约束之前。)

\n\n

一天可能有比赛或没有比赛的事实会产生某种非凸性,使这些问题变得困难,但如果 k 很小(例如,k = 7),则很容易通过所有2 k 种可能的日期有匹配。对于这个答案的其余部分,假设我们知道。

\n\n

弄清楚如何将人员分配到特定的比赛可以被表述为最小成本循环问题。我将把它写成一个整数程序,因为在我看来它更容易理解,并且一旦添加了侧面约束,无论如何你都可能会达到整数程序求解器。

\n\n

设 P 为人员集合,M 为匹配集合。对于 P 中的 p 和 M 中的 m,如果 p 愿意在 m 中玩,则令 p ~ m。令 U(p) 为 p 的匹配数的上限。设 D 为每场比赛所需的人数。

\n\n

对于每个 p ~ m,令 x(p, m) 为 0-1 变量,如果 p 参加 m 比赛则为 1,如果 p 不参加 m 比赛则为 0。对于 P 中的所有 p,令 y(p) 为 0-1 变量(直观上,如果 p 至少参加一场比赛,则为 1;如果 p 没有参加任何比赛,则为 0,但请稍等一下)。我们有限制

\n\n
# player doesn\'t play in too many matches\nfor all p in P, sum_{m in M | p ~ m} x(p, m) \xe2\x89\xa4 U(p)\n\n# match has the right number of players\nfor all m in M, sum_{p in P | p ~ m} x(p, m) = D\n\n# y(p) = 1 only if p plays in at least one match\nfor all p in P, y(p) \xe2\x89\xa4 sum_{m in M | p ~ m} x(p, m)\n
Run Code Online (Sandbox Code Playgroud)\n\n

目标是最大化

\n\n
sum_{p in P} y(p)\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意,如果玩家 p 至少参加了一场比赛,我们实际上不会强制 y(p) 为 1。最大化目标为我们解决了这个问题。

\n\n

您可以编写代码以编程方式将给定实例制定为混合整数程序(MIP) 并求解,如下所示。使用 MIP 公式,天空是侧面约束的极限,例如,避免连续几天与某些人比赛,使结果偏向于将至少两场比赛奖励给尽可能多的人,因为尽可能多的人得到了他们的首先,等等,等等

\n