المزيد عن طرق حل أنظمة المعادلات الجبرية الخطية

بالطبع من الصعب للغاية معرفة التفاصيل حول جميع الأساليب ، ولكن بالنسبة لي يبدو هذا الموضوع مثيرًا للاهتمام ومهمًا للغاية ، حيث يواجه الجميع مهمة إيجاد حل في كثير من الأحيان. في المقال الأول لماذا غاوس؟ تم وصف طريقة غاوس (بما في ذلك التعديلات) وبعض الطرق التكرارية. ومع ذلك ، نظرًا لانتقادات سن3 ، قررت أن أصف طرقًا أخرى أيضًا.

ابدأ من جديد


لذا ، دعونا نحتاج مرة أخرى إلى حل نظام معادلات جبرية خطية للنظام n. واحدة من أكثر الطرق العددية اللافتة للنظر هي الطريقة المستخدمة Lu- تكوين المصفوفة.

هذه الطريقة الحدسية هي كما يلي. لنفترض أن لدينا نظامًا من المعادلات الجبرية الخطية (مكتوبة بشكل متجه):

Ax=b،

أين A=(aij)- مصفوفة رهيبة وغير مربكة. نحن نمثلها كمنتج لمصفوفتين أخريين: L=(lij)هي مصفوفة مثلثة أقل U=(uij)هي المصفوفة المثلثية العلوية. ثم من الواضح أن النظام يأخذ الشكل:

LUx=ب.

إذا تم تعيينه Ux=y، ثم يتم العثور على حل النظام الأصلي من حل نظامين آخرين:

Ly=b،

Ux=y.


تكمن ميزة هذه الطريقة في أن حلول نظامين مساعدين بسيطة للغاية (بسبب حقيقة أن المصفوفات Lو U- مثلث). ولكن هل من السهل العثور على هذه المصفوفات؟ لذلك ، يتم تقليل مهمة حل النظام إلى مهمة البناء Lu-تنسيقات المصفوفة.

وصف الخوارزمية المطبقة Luيتم وصف التحلل بتفاصيل كافية هنا . في غضون ذلك ، سنلقي نظرة على طريقة أخرى.

طريقة الجذر التربيعي


نفرض شروط إضافية على المصفوفة A. نطلب أن تكون متناظرة ، أي aij=ajiأو At=A. يمكن تمثيل هذه المصفوفة على أنها

A=StDS،

أين S- مصفوفة مثلثة علوية ، Dهي مصفوفة حقيقية قطرية ، وعناصرها القطرية تساوي الوحدة في القيمة المطلقة. وبالمثل ، تم تقليل النظام الأصلي إلى نظامين آخرين:

StDy=b،

Sx=y،

والتي يتم حلها أيضًا بشكل أساسي بسبب خصائص المصفوفات Sو D.

اشتقاق الصيغ الخوارزمية مرهقة إلى حد ما ولا يزال خارج نطاق النشر. إذا رغبت في ذلك ، يمكن العثور عليها هنا .

نموذج كود Java الذي يقوم بتنفيذ طريقة المسح:

