SHARE
TWEET

Untitled

a guest May 21st, 2019 80 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "pch.h"
  2. #include <iostream>
  3. #include <clocale>
  4. #include <iomanip>
  5. #include <ctime>
  6.  
  7. using namespace std;
  8.  
  9. void NewMat(double**& B, int n);//Выделение памяти для двумерного массива.
  10.  
  11. void Clear(double**& B, int n);//Подчищение памяти.
  12.  
  13. void Out(double**& A, int n, int m);//Вывод на экран.
  14.  
  15. void Input(double**& B, int n);//Ввод самого массив.
  16. void ManualInput(double** A, int n);//Матрица, заданная явно
  17. void Unitmatrix(double** A, int n);//Единичная матрица
  18. void MatrixGilbert(double** A, int n);// Матриуа гильберта
  19. void MatrixNull(double** A, int n);//Нулевая или вырожденная матрицы (2 коллинеарные строки, или одна нулевая строка)
  20. void MatrixRandom(double** A, int n);//рандомное заполнение марицы
  21. void MantrixRand(double**& B, int n, int m);//Заполнение рандомными числами.*****
  22.  
  23. void HostElement(double**& B, int n, int m);//Берём ведущий элемент, и делим на всю i строчку.
  24.  
  25. double Diagonal2(double** A, double* x, int n);//приведение матрицы к треугольному виду
  26. void Swaprows(double**& A, double* b, int N);//Перестановка строк
  27.  
  28.  
  29. void Diagonal(double**& mas, double* x, int N);//Прямой ход
  30. void Reverse(double**& mas, double* x, double* ot, int n);//Обратный ход
  31.  
  32.  
  33. double Determinant(double ** A, int n);// Рекурсивное вычисление определителя
  34. void GetMatr(double ** A, double **p, int i, int j, int n);// Получение матрицы без i-й строки и j-го столбца
  35.  
  36. int main()
  37. {
  38.     setlocale(LC_ALL, "Ru");
  39.     int n, m, key;
  40.     cout << "введите размер матрицы:"; cin >> n; m = n + 1;
  41.     double** A;
  42.     double* b = new double[n];//Для записи чисел стоящих после знака равно.
  43.     double* x = new double[n];//Для записи ответов.
  44.     double* ot = new double[n];//Отвечает за порядок корней
  45.  
  46.  
  47.     NewMat(A, n);//выделение памяти
  48.  
  49.     cout << "выберите: " << endl << " 1-Матрица, заданная явно (размер матрицы 3х3) " << endl << " 2-Единичная матрица" << endl << " 3-Матриуа гильберта" << endl << " 4-Нулевая или вырожденная матрицы" << endl << " 5-рандомное заполнение матрицы " << endl << " 6-ввод массива самостоятельно" << endl << "------>"; cin >> key;
  50.     switch (key) {
  51.     case 1: { n = 3; m = 4; ManualInput(A, n); break; }
  52.     case 2: Unitmatrix(A, n); break;
  53.     case 3: MatrixGilbert(A, n); break;
  54.     case 4: MatrixNull(A, n); break;
  55.     case 5: MatrixRandom(A, n);  break;
  56.     case 6: Input(A, n);  break;
  57.     default: cout << "error"; break;
  58.     }
  59.     key = 0;
  60.     Determinant(A, n);
  61.     Out(A, n, m);
  62.     //
  63.     cout << "Если хочешь реализовать алгоритм метода Гаусса с выбором ведущего элемента по строке, по столбцу либо по всей матрице-1 иначе другое вычисление:"; cin >> key;
  64.     if (key == 1) {
  65.  
  66.         Diagonal2(A, x, n); //Решение методом Гаусса
  67.  
  68.         Clear(A, n);
  69.     }
  70.     else
  71.     {
  72.         Diagonal(A, x, n);
  73.         Reverse(A, x, ot, n);
  74.         Clear(A, n);
  75.     }
  76.     return 0;
  77. }
  78.  
  79. void NewMat(double**& B, int n)//выделение памяти для двумерного массива
  80. {
  81.     B = new double*[n + 1];
  82.  
  83.     for (int i = 0; i < n; i++)
  84.         B[i] = new double[n + 1];
  85. }
  86.  
  87. void Clear(double**& B, int n)//подчищение памяти в двумерном массиве.
  88. {
  89.     for (int i = 0; i < n; i++)
  90.         delete[]B[i];
  91.  
  92.     delete[] B; B = NULL;
  93. }
  94.  
  95. void MantrixRand(double**& B, int n, int m)//Заполнение рандомными числами.
  96. {
  97.     srand(time(0));
  98.     for (int i = 0; i < n; i++)
  99.     {
  100.         for (int j = 0; j < m; j++)
  101.         {
  102.             B[i][j] = rand() % 10;
  103.         }
  104.     }
  105.  
  106. }
  107.  
  108. void Input(double**& A, int n)//Ввод матрицы*****
  109. {
  110.     cout << "Введите матрицу :\n";
  111.     for (int i = 0; i < n; i++)
  112.         for (int j = 0; j < n + 1; j++)
  113.         {
  114.             if (j <= n - 1)
  115.             {
  116.                 printf("Введите элемент матрицы a[%d][%d]:", ++i, ++j);
  117.                 --j;
  118.                 --i;
  119.             }
  120.             else
  121.             {
  122.                 printf("Введите элемент матрицы b[%d]:", ++i);
  123.                 --i;
  124.             }
  125.             cin >> A[i][j];
  126.         }
  127. }
  128.  
  129. void ManualInput(double** A, int n)//Ручной ввод матрицы
  130. {
  131.     printf("Ваша матрица равна:\n");
  132.     A[0][0] = 3;
  133.     A[0][1] = 2;
  134.     A[0][2] = -5;
  135.     A[0][3] = -1;
  136.     A[1][0] = 2;
  137.     A[1][1] = -1;
  138.     A[1][2] = 3;
  139.     A[1][3] = 13;
  140.     A[2][0] = 1;
  141.     A[2][1] = 2;
  142.     A[2][2] = -1;
  143.     A[2][3] = 9;
  144. }
  145.  
  146. void Unitmatrix(double** A, int n)//Единичная матрица
  147. {
  148.     for (int i = 0; i < n; i++) {
  149.         for (int j = 0; j < n + 1; j++) {
  150.             if (j == n) { cout << "введите А[" << i << "][" << j << "]= "; cin >> A[i][j]; }
  151.             else if (i == j) A[i][j] = 1;
  152.             else A[i][j] = 0;
  153.  
  154.         }
  155.         cout << endl;
  156.     }
  157. }
  158.  
  159. void MatrixGilbert(double** A, int n)// Матриwа гильберта
  160. {
  161.     for (int i = 0; i < n; i++) {
  162.         for (int j = 0; j < n + 1; j++) {
  163.             A[i][j] = 1. / (i + j + 1);
  164.         }
  165.         cout << endl;
  166.     }
  167. }
  168.  
  169. void MatrixNull(double** A, int n)//Нулевая или вырожденная матрицы (2 коллинеарные строки, или одна нулевая строка)***************
  170. {
  171.  
  172. }
  173.  
  174. void MatrixRandom(double** A, int n)//рандомное заполнение марицы
  175. {
  176.     for (int i = 0; i < n; i++) {
  177.         for (int j = 0; j < n + 1; j++) {
  178.             A[i][j] = rand() % 20;
  179.         }
  180.         cout << endl;
  181.     }
  182. }
  183.  
  184. void Out(double**& A, int n, int m)//вывод двумерного массива
  185. {
  186.     for (int i = 0; i < n; i++)
  187.     {
  188.         for (int j = 0; j < m; j++)
  189.             cout << setw(10) << A[i][j];
  190.         cout << endl;
  191.     }
  192. }
  193.  
  194. void Diagonal(double**& mas, double* x, int n)//Прямой ход
  195. {
  196.     int i, j, k, s = 1;
  197.     for (k = 0; k < n; k++)             //Прямой ход метода Гаусса
  198.     {                               //На какой позиции должен стоять
  199.         if (fabs(mas[k][k]) < 0.0001)       //главный элемент
  200.         {
  201.             printf("Система не имеет единственного решения!\n");
  202.             return;
  203.         }
  204.         for (j = n; j >= k; j--)        //Приведение матрицы к ступенчатому виду
  205.             mas[k][j] /= mas[k][k];
  206.         for (i = k + 1; i < n; i++)
  207.             for (j = n; j >= k; j--)
  208.                 mas[i][j] -= mas[k][j] * mas[i][k];
  209.     }
  210.     printf("С помощью элементарных преобразований привели матрицу к ступенчатому виду:\n");
  211.     for (i = 0; i < n; i++)             //Вывод матрицы треугольного вида
  212.     {
  213.         for (j = 0; j < n; j++)
  214.             printf("%7.2f", mas[i][j]);
  215.         for (j = n; j < n + 1; j++)
  216.             printf("|%5.2f", mas[i][j]);
  217.         printf("\n");
  218.     }
  219. }
  220.  
  221. void Reverse(double**& mas, double* x, double* ot, int n)//Обратный ход
  222. {
  223.     int i, j, k, o = 1, s = 1;
  224.     for (i = 0; i < n; i++)             //Обратный ход
  225.         x[i] = mas[i][n];
  226.     for (i = n - 2; i >= 0; i--)
  227.         for (j = i + 1; j < n; j++)
  228.             x[i] -= x[j] * mas[i][j];
  229.  
  230.     for (i = 0; i <= n; i++)                //Сначала все корни по порядку
  231.         ot[i] = i;
  232.     printf("Ответ:\n");                    //Вывод результата
  233.     for (i = 0; i < n; i++)
  234.         for (j = 0; j < n; j++)
  235.             if (i == ot[j])
  236.             {                               //Расставляем корни по порядку
  237.                 printf("X%d=%.2f\n", s++, x[j]);
  238.                 break;
  239.             }
  240. }
  241.  
  242.  
  243. // Рекурсивное вычисление определителя
  244. double Determinant(double ** A, int n) {
  245.     int i, j, k, z;
  246.     double d;
  247.     double **p;
  248.     p = new double*[n];
  249.     for (i = 0; i < n; i++)
  250.         p[i] = new double[n];
  251.     ////
  252.     j = 0; d = 0;
  253.     k = 1; //(-1) в степени i
  254.     z = n - 1;
  255.     if (n < 1) cout << "Определитель вычислить невозможно!";
  256.     if (n == 1) {
  257.         d = A[0][0];
  258.         return(d);
  259.     }
  260.     if (n == 2) {
  261.         d = A[0][0] * A[1][1] - (A[1][0] * A[0][1]);
  262.         return(d);
  263.     }
  264.     if (n > 2) {
  265.         for (i = 0; i < n; i++) {
  266.             GetMatr(A, p, i, 0, n);
  267.  
  268.             d = d + k * A[i][0] * Determinant(p, z);
  269.             k = -k;
  270.         }
  271.     }
  272.     cout << endl << "определитель равен = " << d << endl;
  273.     return(d);
  274. }
  275.  
  276. // Получение матрицы без i-й строки и j-го столбца
  277. void GetMatr(double ** A, double **p, int i, int j, int n) {
  278.     int ki, kj, di, dj;
  279.     di = 0;
  280.     for (ki = 0; ki < n - 1; ki++) { // проверка индекса строки
  281.         if (ki == i) di = 1;
  282.         dj = 0;
  283.         for (kj = 0; kj < n - 1; kj++) { // проверка индекса столбца
  284.             if (kj == j) dj = 1;
  285.             p[ki][kj] = A[ki + di][kj + dj];
  286.         }
  287.     }
  288. }
  289.  
  290. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  291. //функция для приведения матрицы в трекгольную
  292.  double Diagonal2(double** A, double* x, int n)
  293. {
  294.     double* y, max;
  295.     int k, index;
  296.     const double eps = 0.00001;  // точность
  297.     y = new double[n];
  298.     k = 0;
  299.  
  300.     //Элементы для определителя
  301.     float* answ; // Массив для сохранения делителей
  302.     int typen = 0; //Кол-во перестановок
  303.     answ = new float[n];
  304.     float opr = 1;
  305.  
  306.     while (k < n)
  307.     {
  308.         // Поиск строки с максимальным a[i][k]
  309.         max = abs(A[k][k]);
  310.         index = k;
  311.         for (int i = k + 1; i < n; i++)
  312.         {
  313.             if (abs(A[i][k]) > max)
  314.             {
  315.                 max = abs(A[i][k]);
  316.                 index = i;
  317.             }
  318.         }
  319.         cout << "max= " << max << endl;
  320.         // Перестановка строк
  321.         if (max < eps)
  322.         {
  323.             // нет ненулевых диагональных элементов
  324.             cout << "Решение получить невозможно из-за нулевого столбца ";
  325.             cout << index << " матрицы A" << endl;
  326.             return 0;
  327.         }
  328.         for (int j = 0; j < n; j++)
  329.         {
  330.             double temp = A[k][j];
  331.             A[k][j] = A[index][j];
  332.             A[index][j] = temp;
  333.             typen++;
  334.         }
  335.         double temp = y[k];
  336.         x[k] = x[index];
  337.         x[index] = temp;
  338.         // Нормализация уравнений
  339.         for (int i = k; i < n; i++)
  340.         {
  341.             double temp = A[i][k];
  342.  
  343.             if (abs(temp) < eps)break;// continue; // для нулевого коэффициента пропустить
  344.             for (int j = 0; j < n; j++)
  345.                 A[i][j] = A[i][j] / temp;
  346.             x[i] = x[i] / temp;
  347.             if (i == k)break;// continue;// уравнение не вычитать само из себя
  348.             for (int j = 0; j < n; j++)
  349.                 A[i][j] = A[i][j] - A[k][j];
  350.             x[i] = x[i] - x[k];
  351.         }
  352.         k++;
  353.     }
  354.     // обратная подстановка
  355.     for (k = n - 1; k >= 0; k--)
  356.     {
  357.         y[k] = x[k];
  358.         for (int i = 0; i < k; i++)
  359.             x[i] = x[i] - A[i][k] * y[k];
  360.         cout << "y= " << y << "  ";
  361.     }
  362.    
  363.     return 0;
  364. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top