Seite 1 von 1

Lineares Gleichungssystem lösen

Verfasst: Donnerstag 17. September 2015, 17:33
von Üpsilon
Hallöchen.
Heute in der Schule habe ich versucht, ein LGS zu lösen. Was immer ich auch tat, ich kam immer zu falschen Ergebnissen. Nach einer Stunde Quälerei mit Einsetzungs-, Gleichsetzungs- und Additionsverfahren fiel mir auf, dass ich die Aufgabe falsch abgeschrieben hatte :roll: . Dann wollte ich eigentlich wutentbrannt Amok laufen, aber stattdessen hab ich dieses Programm geschrieben:

Code: Alles auswählen

from __future__ import division, print_function

def liste_mal(zahl, liste):
    return [zahl*i for i in liste]
def liste_plus(a, b):
    return [sum(paar) for paar in zip(a,b)]

def var_eliminieren(lgs):
    erste_zeile = lgs[0]
    lgs_neu = []
    for zeile in lgs[1:]:
        faktor = - zeile[0] / erste_zeile[0]
        erste_zeile_malgenommen = liste_mal(faktor, erste_zeile)
        zeile_neu = liste_plus(erste_zeile_malgenommen, zeile)[1:]
        lgs_neu.append(zeile_neu)
    return lgs_neu
    
def errechne_stufenform(lgs):
    if len(lgs) == 1: return lgs
    return [lgs[0]] + errechne_stufenform(var_eliminieren(lgs))
    
def auffuellen(lgs):
    maxlen = max(len(zeile) for zeile in lgs)
    return [[0]* (maxlen-len(zeile)) + zeile for zeile in lgs]
    
def loese_stufenform(lgs):
    verdreht = [list(reversed(zeile[:-1])) + [zeile[-1]] for zeile in reversed(lgs)]
    rueckeingesetzt = errechne_stufenform(verdreht)
    aufgeloest = [liste_mal(1/zeile[0], zeile) for zeile in rueckeingesetzt]
    loesungen = list(reversed([zeile[-1] for zeile in aufgeloest]))
    return loesungen
    
def loese_lgs(lgs):
    stufenform = errechne_stufenform(lgs)
    return loese_stufenform(auffuellen(stufenform))
    
print(loese_lgs([[-1,1,-2,-5], [0,3,-1,3], [2,0,1,5]]))
Kritik ist wie immer erwünscht. Lg Y.

PS/Edit: Dies ist mein hundertölfter Beitrag hier. Helau!

Re: Lineares Gleichungssystem lösen

Verfasst: Freitag 18. September 2015, 06:19
von MagBen
Sehr schön, Dein Gleichungslöser rechnet richtig.
So kannst Du das testen

Code: Alles auswählen

import numpy as np
A = [[-1,1,-2], [0,3,-1], [2,0,1]]
b = [-5, 3, 5]
print(np.linalg.solve(A, b)) # [ 1.  2.  3.]
Ich hab's auch mal mit einem anderen Gleichungssystem probiert

Code: Alles auswählen

print(loese_lgs([[-0.1,1,-2,-6,-5], [0,0.3,-1,1.2,3], [0.2,0,1,-2,5], [1,0,-1,0,3.5]])) 
#[11.083916083916066, 25.678321678321687, 7.583916083916087, 2.4003496503496513]
und es stimmt auch da

Code: Alles auswählen

import numpy as np
A = [[-0.1,1,-2,-6], [0,0.3,-1,1.2], [0.2,0,1,-2], [1,0,-1,0]]
b = [-5, 3, 5, 3.5]
print(np.linalg.solve(A, b)) 
# [ 11.08391608  25.67832168   7.58391608   2.40034965]
Üblicherweise wird ein Gleichungssystem in zwei Variablen an einen Löser übergeben:
A: Koeffizientenmatrix
b: rechte Seite

Einen Unterschied zwischen Deinem Löser und dem von Numpy wirst Du sehen, wenn Du das Gleichungssystem größer machst. Probier mal ein Gleichungssystem mit 10 oder mehr Unbekannten.

Re: Lineares Gleichungssystem lösen

Verfasst: Samstag 26. September 2015, 14:41
von Üpsilon
Hat zwar nichts mit dem eigentlichen Thema zu tun, aber ich hab heute noch ein Programm hingerotzt, was mir bei der Klausurvorbereitung hilft, indem es Gleichungssysteme mit "netten" Zahlen auswürfelt. Vielleicht hilft es ja noch jemandem.

Code: Alles auswählen

from random import randint, shuffle
loesungen = [randint(-10,10) for _ in range(3)]
koeffs = list(range(-4,5))
shuffle(koeffs)
for i in range(3):
    zeile = koeffs[3*i:3*i+3]
    erg = sum(a*x for a,x in zip(zeile, loesungen))
    print(zeile, erg)

Re: Lineares Gleichungssystem lösen

Verfasst: Donnerstag 3. Dezember 2015, 22:34
von Üpsilon
Hier mein neuer Lieblings-LGS-Algorithmus. Am Computer zwar nicht wirklich besser, aber egal.

Code: Alles auswählen

from __future__ import division, print_function

def liste_mal(zahl, liste):
    return [zahl*i for i in liste]
def liste_plus(a, b):
    return [sum(paar) for paar in zip(a,b)]

def var_eliminieren(lgs):
    erste_zeile = lgs[0]
    lgs_neu = []
    for zeile in lgs[1:]:
        faktor = - zeile[0] / erste_zeile[0]
        erste_zeile_malgenommen = liste_mal(faktor, erste_zeile)
        zeile_neu = liste_plus(erste_zeile_malgenommen, zeile)[1:]
        lgs_neu.append(zeile_neu)
    return lgs_neu
    
def loese_2er(lgs):
    # Doppelkreuz-Formel, Herleitung trivial
    [[a,b,c],[d,e,f]] = lgs
    y = (a*f - c*d) / (a*e - b*d)
    x = (c - b*y) / a
    return y
    
def errechne_2er(lgs):
    if len(lgs) == 2: return lgs
    return errechne_2er(var_eliminieren(lgs))
    
def einsetzen(lgs, spalte, wert):
    return [zeile[:spalte] + zeile[spalte+1:-1] + [zeile[-1] - zeile[spalte]*wert] for zeile in lgs]
    
def loese_lgs(lgs):
    loesungen = []
    while len(lgs) != 1:
        z = loese_2er(errechne_2er(lgs))
        loesungen = [z] + loesungen
        lgs = einsetzen(lgs, len(lgs)-1, z)[:-1]
    return [lgs[0][1]/lgs[0][0]] + loesungen
    
lgs = [[-1,1,-2,-5], [0,3,-1,3], [2,0,1,5]]
print(loese_lgs(lgs))
lgs = [[1,1,1,1,5],[8,4,2,1,16],[-1,1,-1,1,1],[3,-2,1,0,8]]
print(loese_lgs(lgs))
lgs = [[8,4,2,1,0],[1,1,1,1,-3],[3,2,1,0,0],[6,2,0,0,0]]
print(loese_lgs(lgs))

Re: Lineares Gleichungssystem lösen

Verfasst: Samstag 19. Dezember 2015, 19:10
von pixewakb
Ihr kennt??? http://docs.sympy.org/dev/modules/solvers/solvers.html

Übrigens finde ich den ersten Post mit der A***-Redewendung und dem Benutzer, der seinen Wohnort angibt (Mainz?), schwierig. Möglicherweise möchtest Du Deinen Beitrag überarbeiten.

BTW: Die Code auswählen-Box müsste mal überarbeitet werden. Es ist sonst Glückssache, die richtige Option zu finden.