1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
double **L;
double **U;
int **A;
int N;
//funkcje pomocnicze do obliczenia wyznacznika
double
suma1(int i, int j)
{
double ret = 0;
for (int k = 0; k < i; k++) {
ret += L[i][k] * U[k][j];
}
return ret;
}
double
suma2(int i, int j)
{
double ret = 0;
for (int k = 0; k < i; k++) {
ret += L[j][k] * U[k][i];
}
return ret;
}
double
wyznacznik(int **A)
{ //funkcje liczaca wyznacznik z podanej macierzy metoda LU
double w = 1.0; //wyznacznik
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
U[i][j] = 0;
L[i][j] = 0;
}
}
for (int i = 0; i < N; i++) {
L[i][i] = 1;
}
for (int i = 0; i < N; i++) {
for (int j = i; j < N; j++) {
U[i][j] = A[i][j] - suma1(i, j);
}
// DMH: Is this code right? You're assigning values to L and those
// values are used in suma1() and suma2(). Is that okay?
for (int j = i + 1; j < N; j++) {
L[j][i] = (1 / U[i][i]) * (A[j][i] - suma2(i, j));
}
}
for (int i = 0; i < N; i++)
w *= U[i][i]; // wyznacznik = iloczynowi elementów na przek¹tnej macierzy U
// The values are usually pretty big, which makes me thing something
// is wrong with the math.
printf("result = %g\n", w);
return w;
}
struct powtorzenie
{ // element przechowujacy macierze zapisane do pliku
int **A;
};
bool
sprawdz(int **A, powtorzenie * B, int k)
{ //funkcja sprawdza czy macierz sie nie powtorzyla
for (int x = 0; x < k; x++) {
bool c = true;
// dmh: added "&& c& tests below for efficiency
for (int i = 0; i < N && c; i++) {
for (int j = 0; j < N && c; j++) {
if (B[x].A[i][j] != A[i][j])
c = false;
}
}
if (c)
return true;
}
return false;
}
int
main()
{
int ilosc;
printf("Podaj rozmiar tablicy(4,8,16):");
scanf("%i", &N);
L = new double *[N];
for (int i = 0; i < N; i++)
L[i] = new double[N];
U = new double *[N];
for (int i = 0; i < N; i++)
U[i] = new double[N];
A = new int *[N];
for (int i = 0; i < N; i++)
A[i] = new int[N];
powtorzenie *B = new powtorzenie[30000];
int k = 0;
FILE *f;
if ((f = fopen("p1_wynik.txt", "w")) == NULL) {
printf("Nie mogê otworzyæ pliku test.txt do zapisu!\n");
exit(1);
}
fprintf(f, "Wygenerowane macierze ktorych wyznacznik wynosi 1: \n \n ");
ilosc = 0;
for (int t = 1; t < 1000000000; t++) { // liczba obrotów oznacz ilosc wygenerowanych i sprawdzonych tablic
// DMH: Here is some debugging code to let you know it's doing something
if (t%100 == 0) {
printf(".");
fflush(stdout);
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
A[i][j] = rand() % 15; //zakres od zera do podanej liczby
}
}
if (wyznacznik(A) == 1) {
if (!sprawdz(A, B, k)) {
B[k].A = new int *[N];
for (int i = 0; i < N; i++)
B[k].A[i] = new int[N];
fprintf(f, "\n ");
printf("\n ");
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
fprintf(f, "%i ", A[i][j]);
printf("%i ", A[i][j]);
B[k].A[i][j] = A[i][j];
}
fprintf(f, "\n ");
printf("\n ");
}
fprintf(f, "\n ");
printf("\n ");
fflush(stdout);
fflush(f);
k++;
ilosc++;
}
}
}
printf("Znaleziono %d macierzy", ilosc);
fclose(f);
return 0;
}
|