import java.io.FileNotFoundException; import java.io.FileReader; import java.io.PrintWriter; import java.util.Locale; import java.util.Scanner; public class SquareRootMethod { public static void main(String[] args) throws FileNotFoundException { Scanner scanner = new Scanner(new FileReader("input.txt")); scanner.useLocale(Locale.US); int n = scanner.nextInt(); double[][] a = new double[n + 1][n + 1]; double[] b = new double[n + 1]; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { a[i][j] = scanner.nextDouble(); } b[i] = scanner.nextDouble(); } double[] x = new double[n + 1]; double[] d = new double[n + 1]; double[][] s = new double[n + 1][n + 1]; // for i = 1 d[1] = Math.signum(a[1][1]); s[1][1] = Math.sqrt(Math.abs(a[1][1])); for (int j = 2; j <= n; j++) { s[1][j] = a[1][j] / (s[1][1] * d[1]); } // for i > 1 //searching S and D matrix for (int i = 2; i <= n; i++) { double sum = 0; for (int k = 1; k <= i - 1; k++) { sum += s[k][i] * s[k][i] * d[k]; } d[i] = Math.signum(a[i][i] - sum); s[i][i] = Math.sqrt(Math.abs(a[i][i] - sum)); double l = 1 / (s[i][i] * d[i]); for (int j = i + 1; j <= n; j++) { double SDSsum = 0; for (int k = 1; k <= i - 1; k++) { SDSsum += s[k][i] * d[k] * s[k][j]; } s[i][j] = l * (a[i][j] - SDSsum); } } //solve of the system (s^t * d)y = b double[] y = new double[n + 1]; y[1] = b[1] / (s[1][1] * d[1]); for (int i = 2; i <= n; i++) { double sum = 0; for (int j = 1; j <= i - 1; j++) { sum += s[j][i] * d[j] * y[j]; } y[i] = (b[i] - sum) / (s[i][i] * d[i]); } //solve of the system sx = y x[n] = y[n] / s[n][n]; for (int i = n - 1; i >= 1; i--) { double sum = 0; for (int k = i + 1; k <= n; k++) { sum += s[i][k] * x[k]; } x[i] = (y[i] - sum) / s[i][i]; } //output PrintWriter pw = new PrintWriter("output.txt"); for (int i = 1; i <= n; i++) { pw.printf(Locale.US, "x%d = %f\n", i, x[i]); } pw.flush(); pw.close(); } } 

طريقة الاجتياح


باستخدام هذه الطريقة ، لا يمكن حل سوى أنظمة محددة لا تزيد عن ثلاثة مجهولين في كل صف. أي مع النظام

Ax=b

مصفوفة Aثلاثي الأبعاد:

A = \ start {pmatrix} C_1 & -B_1 & 0 & \ dots & 0 & 0 \\ -A_2 & C_2 & -B_2 & \ dots & 0 & 0 \\ \ vdots & \ vdots & \ vdots & \ ddots & \ vdots & \ vdots \\ 0 & 0 & \ dots & -A_ {n-1} & C_ {n-1} & -B_ {n-1} \\ 0 & 0 & \ dots & 0 & -A_n & C_n \\ \ end {pmatrix}.



فقط لاحظ أنه يوجد اتصال بين الحلول المجاورة:

xi1= alphai1xi+ betai1،


 alphak، betak- بعض الأرقام المجهولة. إذا وجدناها ومتغير واحد ، يمكننا أن نجد جميع المتغيرات الأخرى.

اشتقاق الصيغ

 alpha1= dfracB1C1،  alphai= dfracBiCiAi alphai1، i= overline2،n،

 beta1= dfracb1C1،  betai= dfracbi+Ai betai1CiAi alphai1، i= overline2،ندولا

موجود هنا . حسنًا ، في النهاية

xn= dfracbn+An betan1CnAn alphan1، xi= alphaixi+1+ betai، i=n1،n2، dots،1


لاحظ أنه في صيغ البحث  alphai، betaiهناك قسمة على الرقم CiAi alphai1،والتي قد تتحول إلى صفر ويجب تتبعها. ولكن في الواقع ، العبارة التالية سارية ، والدليل هنا : خوارزمية المسح صحيحة ومستقرة إذا تم استيفاء الشروط:

C1،Cn neq0،Ai،Bi neq0 (i= overline2،n)،

|Ci| geq|Ai|+|Bi|.


ضع في اعتبارك كود برنامج Java الذي يحل النظام.

\ left \ {\ start {align} & x_1 = 0، \\ & x_ {i-1} + \ xi x_ {i + 1} = \ dfrac {i} {n}، \ (i = \ overline {2، n-1})، \\ & x_n = 1، \\ \ end {align} \ right.

في  xi=2،n=21.

 package SystemOfLinearAlgebraicEquations; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.PrintWriter; import java.util.Locale; import java.util.Scanner; public class TridiagonalMatrixAlgorithm { public static void main(String[] args) throws FileNotFoundException { final int n = 21; double[] A = new double[n + 1]; double[] B = new double[n + 1]; double[] C = new double[n + 1]; double[] F = new double[n + 1]; double xi = 2; C[1] = 1; F[1] = 0; for(int i = 2; i <= n-1; i++) { A[i] = 1; C[i] = xi; B[i] = 1; F[i] = - (double) i / n; } A[n] = 0; C[n] = 1; F[n] = 1; double[] alpha = new double[n + 1]; double[] beta = new double[n + 1]; // right stroke alpha[1] = B[1] / C[1]; beta[1] = F[1] / C[1]; for (int i = 2; i <= n - 1; i++) { double denominator = C[i] - A[i] * alpha[i-1]; alpha[i] = B[i] / denominator; beta[i] = (F[i] + A[i] * beta[i - 1]) / denominator; } double[] x = new double[n + 1]; // back stroke x[n] = (F[n] + A[n] * beta[n - 1]) / (C[n] - A[n] * alpha[n - 1]); for (int i = n - 1; i >= 1; i--) { x[i] = alpha[i] * x[i + 1] + beta[i]; } // output PrintWriter pw = new PrintWriter("output.txt"); for (int i = 1; i <= n; i = i + 5) { pw.printf(Locale.US, "x%d = %f\n", i, x[i]); } pw.flush(); pw.close(); } } 

Source: https://habr.com/ru/post/ar418627/


All Articles