# Variablen einmal nur zu weisen



## linomail (1. Sep 2017)

Hallo,

ähm ich bräuchte bei folgender Aufgabe eure Hilfe.

Ich hab eine Methode geschrieben die Kanten in einer XML Datei reinschreibt und sie funktioniert.

Die XML Datei benutze ich als "Datenbank". Ich möchte mit einer Software das TSP-Problem lösen. Dabei ist mir aufgefallen wenn ich die Kanten erstelle(Straßen) dann weist er ab und zu eine Straße doppelt zu. 

Meine Kanten haben die Information von Quelle bis Ziel. Also das bedeutet er nimmt aus der Klasse Stadt eine Stadt als Quelle und eine Stadt als Ziel. Damit die Stadt nicht sowohl wie Ziel und Quelle eingetragen wird, habe ich schon bereits eine Lösung gefunden.

Jetzt suche eine Lösung wie ich das Problem verhindere, dass eine Straße doppelt eingetragen wird. 

1. Road = Name: City4 , X: 59 , Y: 350 --> Name: City0 , X: 128 , Y: 266
2. Road = Name: City2 , X: 317 , Y: 294 --> Name: City5 , X: 86 , Y: 34
3. Road = Name: City5 , X: 86 , Y: 34 --> Name: City9 , X: 215 , Y: 441
4. Road = Name: City4 , X: 59 , Y: 350 --> Name: City5 , X: 86 , Y: 34
5. Road = Name: City9 , X: 215 , Y: 441 --> Name: City5 , X: 86 , Y: 34
6. Road = Name: City2 , X: 317 , Y: 294 --> Name: City0 , X: 128 , Y: 266
7. Road = Name: City0 , X: 128 , Y: 266 --> Name: City5 , X: 86 , Y: 34
8. Road = Name: City8 , X: 314 , Y: 413 --> Name: City2 , X: 317 , Y: 294
9. Road = Name: City2 , X: 317 , Y: 294 --> Name: City4 , X: 59 , Y: 350
10. Road = Name: City0 , X: 128 , Y: 266 --> Name: City5 , X: 86 , Y: 34

Das sind meine Straßen, die mein Programm zufällig erstellt. X und Y sind die Koordinaten.

Hier zum Beispiel sind Road 7 und Road 10 doppelt. Wie kann ich das verhindern? 

Die Idee ist das jede Stadt einmal als Quelle und einmal als Ziel eingetragen wird.

Könnte mir da jemand helfen?

Falls es nötig ist, füge ich mein Programmcode ein.

Wäre schön, wenn mir jemand helfen könnte...


----------



## JStein52 (1. Sep 2017)

linomail hat gesagt.:


> Hier zum Beispiel sind Road 7 und Road 10 doppelt. Wie kann ich das verhindern?


Indem du entsprechend abprüfst. Aber ohne Code und Daten zu kennen ist das jetzt nicht genauer zu sagen.


----------



## linomail (1. Sep 2017)

JStein52 hat gesagt.:


> Indem du entsprechend abprüfst. Aber ohne Code und Daten zu kennen ist das jetzt nicht genauer zu sagen.



Meinst du vill, dass ich eine Methode schreibe, die alle Straßen abruft und dann diese vergleicht?


----------



## linomail (1. Sep 2017)

```
public void fillRandom(){

        Random random = new Random();

        //Die Schleife geht solange bis sie die Größe erfüllt hat
        for (int i = 0; i < cities.length; i++){
            //jetzt eine Grenze def.
            int xPos = random.nextInt(500);
            int yPos = random.nextInt(500);
            cities[i] = new City("City" + i, xPos, yPos);
        }


        //die Straßen werden hier def. angelehnt an den Cities, wegen Q ---> Z
        for (int i = 0; i < roads.length; i++){
            int s = random.nextInt(cities.length);
            int t = random.nextInt(cities.length);

            int counter = 0;
            //solange sie gleich sind soll die schleife gehen
            while (s == t && counter < 1000){
                counter++;
                t = random.nextInt(cities.length);
            }
            if (s != t) {
                roads[i] = new Road(cities[s], cities[t]);
            }
        }
```


----------



## linomail (1. Sep 2017)

So fülle ich die Punkten und Kanten


----------



## Joose (1. Sep 2017)

Ja, bevor du eine neue Road zum Array hinzufügst sollst du natürlich prüfen ob so eine schon existiert!
Achtung: wahrscheinlich gilt zu beachten dass eine Straße gleich ist egal in welche Richtung es geht (also zwischen City0 -> City5 ist dieselbe Straße wie City5 -> City0)


----------



## JStein52 (1. Sep 2017)

Joose hat gesagt.:


