Advertisement
Guest User

Untitled

a guest
May 21st, 2019
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.98 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement