Fehlermeldung Array zuweisen und printen

C.B.

Aktives Mitglied
Hallo zusammen,

ich bekomme beim printen von meinem array diese Fehlermeldungen und ich denke es liegt an der Zuweisung von den Werten also an der Methode setValues().

Ich weiß aber nicht warum, könnt ihr mir helfen?

Vielen Dank

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at Implementation.Adjazenmatrix.setValues(Adjazenmatrix.java:14)
at Implementation.Adjazenmatrix.main(Adjazenmatrix.java:57)



Java:
package Implementation;

public class Adjazenmatrix {
    
    //Attribute
    int n; // Anzahl der Knoten
    private double[][] adjazenmatrix = new double[n][n];

    public Adjazenmatrix(int n) {
        this.n = n;
    }
    
    public void setValues(int row, int column, double value) {
        adjazenmatrix[row][column]= value;   
    }
    
    public void printMatrix() {
        for (int i = 0; i<=adjazenmatrix.length;i++) {
            for(int j=0; j<=adjazenmatrix[i].length;j++) {
                System.out.print(adjazenmatrix[i][j]);
            }
        }
    }
        
    boolean isConnected (int i, int j) {
        boolean connected = false;
    if(adjazenmatrix[i][j]!=0.0) {
        connected = true;
    }
        else {
            connected = false;

        }
            return connected;
        }
    

    
    //void complement() {
        
//    }
    

//gibt es einen Pfad im Graphen von dem Knotten i zum Knoten j?
//boolean isReachable(int i, int j) {
//}


        
        
    public static void main(String[] args) {
        
        //ungerichtete Matrix
        Adjazenmatrix a1 = new Adjazenmatrix(5);
        
        //0te Reihe
        a1.setValues(0,1,1.0);
        a1.setValues(0,4,1.0);
        
        //not connected, value 0.0
        a1.setValues(0,0,0.0);
        a1.setValues(0,2,0.0);
        a1.setValues(0,3,0.0);

        
        
        //1te Reihe
        a1.setValues(1,0,1.0);
        a1.setValues(1,2,1.0);
        a1.setValues(1,4,1.0);
        
        //not connected, value 0.0
        a1.setValues(1,1,0.0);
        a1.setValues(1,3,0.0);
        
        
        //2te Reihe
        a1.setValues(2,1,1.0);
        a1.setValues(2,3,1.0);
        a1.setValues(2,4,1.0);
        
        //not connected, value 0.0
        a1.setValues(2,0,0.0);
        a1.setValues(2,2,0.0);
        
        
        
        //3te Reihe
        a1.setValues(3,2,1.0);
        a1.setValues(3,4,1.0);
        
        
        //not connected, value 0.0
        a1.setValues(3,0,0.0);
        a1.setValues(3,1,0.0);
        a1.setValues(3,3,0.0);

        
        
    
        
        //4te Reihe
        a1.setValues(4,0,1.0);
        a1.setValues(4,1,1.0);
        a1.setValues(4,2,1.0);
        a1.setValues(4,3,1.0);
        
        //not connected, value 0.0
        a1.setValues(4,4,0.0);

        
        a1.printMatrix();
                
        
}
}
 
Hier musst du auf die Reihenfolge achten, in der die Elemente angelegt werden:
Java:
    int n; // Anzahl der Knoten
    private double[][] adjazenmatrix = new double[n][n];

    public Adjazenmatrix(int n) {
        this.n = n;
    }
Es wird zuerst n= 0 gesetzt,
dann wird ein Array mit Größe 0x0 erzeugt
und erst dann wird im Konstruktor n auf den übergebenen Wert gesetzt.
 
Hier musst du auf die Reihenfolge achten, in der die Elemente angelegt werden:
Java:
    int n; // Anzahl der Knoten
    private double[][] adjazenmatrix = new double[n][n];

    public Adjazenmatrix(int n) {
        this.n = n;
    }
Es wird zuerst n= 0 gesetzt,
dann wird ein Array mit Größe 0x0 erzeugt
und erst dann wird im Konstruktor n auf den übergebenen Wert gesetzt.
Ah super danke🙂
 
Hier musst du auf die Reihenfolge achten, in der die Elemente angelegt werden:
Java:
    int n; // Anzahl der Knoten
    private double[][] adjazenmatrix = new double[n][n];

    public Adjazenmatrix(int n) {
        this.n = n;
    }
Es wird zuerst n= 0 gesetzt,
dann wird ein Array mit Größe 0x0 erzeugt
und erst dann wird im Konstruktor n auf den übergebenen Wert gesetzt.
Und du solltest < statt <= benutzen!
Dankeschön🙂
 
Java:
public class Adjazenmatrix {
    
    //Attribute
    int n; // Anzahl der Knoten
    private double[][] adjazenmatrix;

