桌子/座位分配算法
本文关键字:分配 算法 桌子 | 更新日期: 2023-09-27 18:28:21
我目前正在开发一个预订系统,需要一种算法来根据一些条件和预定义值将公司参与者分配到座位。
条件是:
- 每个不同的公司必须至少有两名参与者坐在同一张桌子上。(假设该公司至少有2名参与者)
- 公司已经确定了竞争对手。公司不能与竞争对手坐在同一张桌子上
预定义值为:
- 桌子和座位是预定义的
- 预先定义了公司参与者和竞争对手关系
实体定义:
表格:ID(Int,PK),描述(字符串),数字(Int),
桌座:ID(Int,PK),数字(Int),TableID(FK),CustomerID(Nullable Int,FK)
公司:ID(PK)名称(字符串)默认参与者数量(Int)竞争对手ID(FK)
竞争对手:ID(PK)公司ID(FK)公司ID2(FK)
因此,例如,如果我定义了以下预设:
表格:
- 表1有6个座位
- 表2有4个座位
- 表3有6个座位
- 表4有3个座位
公司/参与者:
- 公司1有3个参与者,没有竞争对手
- 公司2有2名参与者,公司3是竞争对手
- 公司3有4名参与者,公司2是竞争对手
我需要自动分配总共9名参与者,来自3家公司,总共4张桌子上的19个座位。根据条件,第2公司和第3公司的参与者不能坐在同一张桌子上。此外,当参与者坐在桌子旁时,(如果可能的话)应该有一位同伴陪同。
任何关于合适算法的想法或指针都将受到极大的赞赏。谢谢
您可以尝试此算法的以下变体:将玩家分配到表
同样,总体思路是依次处理每张桌子上的每个座位,随机安排一个剩余的有效人员。如果没有这样的人,算法就会终止,没有结果(这就是所谓的拉斯维加斯算法)。
根据有多少有效的解决方案,在找到解决方案之前,你可能需要运行算法100次,但这没关系,因为一次运行很快:我估计,就你给出的例子而言,你应该在不到一秒钟的时间内找到结果,至少比彻底搜索所有可能的排列要快得多。
不允许两名竞争对手在同一张桌子上的条件可以很容易地强制执行:当选择下一个坐在桌子旁的人,只需排除已经坐在那张桌子上的所有人的竞争对手。
另一个条件是,一个人最好与至少一位同事坐在一起,这更难做到正确。它仍然可以作为一个硬约束来实现,但我怀疑可能有相当多的情况不会产生任何结果
因此,我建议将这一条件设为"软约束",最初完全忽略这一条件,但之后对每一个结果进行评估,对每个没有与同事坐在一起的人给予罚分。
这保证了即使在不是每个人都能和同事坐在一起的情况下,你仍然能得到一个可以接受的座位。
然后算法变为:
//Place everyone at a table while avoiding seating competitors together
for each table T:
UP = a randomly shuffled list of unseated people
for each person X from UP
While there still is at least one seat available at T AND
X is not a competitor of anyone already seated at T
seat X at T
if T still has one or more seats available
abort; //With the decisions taken so far, noone can be seated at T. This run has no result.
//Complete seat configuration found. Award a penalty point for evey person not seated with a colleague.
penaltyPoints = 0
for each table T:
for each person X seated at T
If there is no other person at T that is from X's company
Add a penalty point.
运行此算法几次(十万?),并以最少的惩罚次数保持结果点。
我认为这个问题可以归结为图的顶点着色。竞争对手公司的参与者在图中相连。颜色的数量等于表格的数量。还有一个额外的限制,即每个颜色/表都有与其关联的最大节点数
对于同一公司至少有两个人需要坐在同一张桌子上的问题,每当你给一个新节点上色时,忍受同一公司的另一个节点有相同的颜色,否则就试图给同一家公司的另个节点涂上相同的颜色。