Variablen Gleichungen lösen

inixweiss

Mitglied
a+b-c-j=0
c+i-d-e=0
e+g-f=0
j-g-h-i=0

bekannt:
a=10
b=7
d=3
e=2
f=3
j=14

Wie bestimmt man die Unbekannten programmatisch mit welchen Verfahren?
 
Zuletzt bearbeitet:

KonradN

Super-Moderator
Mitarbeiter
Wo ist denn das Problem? Setz die bekannten Zahlen ein. Dann hast Du in der ersten Gleichung nur noch eine Unbekannte (c) die Du dann direkt berechnen kannst, in dem Du die Methode nach c umstellst.
Damit hast Du in der zweiten Gleichung auch nur noch eine Unbekannte (i), die Du dann berechnen kannst.
Bei der dritten Gleichung hast du von Anfang an nur eine Unbekannte...
Bei der letzten Gleichung hast Du dann - nach der Berechnung durch die ersten drei Gleichungen - auch nur eine Unbekannte und damit hast Du direkt die Lösung.
 

KonradN

Super-Moderator
Mitarbeiter
Wenn man diesen Lösungsweg begriffen hat, dann ist die Frage, wie die Anforderung ganz genau ist. Das Beispiel ist halt relativ trivial zu lösen, da Du nie mehr wie eine Unbekannte pro Formel hast. Das muss aber so nicht sein. Ebenso ist die Frage: Ist die Anzahl der Variablen konstant? Du hast immer genau 4 Variablen. Das kann es etwas einfacher machen.

Die Analyse, was Du da hast, ist einfach:
  • VariablerAusdruck: Du hast immer eine Konstante * Variable.
  • KonstanterAusdruck: Das ist dann eine Zahl, die gegeben wurde.
  • Formel: Die Summe mehrere Ausdrücke (Ausdruck ist entweder ein Variabler Ausdruck oder ein Konstanter Ausdruck) = 0

Das Vorgehen oben, das wir manuell ausgeführt haben, ist dann einfach:
  • Du fügst bekannte Variablen ein. Damit entfernst Du VariablerAusdruck durch KonstanterAusdruck
  • Dann bringst Du einen KonstanterAusdruck auf die andere Seite (mit Konstante * (-1)) und hast dann eine Formel, die dann einen KonstantenAusdruck ersetzen kann.

Das kann man dann komplett durchgehen. Am Ende kommt dann immer raus, dass Du eine Formel hast mit genau einer Unbekannten. Und dann kannst Du die Lösung immer bei den Formeln einsetzen, mit denen Du einen konstanten Ausdruck ersetzt hast um erneut eine weitere Variable zu bekommen.
 

KonradN

Super-Moderator
Mitarbeiter
Möchte ein Verfahren, dass es für beliebige Gleichungen löst haben.
Und da ist halt ganz wichtig, dass Du den Lösungsweg selbst durchspielst. Nur damit kannst Du dann beobachten, was Du genau hast. Mit welchen Daten arbeitest Du? Wann machst Du was?

Und dann musst Du erfassen, was die Daten sind, mit denen du agierst.

Dann hast Du halt bei "a+b-c-j=0" die Formel: 1 "a" und 1 "b" und "-1" c und "-1" j sind 0.
"a", "b" und "j" kannst Du einsetzen und dann hast Du:
10 + 7 + (-1) "c" -14 = 0
Das C kriegst Du auf die andere Seite und hast dann: 1 "c" = 10 + 7 - 14
Das ist dann berechenbar.

Aber mal angenommen, dass J wäre nicht bekannt. Dann hättest Du bei 1 "c" = 10 + 7 + (-1) j
Wenn da noch keine 1 beim "c" wäre, dann würde man alles teilen...

Das ist dann bei einer anderen Formel einsetzbar.

"c+i-d-e=0" wäre ja gewesen nach einem parsen:
1 "c" + 1 "i" + (-1) "d" + (-1) e = 0
Das obrige "c" kann man einsetzen:
10 + 7 + (-1) "j" + 1 "i" + (-1) "d" + (-1) e = 0
 

inixweiss

Mitglied
#7 ist kein gültiger Pseudocode, mehr ne Ideen beschreibung.

Wenn ich dir einen . auf eine Leinwand malen würde, wäre das dann auch Kunst? Wären die Brötchen dadurch bezahlt?