> Ja, bevor du eine neue Road zum Array hinzufügst sollst du natürlich prüfen ob so eine schon existiert!


Bei den Cities kann es ja theoretisch auch passieren dass City0 und City9 auf denselben Koordinaten liegen. Hier solltest du auch prüfen dass jede City einen gewissen Abstand von allen anderen hat.


----------



## linomail (1. Sep 2017)

Joose hat gesagt.:


> Ja, bevor du eine neue Road zum Array hinzufügst sollst du natürlich prüfen ob so eine schon existiert!
> Achtung: wahrscheinlich gilt zu beachten dass eine Straße gleich ist egal in welche Richtung es geht (also zwischen City0 -> City5 ist dieselbe Straße wie City5 -> City0)



Hättest du grob ein Beispiel? Wüsste jetzt nicht wie ich das schreiben soll. 
Stimmt diesen Fehler hab ich gar nicht beachtet Das macht meine Idee grade ein bisschen kaputt. Wahrscheinlich sollte ich einfach, wenn ich die xml erstelle, dass er nochmal alle vergleicht und an dieser Stelle wieder zufällig ein Punkt generiert bis sie sich unterscheiden. 

Hättet ihr für mich ein Beispiel ?


----------



## JStein52 (1. Sep 2017)

linomail hat gesagt.:


> roads[i] = *new* Road(cities[s], cities[t]);


Du solltest vor dieser Zeile prüfen ob dein Array schon diese beiden Cities enthält und nicht beim erstellen der xml-Datei


----------



## JStein52 (1. Sep 2017)

linomail hat gesagt.:


> cities[i] = *new* City("City" + i, xPos, yPos);


Und vor dieser Zeile genau so. Der Abstand einer City die schon in dem Array ist zur aktuell gewürfelten City errechnet sich nach Pythagoras zu d = Math.sqrt(deltaX^2 + deltaY^2);
Und wenn der kleiner als z.B. 1 oder so was ist wirfst du die aktuell ermittelten Koordinaten weg und würfelst nochmal.


----------



## JStein52 (1. Sep 2017)

Und implementieren könntest du das indem du für City und Road eine equals(...)-Methode implementierst die das übergebene Objekt mit dem this vergleicht ...


----------



## linomail (1. Sep 2017)

Mh ich versuche dass mal morgen


----------



## linomail (1. Sep 2017)

J


JStein52 hat gesagt.:


> Und implementieren könntest du das indem du für City und Road eine equals(...)-Methode implementierst die das übergebene Objekt mit dem this vergleicht ...


 ja so in der Art hab ich das auch gedacht , ich werde es morgen mal versuchen


----------



## linomail (7. Sep 2017)

JStein52 hat gesagt.:


> Und implementieren könntest du das indem du für City und Road eine equals(...)-Methode implementierst die das übergebene Objekt mit dem this vergleicht ...



kannst du mir vill iwie ein pseudocode machen auf die Schnelle?

Im internet finde ich nur wie man 2 Arrays miteinaander vergleicht aber nicht wie man den Inhalt eines arrays vergleicht.

Da es ja Objekte sind läuft das ein bisschen anders oder nicht?


----------



## JStein52 (7. Sep 2017)

In der Klasse City schreibst du z.B. eine Methode equals die abprüft ob eine Stadt mit ihren Koordinaten genau auf der anderen liegt:

```
public boolean equals(City city) {
           final int distance = 0.001;   // hier musst du dir was sinnvolles für die minimale distanz ausdenken
           if (Math.sqrt((this.xPos - city.xPos)*(this.xPos - city.xPos) + (this.yPos-city.yPos)*(this.yPos-city.yPos)) < distance) {
               return true;
           }
           else {
               return false;
           }
   }
```


----------



## linomail (7. Sep 2017)

JStein52 hat gesagt.:


> In der Klasse City schreibst du z.B. eine Methode equals die abprüft ob eine Stadt mit ihren Koordinaten genau auf der anderen liegt:
> 
> ```
> public boolean equals(City city) {
> ...



fk sry mein Fehler ich meinte die Straßen nicht die Koordinaten, dass habe ich bereits gelöst. Ich meine wo ich die roads_ einträge miteinander vergleiche._


----------



## JStein52 (7. Sep 2017)

Und da wo du eine neue City einfügen willst prüfst du vorher ab ob es die schon in deinem Array gibt:

```
//Die Schleife geht solange bis sie die Größe erfüllt hat
        for (int i = 0; i < cities.length; i++){
            //jetzt eine Grenze def.
            int xPos = random.nextInt(500);
            int yPos = random.nextInt(500);
            City newCity = new City("City" + i, xPos, yPos);
            for(j=0; j<i; j++) {
                if (cities[j].equals(newCity) ) {
                    // mach was
                }
            }
            // wenn es bis hier die gleiche City noch nicht gab dann einfügen
        }
