0

我对 MATLAB 很生疏,我正试图通过自动化一些拉丁方问题来复习。我正在处理的代码如下:

counter=1;
for i=1:10
    for j=1:10
        if A(i,j)=0
            A(i,j)=[This is where I'm stuck];
        end
        counter=counter+1;
    end
end    

我希望这段代码检查值A(i,j)以确定[1,...,n]第 i 行中是否已经存在来自的值,然后从中选择随机值

[1,...,n] excluding [values already present].

基本上我只是想强行完成部分拉丁方块。

编辑:

我不是要生成随机的拉丁方格,而是要生成具有某些属性的方格。例如,假设我们有以下设置:

A=[X,0,0,0,Y,0,0,0,Z]

其中 0,X,Y,Z 都是 3x3 子矩阵,X,Y,Z 的值来自 1,...,9。我正在尝试设计一种自动化方法来完成具有一些值的部分拉丁方格。

4

1 回答 1

0

您描述的方法不够强大,无法每次都生成拉丁方。例如,假设我们正在计算 5x5 正方形的第二行

1 2 3 4 5
2 4 1 3 ?

前 4 列遵守规则,在每列中选择不会导致行/列冲突的随机值。那么最后一个值必须是 5,这是不允许的。您可以添加另一个阶段,该阶段将在冲突中循环并进行交换,但如果不仔细构建,这可能是无穷无尽的!

一个更简单的方法是n用以下形式构造一个“简单”的拉丁方格:

A = [1    2    3    ...    n-1  n
     n    1    2    ...    n-2  n-1
     n-1  n    1    ...    n-3  n-2
     ...  ...  ...  ...    ...  ...
     3    4    5    ...    1    2  
     2    3    4    ...    n    1   ]

1:n每行是每行一个元素置换的向量。这可以在 Matlab 中使用以下方法轻松生成toeplitz

A = toeplitz([1,n:-1:2],1:n);

现在我们有了一个拉丁方格!您可以通过使行排列随机而不是有序来随机化此过程。之后我们可以这样做,并且也可以使用随机索引来置换列randperm

A = A(randperm(n), randperm(n));

请注意,这不会产生所有可能的拉丁方格,因为:

如果一个正方形可以通过排列行、列和符号从另一个中获得,则两个正方形属于同一同位素类别Brendan McKay

看看类之间的跳跃将是另一个层次。n=8 有超过 100 万个类,并且类的数量随着值的增加而迅速爆炸!维基百科


由于n=10 有 9,982,437,658,213,039,871,725,064,756,920,320,000 个拉丁方格(如您的尝试),我认为可以肯定地说,无论是您的蛮力方法还是这种排列方法都不会很快耗尽它们!


披露:此答案基于 gnovice 的评论,值得扩展上下文和链接。

于 2017-05-31T10:20:21.963 回答