添加或删除单元时,如何保持矩形形状?


18

我有带有行和列的矩形形式的机器人。在从地层中添加或删除机器人时会出现问题。发生这种情况时,漫游器必须重新布置自己,以使矩形形状的纵横比仍大致相同,并尽可能地为矩形。这该怎么做?

一些想法:

  • 添加或删除机器人时,请使用新的机器人总数和所需的恒定长宽比来计算最适合该长宽比的地层的新宽度和高度。然后以某种方式重新调整机器人以适应新的尺寸。

  • 移除机器人后,将其后面的机器人移到其位置,然后继续直到到达编队的尽头。然后通过以某种方式改组后排机器人来尽可能地使后排保持平衡。

  • 另一个完全不同的想法是模仿分子结构保持在一起的方式。通过吸引四个最接近的机器人,然后排斥其余所有机器人,使每个机器人都希望被其他四个机器人包围。击退所有机器人(包括四个机器人),它们太近以至于无法使用平方反比法确保分离。您还需要额外的力来塑造整个结构。但是,这听起来非常昂贵。

更新:因此,研究萨拉赫姆的答案,我想出了一个很好的通用函数,它给出了良好的尺寸。

首先,我解决了下面的宽度和高度联立方程,然后对答案进行了四舍五入。

width/height=aspect ratio of your choice
width*height=number of bots

这为您的机器人数量提供了最接近该纵横比的整数矩形。最接近的矩形一半时间太大,一半时间太小(当然,有时会恰到好处,但谁在乎那些矩形)。在矩形是一个案件有点过大,需要做什么需求。后排最终将几乎满,这是理想的。在矩形是一个案件有点太小了,你有问题,因为极小的微小溢出将不得不去到它自己的等级创建了一个等级上它只有几个机器人,它并不十分好看。在某些情况下,差异也很大(大于宽度的一半),在这种情况下,相加或减去一级即可使差异变小。然后,当矩形太小时,添加一列以使其稍大一点。这样做之后,看起来后排机器人将始终至少具有其他排机器人的一半

更新

获得尺寸后,将其与当前尺寸进行比较。如果新维度的边界较大,则对于每个等级,从下面的等级弹出bot,并将它们推入当前等级,直到该等级上的bot数量等于正面。继续执行该算法,直到获得第二名。使用此算法,机器人将可以有效地适应新的维度。在那之后,我只是将新旧的推到后排。对于新的门面较小的情况,该算法略有不同,但是您可以弄清楚!

接下来还有两个问题。删除,以及一种更灵活的添加方法,其中不必将新漫游器分配给后排,而是在添加新漫游器时最接近它们的位置。


一个单元中最大的机器人数量是多少?如果相对较小,则可以硬编码一定数量的机器人形成的行数和列数。
2013年

3
您能否发布有效或无效的编队图像?我在理解您的要求时遇到了一些麻烦。是否允许使用不完整的行/列?
MichaelHouse

3
您确实意识到这不适用于素数吗?例如,如果有7个机器人,则您必须制作一个3x2的单元,背面要有一个机器人。
2013年

1
好吧,这很尴尬。我完全忘记了质数。然后,也许下一个最好的事情就是只允许ALMOST填充的行和列。连续一个机器人看起来不正确,但是连续一个机器人看起来并不糟糕。
Tiby312

3
质数不是唯一会引起麻烦的数-通过分解来选择地层大小可能会给您不合理的长而窄的地层。例如,如果您有14个漫游器,则唯一的理想矩形形式是7x2,而具有3x4排列并多排2个漫游器看起来会更好
内森·里德

Answers:


16

另一种技术是模仿拿破仑营所使用的技术(如果可能的话,甚至可以追溯到希腊方阵)。

正面通常保持恒定,并且当一个人跌倒时(除后排以外的任何等级),他都被直接在他身后的人代替。NCO对后排进行了改组,以确保每个侧面的末端都有几个人,否则将平均填补。

仅当后排等级低于预定密度时,正面才会减少。同样,当后排人员过多时,临时演员会先从两个侧翼开始填补其他人员,然后增加正面。

更改正面时,我建议您在增加正面时将您的机器人从后排移到两个侧面,而在减小正面时从两个侧面移入到后排。

如果我能正确地推断出您正在寻找一种“军事”印象,并使您的机器人组织看起来像方阵,我相信这种有序的重新安排是实现此目标的更好方法。

