只是附加信息:这是我正在进行的游戏项目。
我正在尝试制作一种有效的随机化算法,在给定可用空间的长度的情况下放置多个对象(彼此排列)。
直接问题:给定一个length = lengthOfArea的可用空间,以及要定位的对象数= numObjects,其中每个对象的长度为lengthObject =(lengthOfArea / 2)/ numObjects。 (这样,物体占据的空间总量是可用空间长度的一半)。
我应该寻找每个对象的中心位置并返回它的数组。
这是我目前的尝试:
public int[] FindObjectPositions(int lengthOfArea, int numObjects, Random random)
{
int lengthOfObject = (lengthOfArea / 2) / numObjects;
int[] positionsPicked = new int[numObjects];
int minPosition = lengthObject / 2;
int maxPosition = lengthOfArea - (lengthObject / 2);
for (int i = 0; i < numObjects; i++)
{
int newPosition;
do
{
newPosition = minPosition + random.Next(maxPosition - minPosition);
} while (!IsPositionValid(positionsPicked, newPosition, lengthObject));
positionsPicked[i] = newPosition;
}
return positionsPicked;
}
public bool IsPositionValid(int[] positionsPicked, int newPosition, int lengthObject)
{
for (int i = 0; i < positionsPicked.Length; i++)
{
if (Math.Abs(positionsPicked[i] - newPosition) <= (lengthObject / 2))
return false;
}
return true;
}
基本上我正在做的是我不断地为每个对象随机找到一个有效的位置。我只是想知道它是否效率低下。另外,我想知道我是否会用这种方法陷入僵局?
答案 0 :(得分:1)
如果存在无法容纳更多对象的配置,则可能会死锁。例如,如果有30个空格,并且每个对象的长度为5个空格,则配置
_ _ _ _ x x x x x _ _ _ _ x x x x x _ _ _ _ x x x x x _ _ _
没有可能适合另一个物体的地方,即使有15个空地!
假设有m
个空格,每个对象的宽度为w
。一种不会死锁的方法是生成m-w+1
个数字1, 2, ..., m-w, m-w+1
的列表。然后随机选择一个 - 这将代表对象的最左侧位置。然后删除该数字右侧和左侧的w-1
个数字 - 这表示对象宽w
,宽度为w
的其他对象}将适合它左侧的w-1
个空格。
例如,如果m = 20
和w = 3
,
创建1到18的列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
然后随机选择一个。假设我们选择10.然后空格10,11,12被我们的对象填充,空格8,9不能是另一个对象的最左边位置,所以我们删除了数字8到12。
1 2 3 4 5 6 7 13 14 15 16 17 18
说我们接下来选择18。然后我们删除16-18:
1 2 3 4 5 6 7 13 14 15
依此类推,直到我们没有数字为止。
上面的方法不会死锁,但它有另一个问题:它可能可能配置(比方说)6个对象,但上面的方法可能只生成一个配置其中有4或5个物体,没有任何余地。要解决这个问题,我们可以计算出6个对象应该有多少个空格,而不是为我们的对象选择随机位置,而是选择空格的随机点(使用上面的方法)。
这将为您提供所需的对象数量,随机分布,不会出现死锁。