Ich frage dann mal ChatGpt.
 

inixweiss

Mitglied
Es geht mit dem Gaußschen Eliminationsverfahren (erst wollte mich ChatGpt verarschen und hat Blödsinn ausgegeben):

Entschuldigung für das Missverständnis. Es scheint, als ob du nach einem Lösungsansatz für Gleichungssysteme suchst, bei denen Variablen addiert oder subtrahiert werden. Hier ist ein Beispiel, wie du solche Gleichungssysteme in Java lösen könntest:

Java:
import java.util.Arrays;

public class GleichungssystemLoeser {

    public static double[] loeseGleichungssystem(double[][] matrix) {
        int rows = matrix.length;
        int cols = matrix[0].length - 1; // Letzte Spalte sind Ergebnisse

        for (int i = 0; i < rows; i++) {
            int pivot = i;

            // Suche nach einer nicht-null-Zahl in der Spalte
            while (pivot < cols && matrix[i][pivot] == 0) {
                pivot++;
            }

            if (pivot == cols) {
                // Null-Spalte, keine eindeutige Lösung
                return null;
            }

            // Tausche Zeilen, um die Pivot-Zeile nach oben zu bringen
            double[] temp = matrix[i];
            matrix[i] = matrix[pivot];
            matrix[pivot] = temp;

            // Normalisiere die Pivot-Zeile
            double divisor = matrix[i][i];
            for (int j = i; j <= cols; j++) {
                matrix[i][j] /= divisor;
            }

            // Eliminiere die Pivot-Zeile aus den anderen Zeilen
            for (int j = 0; j < rows; j++) {
                if (j != i && matrix[j][i] != 0) {
                    double factor = matrix[j][i];
                    for (int k = i; k <= cols; k++) {
                        matrix[j][k] -= factor * matrix[i][k];
                    }
                }
            }
        }

        // Extrahiere die Lösungen
        double[] solution = new double[cols];
        for (int i = 0; i < rows; i++) {
            if (matrix[i][i] == 1) {
                for (int j = 0; j < cols; j++) {
                    if (matrix[i][j] != 0) {
                        solution[j] = matrix[i][cols];
                        break;
                    }
                }
            }
        }

        return solution;
    }

    public static void main(String[] args) {
        double[][] matrix = {
            {2, -1, 1, 2},
            {1, 1, -1, 0},
            {3, -2, 2, 3}
        };

        double[] solution = loeseGleichungssystem(matrix);

        if (solution != null) {
            System.out.println("Lösung:");
            for (int i = 0; i < solution.length; i++) {
                System.out.println("x" + i + " = " + solution[i]);
            }
        } else {
            System.out.println("Das Gleichungssystem hat keine eindeutige Lösung.");
        }
    }
}

Dieser Code verwendet das Gaußsche Eliminationsverfahren, um das Gleichungssystem zu lösen, bei dem Variablen addiert oder subtrahiert werden. Die Methode loeseGleichungssystem nimmt eine Matrix als Eingabe, wobei die letzte Spalte die Ergebnisse der Gleichungen enthält. Falls eine eindeutige Lösung existiert, wird ein Array mit den Lösungen zurückgegeben, andernfalls null.

Der main-Teil demonstriert die Verwendung dieser Methode mit einer Beispielmatrix und gibt die Lösungen aus, wenn vorhanden. Beachte, dass dies ein grundlegendes Beispiel ist und spezielle Fälle oder Fehlerbehandlungen möglicherweise nicht abgedeckt sind.
 

KonradN

Super-Moderator
Mitarbeiter
Was genau ist denn an #7 unverständlich? Ich habe zum einen mögliche Datentypen beschrieben und dann, wie man damit operieren kann.

Wenn das nicht ausreicht oder es nicht verstanden wurde, dann kann man gezielt nachfragen. Ein
Wenn ich dir einen . auf eine Leinwand malen würde, wäre das dann auch Kunst? Wären die Brötchen dadurch bezahlt?
hilft weder Dir noch erhöht es die Lust, Dir einfach #7 noch ausführlicher zu schreiben.