更新
管理后排的一种简单方法是将后排部队分为三个小队:每个后排一个,中间一个。根据正面是奇数还是偶数,以及后排单元的数量是否等于0、1、2或3 mod 3,有六种情况需要处理。

作为对上述内容的增强,请考虑在填充低于阈值时,将每个后排小队的最后一个(或多个)单元隔开,如下所示:
xxx.x .... x.xxx.x .... x。 xxx
或以下
格式:xx.xx..x.xxx.x ... xxxx
需要做更多的工作,以获得更好的外观。

更新#2
关于地层深度的其他思考。在18世纪末和19世纪初,齐射火的影响加上现代的刺刀使3或4英尺的深度足够了。(与流行的看法相反,英国人很少在战斗中进行两次战斗,直到最后一战;因为一次战斗,他们的战线过长而无法迅速形成方阵。)在此之前,通常情况下,战斗机的纵深要多一些,最多可达8级。或配备Sarissa的希腊方阵为10。选择可产生所需印象的深度。

现实生活中的军队试图以尽可能长的时间维持部队的正面,以增加部队的脆性为代价,因为这使布置战场变得更加简单。凯撒(Pharsalus)的凯撒(Caesar)刻意减小单位深度,以增加与庞培(Pompey)部队相匹配的阵线。俗话说:“我们今天赢或死;庞培的男人还有其他选择。” (当然,凯撒巧妙而谨慎地保证了这一点)。


听起来这是一种更为优雅的解决方案。根本无需大意素数或长宽比,但是它仍然避免了其中机器人数量异常少的任何行,唯一需要检查的条件是后备等级有多高!
Tiby312

但是等一下。假设后排只有3个漫游器,分别位于第1、2和3列。我从第5列中删除了靠近前排的某个人。我最终在第5列的倒数第二行中获得了一个空位,而后面没有任何机器人可以取代它。谁来填补这个位置?
Tiby312

大概,排名靠后的机器人(即第3列中的机器人)应该运行以填补它。或者,您可以通过将倒数第二个机器人的第3列和第4列中的机器人向上移动每一列,将间隙移至第3列,然后让第3列中的机器人向前填充来节省一些时间它。(IMO,最“自然”的看似策略可能是两者的某种启发式组合,可能还带有一些随机性。)
Ilmari Karonen13年

1
如果后面排名太少成员(说其他队伍的不足50%),并且增加了正面,这是保证来解决这个问题,或者是有可能,后面排名将仍然有增大后太少成员需要重复的正面或类似的东西?
Tiby312

1
@ Tiby312:我相信你想得太多。试一试,知道您以后可以随时对其进行调整
Pieter Geerkens 2013年

7

假设一个单位是机器人的线性数据结构(例如list)。

首先,您必须在数据结构中添加机器人或从数据结构中删除机器人,并确定单元中新的机器人数量。

然后,您必须使用https://en.wikipedia.org/wiki/Integer_factorization确定新的行数和列数。

当然,由于质数,这并不总是可能的。当新的单位大小是质数时,您需要使用下一个更大的单位大小,而不是。

然后,只需遍历数据结构,就可以为行和列分配漫游器。

要放置机器人,只需在数据结构上进行迭代,然后为每个机器人分配一个与单位位置的偏移量,该偏移量由机器人所在的行和列确定(或者将该点设置为机器人移动的目标)。

为了使一个单元的中心位于一个角,机器人的位置由下式给出:

unitPosition + 标题 * columnNumber * botSeparationDistance + rightVector * rowNumber * botSeparationDistance

为了使单元居中,将机器人的位置由下式给出