```


----------



## linomail (7. Sep 2017)

JStein52 hat gesagt.:


> Und da wo du eine neue City einfügen willst prüfst du vorher ab ob es die schon in deinem Array gibt:
> 
> ```
> //Die Schleife geht solange bis sie die Größe erfüllt hat
> ...



Nein das meinte ich nicht ich meine sowas in der Art


```
if (s != t && !roads.equals(roads)) {


                        roads[i] = new Road(cities[s], cities[t]);
                    }
```

er soll nicht die gleichen Reinschreiben ja gut, dass löst nicht das problem mit City 0 ---> City 1  City 1<---0 aber es wäre ein anfang das er wenigstens die doppelten nicht reinschreibt nur leider weiß ich echt nicht wie ich das implementieren.


----------



## JStein52 (7. Sep 2017)

Ah ok. Aber Roads geht sinngemaess genau so. Eine Road hat ja scheinbar je eine City als Anfangs- und Endpunkt.
Und im equals für Road kannst du ja this.city_1.getName() und road.city_1.getName() miteinander vergleichen.


----------



## JStein52 (7. Sep 2017)

du kannst doch wieder hier wo du sie einfügen willst vorher gucken ob diese schon drin ist:

```
if (s != t) {
                Road newRoad = new Road(cities[s], cities[t]);
                for (k=0; k<i; k++) {
                   if (roads[k].equals(newRoad)) {
                       // Strasse gibts schon, etwas tun
                   }
                }
                // wenn du hier her kommst und es gab die Strasse noch nicht dann einfügen
                roads[i] = newRoad;
            }
```

Edit: und das equals für Road musst du halt so aufbauen dass es die Namen der Städte der Endpunkte jeweils für this und die übergebene Stadt miteinander vergleicht


----------



## linomail (7. Sep 2017)

JStein52 hat gesagt.:


