假设你有一个 n x m矩阵。在此矩阵中,您将随机定位四个不同的对象,如 a , b , c , d 。每个都会有很多。
现在什么是最好的算法,以便当它们随机放置时,它们的位置不会发生冲突?
我的方法是:
我只是想知道是否还有其他有效的解决方案。
答案 0 :(得分:1)
如果最终目标是填充棋盘,你可以选择矩阵上的每个空格(选择是随机的)。
要添加空格的选项,请添加第五个选项NO_TYPE。
如果已知出现次数,请尝试以下操作:
创建一个大小为 n X m 的列表(称之为 L ),值为1 .. L 。
对于每个外观,从列表中随机选择(类似pos = rand(L)
的内容,并从列表中删除该值(不要忘记减少 L )。
根据需要多次这样做。
答案 1 :(得分:0)
另一个答案的变体,没有创建额外的结构(并且具有更好的时间复杂度):
假设您有对象a_1,..,a_K(在您的情况下K = 4)并且每个对象必须存在n_k次,其中n_1 + .. + n_K <= n * m。你可以用伪代码填写矩阵:
Initialize X as an empty n*m matrix
Initialize n as a vector of length l with n[l] = n_l
Set N = 0
For i = 1; i <= n; i++
For j = 1; j <= m; j++
Draw t at random uniformly on [0,1]
For l = 1; l <=k; l++
Set x_l = n[l] / (n*m-N)
If (t <= x_l)
Set X[i][j] = a_l
Set n[l] = n[l]-1
Escape the loop on l
Set N = N+1
如果您有许多物品要放置,因为您从不拒绝展示位置,这将比您的方法更好。如果你不这样做,那么你的方法很好。
答案 2 :(得分:0)
如果您的算法可以生成一系列不会在阵列中发生冲突的随机位置,那么您可以轻松生成 a 然后 b <所需的多个位置/ strong>然后 c 然后 d 等。
您可以使用此算法完成此操作:
Generate a random prime number p that is greater than n * m
Generate a random number r in the range [0, n * m)
while(need more numbers)
{
// output a position:
yield x = r % n, y = r / n
// generate the next position:
r = (r + p) % (n * m)
}
位置永远不会重叠,因为p和n * m之间没有共同因素。它将产生Full Cycle超过n * m
有关如何生成随机素数的信息,请参阅此StackOverflow问题:
Generate Random Prime number in C/C++ between 2 limits
如果p是素数,那么它将是n * m
的相对素数另见这个问题: