【问题标题】:Is there a way to generate random square matrixes until there is one that is symmetric? (C)有没有一种方法可以生成随机方阵,直到有一个对称方阵? (C)
【发布时间】:2020-08-19 16:19:38
【问题描述】:

我需要做的是在内部创建一个 3>=n>=8 行和列的随机矩阵,程序应该这样做,直到找到一个对角对称的,然后打印它,随机数必须是从 0 到 7,并且应该有一个功能,可以将变量形式从 true 更改为 false,您可以选择打印或不打印不对称的矩阵。我已经能够创建随机矩阵,直到它是对称的,但仅限于 3x3,上面的任何数字都会让我的电脑永远在思考,我确定必须有更有效的方法来做到这一点,但我不太擅长 c 这里的代码 ive得到:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int simetria (int n, int matriz[n][n], int transpuesta[n][n]);

int main(void)
{
    setbuf(stdout, NULL);
    srand(time(0));

    int n, r, c, symmetry = 0;

    scanf("%i", &n);

    int matriz [n][n],transpuesta[n][n];

    int contador = ((n*n)-n);

    while(symmetry != contador)
    {
        for(r = 0; r<n; r++){
            for(c = 0; c<n; c++){
                matriz [r][c] = (rand() %8);
            }
        }
        for(r = 0; r<n; r++){
            for(c = 0; c<n; c++){
                transpuesta[c][r] = matriz [r][c];
            }
        }
        symmetry = simetria(n, matriz, transpuesta);

    }
    printf("\n");
    for(r = 0; r<n; r++){
                for(c = 0; c<n; c++){
                    printf("%i \t", matriz [r][c]);
                }
                printf("\n\n");
            }
    return 0;
}

int simetria (int n, int matriz[n][n], int transpuesta[n][n])
{
    int r, c;
    int symmetry = 0;
    for(r = 0; r<n; r++){
                for(c = 0; c<n; c++){
                    if (r!=c){
                        if (transpuesta[r][c] == matriz [r][c]){
                            symmetry++;
                        }
                        else{
                            symmetry = 0;
                            return symmetry;
                        }
                    }
                }
            }
    return symmetry;
}

【问题讨论】:

  • 为了确定矩阵是否关于前导对角线对称,您是否只需要检查matrix[r][c] == matrix[c][r],确保您不检查对角线并且不要检查任何两次。无需创建转置。这将加快比较。但最终,随着矩阵变大,随机生成对称矩阵是不太可能的。
  • 你不是宁愿只生成一个三角形,然后对角线反射它...
  • @JonathanLeffler 好的,所以你说得对,我删除了所有转置的东西,我现在遇到的问题是只检查一次,我还没有想到只比较一半三角形的方法避免做剩下的转置。
  • for (int r = 0; r &lt; n; r++) { for (int c = r + 1; c &lt; n; c++) { if (matrix[r][c] != matrix[c][r]) { …asymmetric… } } } — 如果这是在布尔函数中,您可以return false; 检测不对称,return true; 如果循环完成。首先将matrix[0][1][matrix[1][0] 进行比较。请注意,如果目标是生成一个对称但随机的矩阵,您将使用类似的循环(但使用c = r 而不是c = r + 1)并使用matrix[r][c] = matrix[c][r] = rand() % 8; 或其他。内循环开始条件的变化也分配给前导对角线。
  • 我认为你的算法本质上会很慢。生成对称矩阵也更快,只需同时填充底部和顶部。

标签: c arrays matrix random-seed symmetric


【解决方案1】:

将我的 cmets 转换为答案。

要确定矩阵是否关于前导对角线对称,您只需要检查matrix[r][c] == matrix[c][r]。为了提高效率,你应该确保你不检查对角线,也不检查任何东西两次。无需像问题中那样创建转置。这将加快比较。但最终,随着矩阵变大,随机生成对称矩阵是不太可能的。

如果您有一个 2x2 矩阵,其中每个单元格都包含 0..7 范围内的整数值,那么您有八分之一的机会获得一个关于前导对角线对称的矩阵。如果您有一个 3x3 矩阵,则概率下降到 1 in 8³ 或 1:512,因为对角线上方有 3 个单元格,并且对角线下方的每个相应单元格包含相同值的概率为 8 分之一。使用 4x4 矩阵,下降到 1 in 8⁶ 或 1:4096;使用 5x5,概率下降到 1 in 8¹⁰ 或 1:32767,依此类推。对于 NxN 矩阵,概率为 8 的 N(N-1)/2 次方。

我还没有想到只比较一半三角形的方法。

for (int r = 0; r < n; r++)
{
    for (int c = r + 1; c < n; c++)
    {
        if (matrix[r][c] != matrix[c][r])
        {
            …asymmetric…
        }
    }
}

如果这是在布尔函数中,您可以使用return false; 检测不对称性,如果循环完成则使用return true;。首先将matrix[0][1]matrix[1][0] 进行比较。

请注意,如果目标是生成一个对称但随机的矩阵(每个单元格包含 0..7 范围内的整数值,您可以使用类似的循环(但使用 c = r 而不是 c = r + 1)并使用matrix[r][c] = matrix[c][r] = rand() % 8;。内循环开始条件的变化也分配给前导对角线。或者您可以避免将两次分配给前导对角线上的元素:

for (int r = 0; r < n; r++)
{
    matrix[r][r] = rand() % 8;
    for (int c = r + 1; c < n; c++)
         matrix[r][c] = matrix[c][r] = rand() % 8;
}

【讨论】:

    猜你喜欢
    • 2019-10-29
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    • 2015-03-08
    • 2021-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多