> du kannst doch wieder hier wo du sie einfügen willst vorher gucken ob diese schon drin ist:
> 
> ```
> if (s != t) {
> ...




iwie macht das für mich kein Sinn.
roads[k] gibt es doch gar nicht ich meine ok oben ist k defeniert aber im array steht doch nix oO


----------



## JStein52 (7. Sep 2017)

Doch, in roads gibt es i Elemente. Und mit k durchläufst du die alle nacheinander


----------



## linomail (22. Sep 2017)

JStein52 hat gesagt.:


> Doch, in roads gibt es i Elemente. Und mit k durchläufst du die alle nacheinander



hab mich jetzt doch für Hashset entschieden  da ich hier nicht extra eine Methode schreiben muss damit bei equals true raus kommt.

Komme aber hier auch nicht weiter... ich arbeite das 1. mal mit dem set und fand es einfach nützlicher 

```
public void fillRandom() {

        Random random = new Random();

        //passt da array bei 0 anfängt und lenght 1
        for (int i = 0; i < cities.length; i++) {

            //Grenze ist 500
            int xPos = random.nextInt(500);
            int yPos = random.nextInt(500);

            //trag sie im Array ein
            cities[i] = new City("City" + i, xPos, yPos);
        }

        //für Road
        for (int i = 0; i < roads.length; i++) {

            //vergibt zufällig namen der Citys
            int s = random.nextInt(cities.length);
            int t = random.nextInt(cities.length);

            int counter = 0;

            while (s == t && counter < 1000) {

                //vergibt ihm ne neue City
                counter++;
                t = random.nextInt(cities.length);
            }

            if (s != t) {

                Road newRoad = new Road(cities[s], cities[t]);

                Set<Road> set = new HashSet<>();
                set.add(newRoad);

               Road[] road = set.toArray(new Road[set.size()]);

               System.out.println(road);
            }
        }
```

so sieht das ganze aus ich weiß das die Implementierung was fehlt  und zwar bei set.toArray 

denn als ausgabe bekomme ich jetzt sowas 

```
[LRoad;@1540e19d
[LRoad;@14ae5a5
[LRoad;@6d6f6e28
[LRoad;@45ee12a7
[LRoad;@2503dbd3
[LRoad;@7ea987ac
[LRoad;@29453f44
[LRoad;@6e0be858
[LRoad;@610455d6
[LRoad;@60e53b93
[LRoad;@1d44bcfa
[LRoad;@6f94fa3e
[LRoad;@66d3c617
[LRoad;@2b193f2d
[LRoad;@4dc63996
[LRoad;@6ff3c5b5
[LRoad;@4b1210ee
[LRoad;@3cd1a2f1
[LRoad;@7440e464
[LRoad;@78308db1
```


----------



## JStein52 (22. Sep 2017)

Hat Road eine sinnvolle toString()-Methode ? So wie du es hast scheint er die von Object geerbte zu nehmen und die gibt einfach die Referenz ( sowas wie eine Adresse) aus.


----------



## linomail (22. Sep 2017)

JStein52 hat gesagt.:


> Hat Road eine sinnvolle toString()-Methode ? So wie du es hast scheint er die von Object geerbte zu nehmen und die gibt einfach die Referenz ( sowas wie eine Adresse) aus.



naja hatte vorher diese für array 
	
	
	
	





```
/**
* Die Elemente werden einem String überschrieben
* @return : z.B City1 -----> City 2
*/
@Override
public String toString(){

    return sourceCity.toString() + "------>" + targetCity.toString();
}
```


----------



## linomail (22. Sep 2017)

bin schon echt am ende :*D mit meiner Geduld und java xD


----------



## linomail (22. Sep 2017)

ich kann dir ja mal mein orginal code schicken ohne das set oder iwas quasi das wo ich angefangen hab ne Lösung zu suchen 


```
import java.awt.*;
import java.util.Random;

/**
* Created by AS on 07.05.2017.
*/
//Die Hauptklasse der TSP-Software
public class Map {

    private double costs[][];

    //2 Arrays Cities und Roads(Kanten)
    City[] city;
    Road[] roads;

    //Konstruktor wartet auf die Größe der beiden Arrays und erzeugt diese auch
    public Map(int cityLength, int roadLength) {
        city = new City[cityLength];
        roads = new Road[roadLength];
    }

    //Der Generator füllt die Arrays mit Werten
    public void fillRandom() {

        Random random = new Random();

        for (int i = 0; i < city.length; i++) {
            int xPos = random.nextInt(500);
            int yPos = random.nextInt(500);
            city[i] = new City("City" + i, xPos, yPos);

        }

        for (int i = 0; i < roads.length; i++) {
            int s = random.nextInt(city.length);
            int t = random.nextInt(city.length);

            int counter = 0;
            while (s == t && counter < 1000) {
                counter++;
                t = random.nextInt(city.length);
            }
            if (s != t) {
                roads[i] = new Road(city[s], city[t]);
            }

        }

        outPutCoords();
    }
    public String getCoord(City city)
    {
        return "X" + city.xPos +
                "Y" + city.yPos;
    }

    public void outPutCoords()
    {
        for (int i = 0; i < city.length; i++)
        System.out.println("" + getCoord(city[i]));
    }

    //Rückgabewert der amountCities
    public int amountCities() {
        return city.length;

    }

    //Rückgabewert der amountRoads
    public int amountRoads() {
        return roads.length;
    }

    //Rückgabewert der Road
    public Road returnRoad(int i) {
        if (i < 0 || i >= roads.length)
            return null;
        return roads[i];
    }

    //Rückgabewert der City
    public City returnCity(int i) {
        if (i < 0 || i >= city.length)
            return null;

        return city[i];
    }



    public void paintCity(Graphics g){

        int i = 0;

        do {
            city[i].paintCity(g);
            i++;
        }
        while (i < city.length);

    }



    public void paintRoads(Graphics g)
    {

        int i = 0;

        do {
            roads[i].paintRoad(g);
            i++;
        }
        while (i < roads.length);
    }

   // public double calcCost(int route){
  //  return calcCost(route, false);
    //}

    //public double calcCost(int route, boolean isVerbosse){
      //  double travelcost = 0;
  //      for (int i = 1; i < route.length; i++){
    //        travelcost += costs[route[i-1]][route[i]];
      //  }
    //}

    private double distance(int s1, int s2)
    {
        double dx, dy, dx2, dy2;

        dx = city[s1].xPos - city[s2].xPos;
        dy = city[s1].yPos - city[s2].yPos;
        dx2 = dx * dx;
        dy2= dy *dy;

        return Math.sqrt(dx2 + dy2);
    }



    public int nextCity(int s) {
        double dist, min = 100000;
        int index = -1;

        int start = 0;

        while (start < amountCities()) {
            while ((start < amountCities()) && city[start].inTour) start++;

            if (start >= amountCities()) {
                break;
            }

            dist = distance(start, start);

            if ((start != s) && (dist < min)) {
                min = dist;
                index = start;
            }
            start++;
        }
        return index;
    }

    public void nearestNeighbour()
    {
        int s = 0;

        for (int i=0; i<city.length - 1; i++)
        {
            city[s].inTour = true;
            city[s].next = nextCity(s);
            s = city[s].next;
        }
        city[s].inTour = true;
        city[s].next = 0;
    }


    public void paint(Graphics g)
    {
     int next = 0;
     int x1, y1, x2, y2;
     do {
         city[next].paintCity(g);
         x1 = city[next].xPos;
         y1 = city[next].yPos;
         next = city[next].next;
         x2 = city[next].xPos;
         y2 = city[next].yPos;
         g.drawLine(x1,y1,x2,y2);
     }
     while (next !=0);

    }







}
```



```
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.awt.*;


/**
* Created by AS on 07.05.2017.
*/
public class City {
    //Datenstrukturen der Cities und um das TSP zu lösen
    String name = "City";
    int xPos, yPos;
    int next;
    boolean inTour;


    //Konstruktor um Cities zu erstellen
    public City(String name, int xPos, int yPos) {
        this.xPos = xPos;
        this.yPos = yPos;

        next = 0;
        inTour = false;
        this.name = name;
    }

    //Methode zum aufbau der XML - Datei/erstellung Eltern --> Kinder
    public void generateXML(Document doc, Element nodes) {
        Element node = doc.createElement("Node");
        nodes.appendChild(node);
        Element name = doc.createElement("Name");
        name.setTextContent(this.name);
        node.appendChild(name);

        Element xPos = doc.createElement("XKoordinate");
        xPos.setTextContent("" + this.xPos);
        node.appendChild(xPos);
        Element yPos = doc.createElement("YKoordinate");
        yPos.setTextContent("" + this.yPos);
        node.appendChild(yPos);


    }

    //Hier werden name xPos und yPos zurückgegeben
    @Override
    public String toString() {
        return "Name: " + name
                + ", X: " + xPos
                + ", Y:" + yPos;
    }


    public void paintCity(Graphics g) {

        g.setColor(Color.RED);
        g.drawOval(xPos, yPos, 10, 10);
        g.setColor(Color.BLACK);
        g.fillOval(xPos, yPos, 10, 10);
        if (inTour)
            g.setColor(Color.blue);
        else
            g.setColor(Color.RED);
        g.drawString(name, xPos-name.length()*4, yPos+20);
        g.drawString(""+name+">"+ next, xPos - name.length() * 4, yPos + 36);
    }


}
```


```
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import java.awt.*;

/**
* Created by AS on 09.05.2017.
*/
public class Road {

    City sourceCity = null;
    City targetCity = null;



    public Road(City sourceCity, City targetCity){
        this.sourceCity = sourceCity;
        this.targetCity = targetCity;


    }

    public void generateXML(Document doc, Element edges)
    {
        Element edge = doc.createElement("Edge");
        edges.appendChild(edge);

        Element source = doc.createElement("Source");
        source.setTextContent("" + sourceCity.name);
        edge.appendChild(source);


        Element target = doc.createElement("Target");
        target.setTextContent("" + targetCity.name);
        edge.appendChild(target);
    }





    @Override
    public String toString()
    {
        return sourceCity.toString()  + " --> " + targetCity.toString()  ;
    }



    public void paintRoad(Graphics g) {

        g.setColor(Color.green);
        g.drawLine(sourceCity.xPos, sourceCity.yPos, targetCity.xPos, targetCity.yPos);


    }
```

Falls du mal ein Abend langeweile hast und du den überblick nicht verlierst haha.


----------



## mrBrown (22. Sep 2017)

versuchs mal statt `System.out.println(road);` mit `System.out.println(Arrays.toString(road));`


----------



## linomail (22. Sep 2017)

mrBrown hat gesagt.:


> versuchs mal statt `System.out.println(road);` mit `System.out.println(Arrays.toString(road));`



ja gut jetzt kann man es lesen haha trotzdem nicht das gewünschte ergebnis


----------



## linomail (22. Sep 2017)

wahrscheinlich brauch ich noch ne Hash-Methode wie ich das jetzt so im Internet lese...


----------



## mrBrown (22. Sep 2017)

linomail hat gesagt.:


> ja gut jetzt kann man es lesen haha trotzdem nicht das gewünschte ergebnis


*Wie* soll es denn aussehen?



linomail hat gesagt.:


> wahrscheinlich brauch ich noch ne Hash-Methode wie ich das jetzt so im Internet lese...


Wenn du HashSets benutzt: Ja.


----------



## linomail (22. Sep 2017)

mrBrown hat gesagt.:


> *Wie* soll es denn aussehen?
> 
> 
> Wenn du HashSets benutzt: Ja.



ja hatte an sowas gedacht


```
@Override
   public boolean equals(Road road){
     return start.equals(road.start) && ende.equals(road.ende) ||
       start.equals(road.ende) && ende.equals(road.start);
   }
   @Override
   public int hashCode(){
     return start.hashCode() + ende.hashCode();
   }
}
```

hab da aber eine fehlermeldung im ersten override


----------



## linomail (22. Sep 2017)

ich hab noch nie mit hashset gearbeitet alle neuland für mich und versuche das ganze grade ehrlich zu verstehen


----------



## linomail (22. Sep 2017)

wenn ich sie im Entwicklungsumgebung genriere sieht sie so aus 

```
@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Map map = (Map) o;

        // Probably incorrect - comparing Object[] arrays with Arrays.equals
        if (!Arrays.equals(cities, map.cities)) return false;
        // Probably incorrect - comparing Object[] arrays with Arrays.equals
        return Arrays.equals(roads, map.roads);
    }

    @Override
    public int hashCode() {
        int result = Arrays.hashCode(cities);
        result = 31 * result + Arrays.hashCode(roads);
        return result;
    }
```


----------



## mrBrown (22. Sep 2017)

Willst du noch mal darlegen, was du überhaupt vor hast?

Deine Benutzung von Set sieht nicht so aus, als hättest du verstanden, wofür die gut sind.


Die autogenerierte equals hast du in der falschen Klasse generiert, ich bezweifle mal, dass du Maps vergleichen willst?
Deine Handgeschriebene sieht besser aus, bis auf den Parameter von equals - der muss Object sein


----------



## linomail (22. Sep 2017)

mrBrown hat gesagt.:


> Willst du noch mal darlegen, was du überhaupt vor hast?
> 
> Deine Benutzung von Set sieht nicht so aus, als hättest du verstanden, wofür die gut sind.
> 
> ...



Ja das ist ja das Problem 

Mein Problemfall ist folgende:
Da ich mit der klasse Random arbeite, kommt es ja ab und zu vor das ich doppelte Werte in meinem Array einstze.

Auf der suche wie ich diese werte meide, bin ich auf Hashset gestoßen.

Wie ich Hashset verstanden hab verhindert er grade das(die doppelten Objekte) Da ich aber keine primitiven Datentype nutze sonder Arrays gestaltet sich das für mich sehr schwierig die Equals Methode zu implementieren. 

Ja das verstehe ich grade nicht so ganz warum ist der Parameter falsch? In diesem fall ist es doch Road? Road ist doch das Objekt was ich vergleichen möchte...


----------



## linomail (22. Sep 2017)

Schande über mich , dass ich das echt nicht raffe


----------



## mrBrown (22. Sep 2017)

linomail hat gesagt.:


> Ja das verstehe ich grade nicht so ganz warum ist der Parameter falsch? In diesem fall ist es doch Road? Road ist doch das Objekt was ich vergleichen möchte...


Um equals zu überschreiben, müssen die Parameter die gleichen sein - und equals ist als equals(Object o) definiert 


linomail hat gesagt.:


> Ja das ist ja das Problem
> 
> Mein Problemfall ist folgende:
> Da ich mit der klasse Random arbeite, kommt es ja ab und zu vor das ich doppelte Werte in meinem Array einstze.
> ...


Im Moment speicherst du eine Road in einem neuem Set, du wirst damit also niemals doppelte finden können, weil niemals zwei in einem Set landen 

Du solltest ein Set haben, in dem du alle Roads sammelst - damit kannst du dann auch feststellen, ob es doppelte gibt.


----------



## linomail (22. Sep 2017)

mrBrown hat gesagt.:


> Um equals zu überschreiben, müssen die Parameter die gleichen sein - und equals ist als equals(Object o) definiert
> 
> Im Moment speicherst du eine Road in einem neuem Set, du wirst damit also niemals doppelte finden können, weil niemals zwei in einem Set landen
> 
> Du solltest ein Set haben, in dem du alle Roads sammelst - damit kannst du dann auch feststellen, ob es doppelte gibt.






```
[Name: City1, X: 436, Y:256------>Name: City9, X: 101, Y:39]
[Name: City8, X: 458, Y:166------>Name: City5, X: 385, Y:417]
[Name: City0, X: 227, Y:332------>Name: City6, X: 242, Y:392]
[Name: City1, X: 436, Y:256------>Name: City9, X: 101, Y:39]
[Name: City1, X: 436, Y:256------>Name: City8, X: 458, Y:166]
```

naja ich sehe das er 2mal city1 ---> city 9 gespeichert hat (das ist die Ausgabe des Sets)


----------



## mrBrown (22. Sep 2017)

Wie sehen denn equals und hashcode in Road aus?


----------



## linomail (22. Sep 2017)

```
public class Road{
   City sourceCity, targetCity;

   //...
   @Override
   public boolean equals(Object o){
     return sourceCity.equals(road.sourceCity) && targetCity.equals(road.targetCity) ||
       sourceCity.equals(road.targetCity) && targetCity.equals(road.sourceCity);
   }
   @Override
   public int hashCode(){
     return sourceCity.hashCode() + targetCity.hashCode();
   }
}
```


----------



## linomail (22. Sep 2017)

mrBrown hat gesagt.:


> Wie sehen denn equals und hashcode in Road aus?



ich habs angepasst :/


----------



## mrBrown (22. Sep 2017)

Und wo kommt road her? das ist nirgends definiert...

Du rufst equals und hashcode auf Citys auf, hast du es da auch überschrieben?


----------



## linomail (22. Sep 2017)

mrBrown hat gesagt.:


> Und wo kommt road her? das ist nirgends definiert...
> 
> Du rufst equals und hashcode auf Citys auf, hast du es da auch überschrieben?


 die ist im Map defeniert...

und er findet sie ja auch :/ road ist meine Liste


----------



## linomail (22. Sep 2017)

den kompletten Code hab ich ja auch paar seiten vorher einmal komplett gepostet bis auf das mit equals, an der sitze ich seit paar stunden


----------



## JStein52 (22. Sep 2017)

Du willst doch für zwei Strassen (this und o) die Namen der Städte an den beiden Enden vergleichen. So war es jedenfalls vor ein paar Tagen mal.
Dazu brauchst du bei City noch eine getName()  und damit kannst du doch dein equals ganz einfach hinkriegen


----------



## linomail (22. Sep 2017)

JStein52 hat gesagt.:


> Du willst doch für zwei Strassen (this und o) die Namen der Städte an den beiden Enden vergleichen. So war es jedenfalls vor ein paar Tagen mal.
> Dazu brauchst du bei City noch eine getName()  und damit kannst du doch dein equals ganz einfach hinkriegen



Ja okay neuer anlauf  danke euch beiden für eure Geduld


----------



## JStein52 (22. Sep 2017)

```
public class Road{
   City sourceCity, targetCity;

   //...
   @Override
   public boolean equals(Object o){
     return (this.sourceCity.getName().equals((Road)o.sourceCity.getName()) && this.targetCity.getName().equals((Road)o.targetCity.getName())) ||
       .... das ganze nochmal für die umgekehrte Richtung .......  );
   }

}
```
ohne Gewähr für Syntax, bin gerade nicht am Rechner

Edit: Korrekterweise müsste man noch prüfen ob o instanceof Road ist !


----------



## linomail (22. Sep 2017)

JStein52 hat gesagt.:


> ```
> public class Road{
> City sourceCity, targetCity;
> 
> ...




Bei mir findet der nicht bei 

```
return sourceCity.equals(Road.sourceCity) &

die variable sourceCity nicht :/
```


----------



## mrBrown (22. Sep 2017)

Guck dir mal an, wie du Road geschrieben hast


----------



## linomail (22. Sep 2017)

mrBrown hat gesagt.:


> Guck dir mal an, wie du Road geschrieben hast



eig genau so oO


----------



## mrBrown (22. Sep 2017)

Die Variabel *R*oad wird es bei dir nicht geben, höchstens *r*oad


----------



## linomail (22. Sep 2017)

mrBrown hat gesagt.:


> Guck dir mal an, wie du Road geschrieben hast




vill Road.this.sourceCity?


----------



## mrBrown (22. Sep 2017)

linomail hat gesagt.:


> vill Road.this.sourceCity?


Mit Raten schreibt man in den seltensten Fällen korrekten Code.


----------



## linomail (22. Sep 2017)

mrBrown hat gesagt.:


> Die Variabel *R*oad wird es bei dir nicht geben, höchstens *r*oad



Ja schon aber in der Klasse Road gibt es auch keine variable mit road 

Road.this.sourceCity könnte doch ne möglichkeit sein


----------



## mrBrown (22. Sep 2017)

Wenn es keine Variable road gibt, warum versuchst du dann sie zu benutzen, und was sollte sie sein?


----------



## linomail (22. Sep 2017)

mrBrown hat gesagt.:


> Wenn es keine Variable road gibt, warum versuchst du dann sie zu benutzen, und was sollte sie sein?



die gibt es aber in einer anderen Klasse da wandle ich den Set in ein array um 


```
Road newRoad = new Road(cities[s], cities[t]);
                Set<Road> set = new HashSet<Road>();

                set.add(newRoad);

                Road[] road = set.toArray(new Road[set.size()]);

                System.out.println(Arrays.toString(road));
```


----------



## linomail (22. Sep 2017)

Mein Kopf ist grade Matsche


----------



## mrBrown (22. Sep 2017)

Ja, aber Variablen haben einen Scope - den Block, in dem sie deklariert sind. Außerhalb sind sie nicht sichtbar.

Geht es immer noch um die equals-Funktion?
Dann mach dir noch mal klar, auf welchem Objekt dieses Funktion aufgerufen wird, und was der Funktion übergeben wird.


----------



## linomail (22. Sep 2017)

mrBrown hat gesagt.:


> Ja, aber Variablen haben einen Scope - den Block, in dem sie deklariert sind. Außerhalb sind sie nicht sichtbar.
> 
> Geht es immer noch um die equals-Funktion?
> Dann mach dir noch mal klar, auf welchem Objekt dieses Funktion aufgerufen wird, und was der Funktion übergeben wird.



Für das Objekt Road


```
@Override
    public boolean equals (Object o){

        Road road = (Road) o;

         return (this.sourceCity.getName().equals(road)......
    }
```

Das geht aber nicht auf ich hab da immer ein Syntaxfehler


----------



## linomail (22. Sep 2017)

@mrBrown
@JStein52  es läuft !!!!!!!! Nein  ich fasse es nicht  ich habs jetzt gerafft


```
@Override
    public boolean equals (Object o){

        Road road = (Road) o;

            return sourceCity.equals(road.sourceCity) && targetCity.equals(road.targetCity) ||
                    sourceCity.equals(road.targetCity) && targetCity.equals(road.sourceCity);
        }


    @Override
    public int hashCode () {
        return sourceCity.hashCode() + targetCity.hashCode();
    }
}


und in meinem Generator

if (s != t) {
                Road newRoad = new Road(cities[s], cities[t]);

                if (cities[s].roads.contains(newRoad)) {
                    i--;

                    //hier evt. auch noch nen counter einfügen, ist ja alles random...
                    continue;
                } else {
                    cities[s].roads.add(newRoad);
                    cities[t].roads.add(newRoad);

                    System.out.println(newRoad);
                }
```

Die Ausgabe keine doppelten jaaaa!


```
Name: City0, X: 485, Y:348 --> Name: City4, X: 103, Y:447
Name: City3, X: 137, Y:309 --> Name: City0, X: 485, Y:348
Name: City0, X: 485, Y:348 --> Name: City2, X: 461, Y:176
Name: City1, X: 151, Y:398 --> Name: City4, X: 103, Y:447
Name: City1, X: 151, Y:398 --> Name: City0, X: 485, Y:348
Name: City4, X: 103, Y:447 --> Name: City2, X: 461, Y:176
Name: City4, X: 103, Y:447 --> Name: City3, X: 137, Y:309
Name: City2, X: 461, Y:176 --> Name: City3, X: 137, Y:309
Name: City3, X: 137, Y:309 --> Name: City1, X: 151, Y:398
Name: City1, X: 151, Y:398 --> Name: City2, X: 461, Y:176
```


----------



## linomail (22. Sep 2017)

@JStein52 @mrBrown  Danke euch zwei ohne euch würde ich da noch wochenlang dran sitzen


----------



## linomail (27. Sep 2017)

Ich bin auch schon ein ganzes Stück näher gekommen , doch bei einem Problem steck ich fest.

Ich hab mein Algo. Nearest Neighbour:

```
public int nextCity(int s) {

        double dist, min = 100000;
        int index = -1;

        int start = 0;

        Road r = roads[start];

        while (start < cities.length){
            {
                while ((start < amountCities()) && cities[start].inTour) start++;

                if (start >= amountCities()) {
                    break;
                }

                dist = distance(start, start);

                if ((start != s) && (dist < min)) {
                    min = dist;
                    index = start;
                }
                start++;
            }

        }
        return index;

    }

public void nearestNeighbour()
    {
        int s = 0;

        for (int i=0; i<cities.length - 1; i++)
        {
            cities.inTour = true;
[*]            cities.next = nextCity(s);
[*]            s = cities.next;
[*]        }
[*]        cities.inTour = true;
[*]        cities.next = 0;
[*]    }
```

funktioniert auch ganz gut und er findet die Städte (dank satz des Pythagoras kann ich die Strecke errechnen) und speichert sie in einer Tour ab 

Das ganze versuche ich grade zu verbessern, indem ich bevor er mit der nächsten stadt anfängt eine contains Methode durchführt ob sie auch in road drin ist. 

gestaltet sich iwie schwieriger als gedacht haha

hätte jemand tipps wie ich das implementiere? Tipps oder pseudocode.

Ist die idee denn schon richtig? 
while (start < cities.length && cities[start].name.contains(r.sourceCity.name)?


----------

