我目前正在开发一个预订系统,需要一个算法来分配公司参与者的座位,基于一些条件和预定义的值。
条件是:
从每个不同的公司,至少有两个参与者必须放在同一张桌子上。(鉴于公司至少有2名参与者)
公司有竞争对手的定义。公司不能和竞争对手坐在同一张桌子上。
预定义值为:
桌子和座位是预先定义的。
公司参与者和竞争对手关系是预先定义的。
实体定义:
表格:
ID(Int,PK),
描述(字符串)
数字(整数),
餐桌:
id(int,pk)
数字(整数)
表格ID(FK)
CustomerID(可空Int,FK)
公司:
ID(主键)
名称(字符串)
默认参与者数(整数)
竞争对手(FK)
竞争对手:
ID(主键)
公司ID(FK)
公司2(FK)
因此,例如,如果我定义了以下预设:
桌子:
表1有6个座位
表2有4个座位
表3有6个座位
表4有3个座位
公司/参与者:
公司1有3个参与者,没有竞争对手
公司2有2个参与者,公司3是竞争对手
公司3有4个参与者,公司2是竞争对手
我需要自动分配总共9名参与者,从3家公司共分配到4张桌子上的19个座位。根据条件,公司2和公司3的参与者不能坐在同一张桌子上此外,当参与者坐在桌子旁时,应(如有可能)由公司的其他参与者陪同。
任何关于合适算法的想法或指针都会非常感激。谢谢。
最佳答案
您可以尝试此算法的以下变体:Distributing players to tables
总的想法是依次处理每一张桌子上的每个座位,让一个随机剩余的有效的人就座如果没有这样的人可用,算法将终止,没有结果(使其成为所谓的Las Vegas算法)。
根据有多少个有效的解决方案,在找到解决方案之前,您可能需要运行算法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.
运行这个算法几百次?一千?)以最少的惩罚次数保存结果
点。
关于c# - 餐 table /座位分配算法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26651271/