unitPosition + 标题 *(columnNumber * unitSeparationDistance-0.5 *(numberOfColumns * botSeparationDistance)+ rightVector * rowNumber * botSeparationDistance-0.5 *(numberOfRows * botSeparationDistance)

其中heading是指向单位面向的方向的矢量,rightVector是与heading正交的矢量。

可以对botSeparationDistance进行调整,以使bot更远或更近地站立。

如果你感到花哨,可以抵消机器人的最后一排rightVector * 0.5 *(numberOfColumns - actualNumberOfBotsInRow)到中心他们上形成


这与我要寻找的非常接近!我唯一的保留意见是,在分配新位置时,可能会将一行的最右边的Bot分配给新矩形中下一行的最左边,从而导致Bot行程很长,并且在处理过程中阻碍其他机器人尝试达到自己的新分配位置。我担心当机器人被添加或删除时,由于Bots忙碌地奔向他们的遥远目的地,整个队伍将变得一团糟。
Tiby312

2
您总是可以计算出新位置,然后将最近的机器人移到该位置,而不是进行线性迭代。
Exilyth

如何在不结束平方计算的情况下做到这一点?如果我正确理解的话,我必须为每个Bot在2d数组中找到与2d数组中当前位置最接近的位置。
Tiby312

在每次迭代中,将分配一个单位(因此,在后续迭代中无需考虑),因此运行时间将为O(n!)。哪一个还不是很好。再说一次,构建[选择的优化结构]并执行n个范围查询也不是一件容易的事。我现在唯一能想到的就是将最后一个机器人移到后面,或者将最后一个机器人从后面塞满。
2013年

这个怎么样。假设新阵型的行大小较小。然后在每一行上,您都有一个额外的机器人。您将该机器人指定为下一个,左分配一个。然后在下一行中,您有两个没有位置的Bot。您将这两个分配为下,左分配一个。然后,您获得了3个没有地方的机器人。继续直到您在底部多了一行。我只是在这里吐球。我并不认为它会一直存在,但听起来像它会工作并且很快。
Tiby312

2

我会将可能的位置存储在图形中,较大的值是较小的矩形。

[4][3][2][1]
[3][3][2][1]
[2][2][2][1]
[1][1][1][1]

每次移除一个机器人时,都会搜索所有其他机器人,并在节点中找到值最小的一个。使用A *或BST算法查找从最小值到空闲空间的路径。如果没有一个机器人的值小于被移除的机器人,则不执行任何操作。

您还应该能够控制矩形的衰减方式。例如,在下图中,当机器人从侧面离开底部时,它将占据其位置。

[4.9][3.8][2.7][1.0]
[4.8][3.7][2.6][1.0]
[3.9][3.6][2.5][1.0]
[3.5][3.4][2.4][1.0]
[2.9][2.8][2.3][1.0]
[2.0][2.1][2.2][1.0]
[1.9][1.8][1.7][1.0]
[1.6][1.5][1.4][1.0]

此处删除了3.8处的一个,因此2.5处的一个出现并填充了它的位置。

[o][x][o][ ]
[o][o][o][ ]
[o][o][r][ ]
[o][o][ ][ ]
[o][o][ ][ ]
[ ][ ][ ][ ]
[ ][ ][ ][ ]
[ ][ ][ ][ ]

另一个例子。这里2.8被删除,因此最小的节点2.2填充了它的位置。

[o][o][o][ ]
[o][o][o][ ]
[o][o][o][ ]
[o][o][o][ ]
[o][x][r][ ]
[ ][ ][ ][ ]
[ ][ ][ ][ ]
[ ][ ][ ][ ]

您可能想要一个值永远为0的节点环,这些环永远不会在外部填充,以便您的寻路算法找到孔。

[0.0][0.0][0.0][0.0][0.0][0.0]
[0.0][4.9][3.8][2.7][1.0][0.0]
[0.0][4.8][3.7][2.6][1.0][0.0]
[0.0][3.9][3.6][2.5][1.0][0.0]
[0.0][3.5][3.4][2.4][1.0][0.0]
[0.0][2.9][2.8][2.3][1.0][0.0]
[0.0][2.0][2.1][2.2][1.0][0.0]
[0.0][1.9][1.8][1.7][1.0][0.0]
[0.0][1.6][1.5][1.4][1.0][0.0]
[0.0][0.0][0.0][0.0][0.0][0.0]

这里可以找到有关A *的很好的教程。


这是一个不错的主意,但是如果我正确理解这一点,则可以允许使用的形状不完美的矩形。边框上的行和列可能不完整。我当时想我可以做到,这样它总是有一个矩形边框,而是通过更改行数和列数来稍微改变长宽比以满足此要求。我已经可以计算出可以完成此操作的新宽度和高度,但是接下来有一些复杂的方法可以将Bot重新分配到最近的Spot ..我认为。
Tiby312

@ Tiby312您打算如何制作一个完美的矩形,例如... 7个机器人?
ClassicThunder13年

没关系,我忘了素数。抱歉。但是我仍然认为,调整行数和列数可以避免行或列的Bot数量异常少。
Tiby312

@ Tiby312我认为,相对于始终使之成为一个完美的矩形,您最好始终保持一致的宽高比(即始终为4:3或8:5)。
corsiKa
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.