Método de Gauss - Seidel
Bueno el método de Gauss-Seidel consiste en solucionar un sistema de ecuaciones a través de una formulas de varias variables auto convergentes, osea que tendremos varias incógnitas y una función que le corresponde a cada incógnita para converger el resultado
Siendo:
j es diferente de i Xi como una función de (X0,X1,...,Xn)
Cj = Constante que acompaña a cada X de la Ecuación (i)
bi = Resultado de la Ecuación (i)
Entonces si resolvemos la sumatoria nos queda:
y sustituyendo en nuestra primera ecuación nos queda:
Dato IMPORTANTE:
Este método solo se le puede aplicar a Sistemas de Ecuaciones cuya Matriz de Coeficientes es Dominante, para enterarme mas sobre que es una matriz dominante los invito a leer el articulo de Wikipedia
Bueno conociendo lo anterior empezamos a programar
Para el Diseño del programa utilice 2 DataGridView que contendrán los valores de la Matriz y sus Respectivos Resultados de la Ecuación, Seguido hay un Listbox donde se mostraran los Resultados y por ultimo 2 Bottons, 1 para poder darle una dimensión a la matriz y el otro para solucionar el sistema de ecuaciones a través del método de Gauss-Seidel
Nota Importante:
Al DataGridView que contiene los Resultados, Previamente le agregue solo 1 columna pues solo tiene 1 sin importar la dimensión, es importante considerarlo porque cuando trabajas con un DataGridView primero se agregan Columnas y luego Renglones o si no marca Error.
Bueno lo que haremos es generar unos textos que contengan las funciones de cada "X" para después solucionarlas por un método que Contiene JavaScript donde lee el texto como código y retorna el valor de la Ecuación Aritmética, por ello es que antes que nada debemos importar la biblioteca de JavaScript.
Nos vamos al proyecto, le damos click derecho, de ahí a agregar, de ahí a Referencias
y Palomeamos la Biblioteca: Microsoft.JScript
Ahora ya tenemos la biblioteca referenciada al proyecto, pero para términos prácticos vamos a importar esta misma al código para acceder de forma mas sencilla a sus operadores
Bueno ahora que ya terminamos todos los preparativos pasemos a declarar un par de variables globales las cuales usaremos casi todo el tiempo
La variable que contiene la dimensión de la Matriz
Dim Dimension As Integer
La variable que requerimos para el solucionador de JavaScript
Dim engine As VsaEngine = VsaEngine.CreateEngine()
Seguido haré un Sub que responda a la acción "Load" del "Form1" este con la finalidad de que indique que todavía no esta dimensionada la Matriz
Bueno ahora si pasemos al código del Botton que Dimensiona la Matriz
Este empezara solicitándole al usuario que introduzca la dimensión de la Matriz y a ese valor dado le restaremos 1 ya que las matrices en VB.Net operan desde el indice 0
Dimension = Val(InputBox("Inserte de Cuanto por cuanto es su matriz")) - 1
De ahi debemos comprobar que el usuario no haya introducido el valor 0 o un valor negativo pues esto no permitiría dimensionar a una matriz
If Dimension > 0 Then
Seguido si es que el usuario ya ah echo operaciones en el programa entonces ya tendrán datos los DataGridView por lo que debemos limpiarlos
DGVM.Rows.Clear()
DGVM.Columns.Clear()
DGVMR.Rows.Clear()
Luego debemos Agregar los Renglones y Columnas a Cada DataGridView con Respecto a la Dimension de la Matriz
For i = 0 To Dimension
DGVM.Columns.Add(i, CStr(i + 1))
DGVM.Columns(i).Width = 70
DGVM.Rows.Add()
DGVMR.Rows.Add()
Next
Y pues listo ahí esta el Primer Botton, ahora si empecemos con lo sabroso
Para el Botton que resuelve el Sistema de Ecuaciones a través del método de Gauss-Seidel vamos a declarar unas cuantas muchas variables y matrices locales
La variable que realiza la suma que verifica que la Matriz sea Dominante
Dim SumaJ As Double
La variable que comprobara si cumple con la Restriccion
Dim Restriccion As Boolean
La Matriz que Contendrá Cada valor de los Coeficientes de las X's
Dim MatrizX(,) As Double
La Matriz que Contendrá los valores de los resultados de cada Ecuación
Dim MatrizR() As Double
La Matriz que Contiene el texto de cada X ("X0","X1", ... , "Xn")
Dim MatrizXS() As String
La Matriz que Contendrá la función auto convergente de cada X en texto
Dim MatrizFX() As String
La Matriz que Contendrá el texto de la Función de cada X pero sustituyendo las respectivas incógnitas
Dim MatrizFXT() As String
Las Matrices que Contendrán los Valores Anteriores y Posteriores de la Evaluación de la función de cada X
Dim MatrizXVA(), MatrizXVP() As Double
Y por ultimo la Matriz que Contiene El texto que muestra el Resultado
Dim MatrizdeRes() As String
Seguido Vamos a Dimensionar cada Matriz con respecto a la dimensión de la Matriz
ReDim MatrizX(Dimension, Dimension)
ReDim MatrizR(Dimension)
ReDim MatrizXS(Dimension)
ReDim MatrizFX(Dimension)
ReDim MatrizXVA(Dimension)
ReDim MatrizXVP(Dimension)
ReDim MatrizFXT(Dimension)
ReDim MatrizdeRes(Dimension)
Despues vamos a Asignarle los valores que Contiene el DataGridView a la Matriz de Coeficientes y la de Resultados
For i = 0 To Dimension
. For j = 0 To Dimension
. . MatrizX(i, j) = Val(DGVM.Rows(i).Cells(j).Value)
. Next
. MatrizR(i) = Val(DGVMR.Rows(i).Cells(0).Value)
Next
Después Comprobamos que la Matriz de Coeficientes sea Dominante
For i = 0 To Dimension
. SumaJ = 0
. For j = 0 To Dimension
. . If j <> i Then
. . . SumaJ = SumaJ + MatrizX(i, j)
. . End If
. Next
. If MatrizX(i, i) < SumaJ Then
. . MsgBox(String.Format("El Metodo de Gauss-Seidel no se puede Solucionar debido a que en el Renglon {0} la Matriz no es Dominante", (i + 1)))
. . Return
. . Return
. End If
Next
Esta Parte que Sigue es interesante, vamos a formular las Funciones que le Corresponden a cada X
Para ello primero vamos a Generar los textos de cada X ("X0","X1", ... , "Xn")
For i = 0 To Dimension
. MatrizXS(i) = String.Format("X{0}", i + 1)
Next
Y Pasamos a Desarrollar las Funciones, para ello lo que haré es primero darle el valor del resultado (b) y de ahí le iré anexando la sumatoria (-Cjxj) y hasta el final lo encerrare en un paréntesis y le anexare hasta la derecha la división (("Ecuación")/Ci)
For i = 0 To Dimension
. MatrizFX(i) = MatrizR(i)
. For j = 0 To Dimension
. . If j <> i Then
. . . If Math.Sign(MatrizX(i, j)) < 0 Then
. . . . MatrizFX(i) = String.Format("{0}+{1}*{2}", MatrizFX(i), MatrizX(i, j), MatrizXS(j))
. . . ElseIf Math.Sign(MatrizX(i, j)) > 0 Then
. . . . MatrizFX(i) = String.Format("{0}-{1}*{2}", MatrizFX(i), MatrizX(i, j), MatrizXS(j))
. . . End If
. . End If
. Next
. MatrizFX(i) = String.Format("({0})/{1}", MatrizFX(i), MatrizX(i, i))
Next
Si es posible les recomiendo hacer una prueba de escritorio para que vean como funciona
Bueno ahora empezamos con el Ciclo el cual lo dividiré en 2 partes, en la primera parte veremos los preparativos, la conversión de inicio, la sustitución de los valores de las X's en las Funciones de Cada X y por ultimo la Evaluación de cada Función ya con sus sustituciones
Preparativos para el Ciclo, Primero debemos saber que el primer valor propuesto para el método de Gauss-Seidel es 0 para cada incógnita por lo que vamos asignarle ese valor a cada indice a la matriz de X posterior pues este iniciando el ciclo le dará esos mismos valores a la matriz de X iniciales
For i = 0 To Dimension
MatrizXVP(i) = 0
Next
Comenzamos con el Ciclo Do-LoopWhile
La primer parte del ciclo como les había mencionado hereda los valores de la matriz de X posterior a la matriz de X inicial con el fin de generar nuevos valores y realizar de forma adecuada cada iteración
For i = 0 To Dimension
MatrizXVA(i) = MatrizXVP(i)
Next
Bueno ahora generaremos la sustitución de variables en las funciones de cada X's , para ello lo que hago es primero asignarle el texto que hicimos previamente a un texto de transición, de ahí ese texto le empezare a remplazar una por una cada incógnita con la función String.Replace
For i = 0 To Dimension
MatrizFXT(i) = MatrizFX(i)
For j = 0 To Dimension
MatrizFXT(i) = MatrizFXT(i).Replace(MatrizXS(j), MatrizXVA(j))
Next
Next
Y para concluir la primera parte del Ciclo vamos a evaluar cada función de X con el operador de JavaScript
For i = 0 To Dimension
MatrizXVP(i) = Eval.JScriptEvaluate(MatrizFXT(i), engine)
Next
En la Segunda parte del Ciclo veremos la Comprobación de que el valor absoluto de la resta de cada Xia - Xip sea lo mas cercana a 0 para tener un margen de error casi nulo y como en base a esto el programa decide si repetir el ciclo o no.
Para comprobar que cumpla con el requerimiento cada una de las incógnitas hice uso de un Bolean el cual solo puede contener falso o cierto, de ahí le hago la comprobación a cada incógnita y de ser cierto que cumple el Bolean sera Cierto pero con que solo uno falle se convertirá en Falso
For i = 0 To Dimension
If Math.Abs(MatrizXVP(i) - MatrizXVA(i)) < 0.000001 Then
Restriccion = True
Else
Restriccion = False
End If
Next
y Si es Falsa la Restricción entonces Repite el Ciclo Do-LoopWhile
Loop While Restriccion = False
Una vez que terminamos el Ciclo y ya tenemos los Resultados, solo falta imprimirlos, para ello haremos un texto que contiene la "Xi = Xresultante"
For i = 0 To Dimension
MatrizdeRes(i) = String.Format("{0} = {1}", MatrizXS(i), MatrizXVP(i))
Next
Y de ahi solo limpiamos el ListBox y seguido de eso le importamos todos los Resultados
LBX.Items.Clear()
LBX.Items.AddRange(MatrizdeRes)
Y pues nada terminamos el Programa, pero antes lo Copilaremos para Comprobar que funciones Correctamente
Lo Compilamos:
Le damos Click a Dimensionar y le colocaremos que queremos una Matriz de 4x4
Veamos los Resultados
Ya vimos que sirve el Botton de Dimensionar ahora llenemos la Tabla de Datos para la matriz y le damos click en Gauss-Seidel para solucionar el Sistema de Ecuaciones
ahora comprobemos los resultados con alguna fuente externa como lo puede ser una calculadora de matrices en linea
Y veamos los Resultados
Efectivamente son los Mismos.
Pues nada eso es todo espero les halla Servido, se que esta super talachudo el Programa pero Al menos Soluciona Sistemas de Ecuaciones de NxN así que creo vale la pena o eso parece jeje nos vemos y gracias por leer.
Comentarios
Publicar un comentario