让我来描述一下我的项目模块的问题:
我有一个容量为50的房间。
10行5列。
我有6种不同的口味,每种口味都有无限量的元素。
我需要制作一个座位计划,以便附近没有相同味道的人(正面 - 背面 - 对角线)。
我可以用什么算法来解决这个问题?
如果可能,请描述算法的步骤。
答案 0 :(得分:1)
<强>算法强>
对于这个具体的例子,你可以使用贪心算法。迭代行和列,并在每个座位设置任何不会与已经坐着的味道冲突的味道。
<强>证明强>
xxxxxxxxxx
xxxxxxxxxx
xxxo......
..........
..........
x - already seated
o - currently seating
. - empty
让我们说我们一行一行,从左到右依次迭代。当我们正在建造新的座位时,这个地方最多有4个已经坐过的邻居(请看上面的图片)。由于我们有6种口味,因此总会存在一种口味,这与其他口味不同。对于我们制作的每个座位都是如此,我们可以填充所有50个空间。
<强>概括强>
对于一般价值观,这个问题可能相当棘手,我甚至敢说NP难。
答案 1 :(得分:1)
一组很好的算法是graph coloring,特别是顶点着色算法。您需要将椅子视为所有相邻椅子边缘的顶点。
答案 2 :(得分:0)
给定的问题是Constraint Satisfaction Problem。特别是(使用术语here):
C1 := (X[0,0] != X[0,1]); C2 := (X[0,0] != X[1,0]); C3 := (X[0,0] != X[1,1])
等等。我个人建议使用Forward Checking以降低复杂性。
由此产生的算法(没有回滚赋值的简化版本,因为这个特定问题不需要)看起来像这样:
initialize_domains_for_each_variable; // set the 6 available flavours
for(int i = 0; i < 10; i++){
for(int j = 0; j < 5; j++){
seats[i,j].flavour = seats[i,j].possible_flavours[0];
// look ahead and eliminate possible conflicts
remove_this_flavour_from_surrounding_seats_possible_flavours;
}
}
这样做会确保不会产生任何冲突,因为每个座位至少有2种可用口味。我们从左到右,从上到下访问座位,因此对于每个座位,我们必须检查哪个分配与先前完成的分配不冲突。在一般情况下,我们将:
seat[i,j].available_flavours = available_flavours - seat[i-1,j+1].flavour - seat[i-1,j].flavour - seat[i-1,j-1].flavour - seat[i,j-1].flavour
有2个项目。在矩阵的边框中,您将拥有更多可用的风格,因为它可能冲突的项目是2(在左边框的情况下),3(在右边框不在第一行的情况下)或1(在右上角元素的情况下,第一行的右边界。)
请注意,使用上述算法只会使用5种口味(最低限度)。如果你有必要使用6种口味,你将不得不调整算法。