Wenn Du mathematische Gleichungen lösen kannst, dann kannst Du Dir überlegen, was Du da genau machst und dieses dann automatisieren. Und wenn die Aufgaben so limitiert sind, wie es scheint (ganz genau wissen wir es nicht, da wir nur ein Beispiel bekommen haben und keine wirkliche Anforderung), dann ist es relativ einfach umzusetzen. Und limitiert würde dann heissen, dass man lediglich Summen von Zahlen oder "Zahl * Symbol" hat mit Symbol einer konkreten unbekannten. Das lässt sich dann relativ simpel umsetzen ohne sowas wie einen Ausführungsbaum aufzubauen und Umformungen hin zu einer Unbekannten sind sehr einfach mit relativ einfachen Mitteln.

Was nicht erwähnt wurde sind halt die Zusammenfassung von Elementen. Wenn das Symbol gleich ist, dann sind die Elemente zusammen zu fassen, indem die Zahl bei der Unbekannten addiert wird. 7x + 3x => 10x

Naja, ist aber auch Blödsinn, weil ich keine Koeffizientenmatrix habe.
Wieso liest Du denn nicht einfach nach, was das gaußsche Eleminationsverfahren ist? Gaußsches Eliminationsverfahren – Wikipedia
Das ist ja genau das, was Du da als Code bekommen hast (Habe ich jetzt nicht komplett geprüft, aber es sieht auf dem Blick danach aus und es ist ja explizit ewähnt.

Da hast Du dann einen fertigen Algorithmus und die Darstellung im Programm wird um einiges einfacher, da Du ja einfach eine Matrix bekommst. Das ist deutlich einfacher darstellbar als eben die Erfassung der Gleichungen rein symbolisch. Letzteres ist aber ein Anfang, wenn man dann ggf. noch mehr mit symbolischer Algebra machen möchte. Das ist ja erweiterbar mit z.B. Polynomen und so.

Und wie Du erkannt hast: Es setzt voraus, dass man die Matrix erstellt. Das wird problematisch, wenn Du die Formeln wirklich so eingeben willst, denn Du musst dann:
  • Alle bekannten Werte einsetzen und die Zahlen auf die andere Seite der Gleichung bringen.
  • Dann für jedes verbliebene Symbol eine Stelle in der Matrix festlegen.
  • Dann Gleichung für Gleichung die Zeilen füllen.
==> Berechnung nach dem Gaußschen Eleminationsverfahren kann los gehen...
 

Barista

Top Contributor
Ich habe nur kurz auf die Wikipedia-Seite zum Gaußschen Verfahren geschaut und kaum was verstanden, ich finde die Wikipedia-Seiten oft unverständlich, typischer Professorenkram, der nicht zur Erklärung dient, sondern zum Ärgern von Studenten und zur Onanie über das eigene Wissen dient.

Ich würde erst mal ein paar Interfaces und Klassen basteln, natürlich unveränderlich, falls Backtracking benötigt wird:
Java:
package org.java_forum.gleichungen_loesen_203373;

/**
 *
 */
public interface Term
{
    Term eval();
}

Java:
package org.java_forum.gleichungen_loesen_203373;

/**
 * {@link Value} or {@link Variable}.
 */
public interface Operand extends Term {


}

Java:
package org.java_forum.gleichungen_loesen_203373;

/**
 * Value
 */
public class Value implements Operand {

    public final int value;

    /**
     * Constructor.
     *
     * @param value
     */
    public Value(final int value) {
        this.value = value;
    }


    @Override
    public Term eval() {
        return this;
    }

    @Override
    public String toString() {
        return String.valueOf( this.value );
    }

}

Java:
package org.java_forum.gleichungen_loesen_203373;

/**
 * This is a term in which variables can be replaced by values.
 *
 * {@link Add} or {@link Subtract} or {@link Variable}.
 */
public interface ReplacableTerm extends Operand {

    Term replace( final Variable variable, final Value value );
}

Java:
package org.java_forum.gleichungen_loesen_203373;

/**
 * Variable.
 */
public class Variable implements ReplacableTerm {

    public final String name;

    /**
     * Constructor.
     *
     * @param name
     */
    public Variable(String name) {
        this.name = name;
    }

    @Override
    public Term eval() {
        return this;
    }

    @Override
    public Term replace(final Variable variable, final Value value) {
        if ( this.equals( variable ) ) {
            return value;
        }
        return this;
    }

    /**
     * Generated by Eclipse
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    /**
     * Generated by Eclipse
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Variable other = (Variable) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return name;
    }

}

Java:
package org.java_forum.gleichungen_loesen_203373;

/**
 * Add
 */
public class Add implements ReplacableTerm {

    public final Term lhs;
    public final Term rhs;

    /**
     * Constructor.
     *
     * @param lhs
     * @param rhs
     */
    public Add(final Term lhs, final Term rhs) {
        this.lhs = lhs;
        this.rhs = rhs;
    }

    @Override
    public Term eval() {
        if (lhs.eval() instanceof Value lhsValue && rhs.eval() instanceof Value rhsValue) {
            return new Value( lhsValue.value + rhsValue.value );
        }
        return this;
    }

    @Override
    public Term replace(final Variable variable, final Value value) {
        final Term lhsReplaced;
        if (lhs instanceof ReplacableTerm lhsReplacableTerm) {
            lhsReplaced = lhsReplacableTerm.replace(variable, value);
        }
        else {
            lhsReplaced = this.lhs;
        }

        final Term rhsReplaced;
        if (rhs instanceof ReplacableTerm rhsReplacableTerm) {
            rhsReplaced = rhsReplacableTerm.replace(variable, value);
        }
        else {
            rhsReplaced = this.rhs;
        }

        return new Add(lhsReplaced, rhsReplaced).eval();
    }

    @Override
    public String toString() {
        return lhs + "+" + rhs;
    }

}

Java:
package org.java_forum.gleichungen_loesen_203373;

/**
 * Subtract
 */
public class Subtract implements ReplacableTerm {

    public final Term lhs;
    public final Term rhs;

    /**
     * Constructor.
     *
     * @param lhs
     * @param rhs
     */
    public Subtract(final Term lhs, final Term rhs) {
        this.lhs = lhs;
        this.rhs = rhs;
    }

    @Override
    public Term eval() {
        if ( lhs.eval() instanceof Value lhsValue && rhs.eval() instanceof Value rhsValue ) {
            return new Value( lhsValue.value - rhsValue.value );
        }
        return this;
    }

    @Override
    public Term replace(final Variable variable, final Value value) {
        final Term lhsReplaced;
        if (lhs instanceof ReplacableTerm lhsReplacableTerm) {
            lhsReplaced = lhsReplacableTerm.replace(variable, value);
        }
        else {
            lhsReplaced = this.lhs;
        }

        final Term rhsReplaced;
        if (rhs instanceof ReplacableTerm rhsReplacableTerm) {
            rhsReplaced = rhsReplacableTerm.replace(variable, value);
        }
        else {
            rhsReplaced = this.rhs;
        }

        return new Subtract(lhsReplaced, rhsReplaced).eval();
    }

    @Override
    public String toString() {
        return lhs + "-" + rhs;
    }

}

Die Term-Objekte würde ich im Code zusammenbauen, ein Parser ist wahrscheinlich nicht gefordert.

Dann die Ersetzungen der Variablen durch Werte auf die Term-Objekte loslassen, das ganze in einer Schleife und eventuell Backtracking.

Dann sollte wahrscheinlich das gewünschte Herauskommen.

Ich sehe gerade, eine Klasse Gleichung habe ich nicht gemacht, kriegst Du sicher selbst hin.
 

KonradN

Super-Moderator
Mitarbeiter
(offtopic) Es gibt viele Wege ein LGS zu bearbeiten. Je nach Struktur der Matrix und Anforderung an die Genauigkeit der Lösung können exakte (z.B. Additions-/Subtraktionsverfahren) oder numerische (die realen Werte werden (zwangsweise) nur angenähert) Verfahren verwendet werden.
Das Themengebiet wird oft einfach als symbolische Algebra oder Symbolische Mathematik bezeichnet. Das ist ein tolles Themengebiet aber setzt zugleich sehr gute Mathematik-Kenntnisse voraus. Aber es sollte klar sein, dass wir mit diesen einfachen Gleichungssystemen nur an der Oberfläche sind und da nicht wirklich tief einsteigen.

Bei der einfachen Aufgabe reicht es, dass man sich überlegt, was man denn da selbst macht, um die Aufgabe zu lösen. Da muss man also nicht wirklich in die CAS (Computer Algebra Systeme) einsteigen. Das sollte durch meine Beiträge #5 (fachlicher Hintergrund) und dann #7ff (mögliche Ideen zur Umsetzung) hoffentlich deutlich geworden sein.
 

Ähnliche Java Themen

Neue Themen


Oben