    public Adjazenmatrix(int n) {
       this.n = n;
       adjazenmatrix = new double[n][n];
        
    }
 
Ich habe jetzt noch eine gerichtete Matrix ergänzt und möchte eine Methode is reachable() einführen.
Damit möchte ich herausfinden ob ein Startknoten über andere Knoten indirekt mit einem Zielknoten verbunden ist.

Leider weiß ich gar nicht wie ich hier vorgehen soll. Ich habe mal ein Bild angehängt, von der Tabelle und vom Graphen.

Beispielsweise ist v0 indirekt mit v4 verbunden über v1 und v2. Hier sollte die Methode true liefern.
Aber v3 kann beispielsweise über keinen anderen Knoten v0 erreichen. Hier gibt es keinen Weg. Da sollte die Methode false liefern. Ist diese Methode mit Schleifen und if Bedingungen umsetzbar?

Mein bisheriger Code lautet:

Java:
package Implementation;
import java.util.Arrays;

public class Adjazenmatrix {
    
    //Attribute
    int n; // Anzahl der Knoten
    private double[][] adjazenmatrix;

    public Adjazenmatrix(int n) {
        this.n = n;
        adjazenmatrix = new double[n][n];

    }
    
    public void setValues(int row, int column, double value) {
        adjazenmatrix[row][column]= value;   
    }
    
    public void printMatrix() {
        
        // System.out.println("Matrix: "+Arrays.deepToString(adjazenmatrix));
            
        
        for (int i = 0; i<adjazenmatrix.length;i++) {
            System.out.println(" ");
            for(int j=0; j<adjazenmatrix[i].length;j++) {
                System.out.print(adjazenmatrix[i][j]+" ");
            }
        }
    }
        
    boolean isConnected (int i, int j) {
        boolean connected = false;   
        //nicht verbundene Kanten haben den default Wert 0
        if(adjazenmatrix[i][j]!=0.0) {
        connected = true;
    }
        else {
            connected = false;

        }
            return connected;
        }
    

    
    //void complement() {
        
//    }
    

//gibt es einen Pfad im Graphen von dem Knotten i zum Knoten j?

    boolean isReachable(int startKnoten, int zielKnoten) {
        boolean reachable = false;
        
        

        return reachable;
        
}


        
        
