Есть ли способ генерировать случайные квадратные матрицы до тех пор, пока не будет одна симметричная c? (C) - PullRequest
0 голосов
/ 05 мая 2020

Мне нужно внутренне создать случайную матрицу из 3> = n> = 8 строк и столбцов, программа должна делать это, пока не найдет матрицу, симметричную c по диагонали, а затем распечатать ее, случайное числа должны быть от 0 до 7, и должна быть функциональность, в которой, изменяя форму переменной с true на false, вы можете выбирать, печатать или нет матрицы, которые не были симметричными c. Мне удалось создать случайные матрицы, пока он не станет симметричным c, но только для 3x3, любое число выше заставит мой p c постоянно думать, я уверен, что должен быть более эффективный способ сделать это, но я не очень хорош at c вот код, который я получил:

#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;
}

1 Ответ

1 голос
/ 05 мая 2020

Преобразование моих комментариев в ответ.

Чтобы определить, является ли матрица симметричной c относительно ведущей диагонали, вам просто нужно проверить это matrix[r][c] == matrix[c][r]. Для эффективности убедитесь, что вы не проверяете диагональ и ничего не проверяете дважды. Нет необходимости создавать транспонирование, как в вопросе. Это ускорит сравнение. Однако в конечном итоге случайное создание матрицы симметрии c довольно маловероятно, поскольку матрицы становятся больше.

Если у вас есть матрица 2x2, каждая ячейка которой содержит целочисленные значения в диапазоне 0..7, у вас есть 1 из 8 шансов получить матрицу, симметричную c относительно ведущей диагонали. Если у вас есть матрица 3x3, вероятность падает до 1 из 8³ или 1: 512, потому что есть 3 ячейки над диагональю, и есть вероятность 1 из 8, что каждая из соответствующих ячеек ниже диагонали содержит одно и то же значение. С матрицей 4x4 это значение уменьшается до 1 из 8⁶ или 1: 4096; при 5x5 вероятность падает до 1 из 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].

Обратите внимание, что если целью является создание симметричной c, но случайной матрицы (каждая ячейка содержит целочисленные значения в диапазоне 0..7, вы можно было бы использовать аналогичные циклы (но с c = r, а не c = r + 1) и использовать matrix[r][c] = matrix[c][r] = rand() % 8;. Изменение внутреннего условия l oop start также назначается ведущей диагонали. Или вы можете избежать двойного назначения элементов на ведущая диагональ с:

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;
}
...