    public static void main(String[] args) {
        
        //ungerichtete Matrix
        Adjazenmatrix a1 = new Adjazenmatrix(5);
        
        //0te Reihe
        a1.setValues(0,1,1.0);
        a1.setValues(0,4,1.0);
        
        //1te Reihe
        a1.setValues(1,0,1.0);
        a1.setValues(1,2,1.0);
        a1.setValues(1,4,1.0);
            
        //2te Reihe
        a1.setValues(2,1,1.0);
        a1.setValues(2,3,1.0);
        a1.setValues(2,4,1.0);   
        
        //3te Reihe
        a1.setValues(3,2,1.0);
        a1.setValues(3,4,1.0);   
        
        //4te Reihe
        a1.setValues(4,0,1.0);
        a1.setValues(4,1,1.0);
        a1.setValues(4,2,1.0);
        a1.setValues(4,3,1.0);
        

        //Methodenausgabe
        a1.printMatrix();
        
        System.out.println("\n"+"\n"+a1.isConnected(0, 0));
                
        
        //gerichtete Matrix
                Adjazenmatrix a2 = new Adjazenmatrix(5);
                //0te Reihe
                a2.setValues(0,1,1.0);
                
                //1te Reihe
                a2.setValues(1,2,1.0);
                a2.setValues(1,4,1.0);
                    
                //2te Reihe
                a2.setValues(2,3,1.0);
                a2.setValues(2,4,1.0);   
                
                //3te Reihe
    
                
                //4te Reihe
                a2.setValues(4,0,1.0);
                a2.setValues(4,3,1.0);
                
            a2.printMatrix();
                
            System.out.println("\n"+"\n"+a2.isConnected(0,1));
                        
                
}
}

1629050403525.png
 
Dies in einer Methode zu realisieren, dürfte schwierig sein.
Du kannst aber - analog zur Adjazenzmatrix - eine "Erreichbarkeitmatrix" definieren und sie füllen.
Zunächst ist jeder Knoten von sich selber aus (in null Schritten) erreichbar - du fülltst also die Diagonale mit "true".
Dann sind in einem Schritt alle Knoten erreichbar, die in der Adjazensmatrix stehen.
Dann untersuchst du die Knten, die in zwei Schritten erreichbar sind: Zum Beispiel ist vom Knoten 0 der Knoten 1 erreichbar, und von Knoten 1 sind die Knoten 2 und 4 erreichbar; also sind von Knoten 0 auch die Knoten 2 und 4 erreichbar.
Das führst du so lange fort, bis kein neuer Eintrag gefunden wurde. Im schlimmsten Fall muss du so viele Iterationen durchführen, wie du Knoten hast.
 
Dies in einer Methode zu realisieren, dürfte schwierig sein.
Mit ein wenig Rekursion ist das doch recht einfach, zumindest wenn man keine besonderen Anforderungen an die Laufzeit stellt:
Code:
Algorithmus erreichbar(start, ziel) {
    Für jedes von start aus direkt erreichbare Ziel z wiederhole
        Falls z == ziel, dann gib true zurück

    Für jedes von start aus direkt erreichbare Ziel z wiederhole
        Falls erreichbar(z, ziel), dann gib true zurück

    gib false zurück
}
 
Mit ein wenig Rekursion ist das doch recht einfach, zumindest wenn man keine besonderen Anforderungen an die Laufzeit stellt:
Code:
Algorithmus erreichbar(start, ziel) {
    Für jedes von start aus direkt erreichbare Ziel z wiederhole
        Falls z == ziel, dann gib true zurück

    Für jedes von start aus direkt erreichbare Ziel z wiederhole
        Falls erreichbar(z, ziel), dann gib true zurück

    gib false zurück
}
Vielen Dank. Mit Rekursion bin ich noch nicht so vertraut aber ich versuche mich mal daran.
 
Habe es nun mit Rekursion probiert und ich denke es funktioniert nun. Habe es getestet und es kommen die richtigen Ergebnisse raus. Anbei nochmal der funktionierende Code. Gibt es noch Anmerkungen?

Java:
boolean isReachable(int start, int ziel) {
        boolean reachable=false;
        if(adjazenmatrix[start][ziel]==1.0) {
            reachable=true;
        }
        else {
        for (int i=0; i <adjazenmatrix.length; i++) {
            if(adjazenmatrix[start][i]==1.0) {
                if(isReachable(i,ziel)==true) {
                    reachable= true;
                }
            }
        }
        }
        return reachable;
    }
 
Mit deinem Code kannst du in eine Unendlichschleife laufen.
Probiere doch nur in dem einfachen Graphen, ob du von 0 nach 2 kommst:
Code:
0 <--> 1 --> 2
 
Das stimmt bei einem ungerichteten Graphen würde ich in eine unendlich Schleife laufen, da alle Knoten erreichbar sind. Wie könnte ich das verhindern? Durch einen Zähler?
 
Noch zwei Bemerkungen (nachdem ich den Code mal ausprobiert habe):

1. Eine Unendlichschleife bekommst du noch nicht beim (gerichteten) Graphen 0 <--> 1 --> 2
jedoch beim Graphen 0 <--> 1 --> 2 --> 3, wenn du nach einer Verbindung von Knoten 0 zu Knoten 3 fragst.
Dieser Graph hat die Adjazensmatrix:
Code:
{
{0, 1, 0, 0},
{1, 0, 1, 0},
{0, 0, 0, 1},
{0, 0, 0 ,0}
}

2. Du könntest (in sehr, sehr uneffektiver Weise) das Problem mit der Unendlichschleife tatsächlich mit einem Zähler lösen. Wenn die Rekursionstiefe größer ist als die Anzahl der Knoten in deinem Graphen, hast du garantiert einen Knoten doppelt besucht und kannst abbrechen.
Im Grunde machst du (bisher) eine Tiefensuche; dabei können allerdings unendlich lange Zweige vorkommen. Wenn du diese unendlich langen Zweige bei der Anzahl der Knoten in deinem Graphen abschneidest, hast du wieder ein endliches Problem.
 
Noch zwei Bemerkungen (nachdem ich den Code mal ausprobiert habe):

1. Eine Unendlichschleife bekommst du noch nicht beim (gerichteten) Graphen 0 <--> 1 --> 2
jedoch beim Graphen 0 <--> 1 --> 2 --> 3, wenn du nach einer Verbindung von Knoten 0 zu Knoten 3 fragst.
Dieser Graph hat die Adjazensmatrix:
Code:
{
{0, 1, 0, 0},
{1, 0, 1, 0},
{0, 0, 0, 1},
{0, 0, 0 ,0}
}

2. Du könntest (in sehr, sehr uneffektiver Weise) das Problem mit der Unendlichschleife tatsächlich mit einem Zähler lösen. Wenn die Rekursionstiefe größer ist als die Anzahl der Knoten in deinem Graphen, hast du garantiert einen Knoten doppelt besucht und kannst abbrechen.
Im Grunde machst du (bisher) eine Tiefensuche; dabei können allerdings unendlich lange Zweige vorkommen. Wenn du diese unendlich langen Zweige bei der Anzahl der Knoten in deinem Graphen abschneidest, hast du wieder ein endliches Problem.
Hab bisschen rumprobiert aber klappt nicht so recht. An welcher Stelle würdest du den Counter setzen?
 
Hab bisschen rumprobiert aber klappt nicht so recht. An welcher Stelle würdest du den Counter setzen?
Funktioniert nun 🙂

Java:
//Counter um zu verhindern, dass die Rekursion bei ungerichteten Graphen unendlich läuft (besuchte Zeilen zählen)
    int counter=0;
    boolean isReachable(int start, int ziel) {   
        //Counter damit Rekursion nicht endlich läuft
        counter++;
        if(adjazenmatrix[start][ziel]==1.0) {
            return true;   
        }
        
        else if (counter>adjazenmatrix.length) {
            return false;
        }
        
        else {
        for (int i=0; i<adjazenmatrix.length; i++) {
            if(adjazenmatrix[start][i]==1.0) {
                if(isReachable(i,ziel)==true){
                    return true;
                }
                
            }
        }
        }
        return false;
    }
 

Zurück
Oben