private string handleNodeCoordSection(StreamReader reader) { String actualLine = reader.ReadLine(); int i = 1; if (mFileHeader.dimension == 0) { mFileHeader.dimension = Int32.MaxValue; } while ((!(actualLine == "EOF")) && (i <= mFileHeader.dimension)) { CTSPPoint point = parseLineToPoint(actualLine); CTSPPointList.getInstance().addPoint(point); actualLine = reader.ReadLine(); i++; } // Nachdem alle Punkte eingefügt wurden noch die Liste optimieren, // da sich hier eigentlich nichts mehr ändern sollte CTSPPointList.getInstance().optimizeList(); // Nachdem wir alle Punkte ausgelesen haben, können wir nun die Verbindungen nach // im FileHeader angegebenen Algorithmus berechnen CConnectionList.getInstance().generateFromPointList(mFileHeader.edgeWeightType); PerformanceCounter freeMemory = new PerformanceCounter("Memory", "Available Bytes"); Debug.WriteLine("Am Ende RAM frei: " + freeMemory.RawValue); Debug.WriteLine("Endspeicher: " + GC.GetTotalMemory(true)); return(actualLine); }
/// <summary> /// erstellt die Liste aller Verbindungen, anhand aller Einträge /// in der CTSPPointList /// </summary> public void generateFromPointList(CTSPLibFileParser.E_EDGE_WEIGHT_TYPE edgeWeightType) { if (edgeWeightType == CTSPLibFileParser.E_EDGE_WEIGHT_TYPE.E_EXPLICIT) { throw new Exception("Unbekannter Fehler in der Verarbeitung."); } // jetzt kann die Liste neu gefüllt werden CTSPPointList pointList = CTSPPointList.getInstance(); // die Liste neu initialiseren initList(pointList.length()); for (int originCityIndex = 0; originCityIndex < pointList.length(); originCityIndex++) { for (int destinationCityIndex = originCityIndex + 1; destinationCityIndex < pointList.length(); destinationCityIndex++) { addConnection(new CConnection(pointList.getPoint(originCityIndex), pointList.getPoint(destinationCityIndex), edgeWeightType)); Debug.WriteLineIf(length() % 100000 == 0, length()); } // Zeit für die GC lassen // Sonst gibt es Fehler, weil diese nicht genug Zeit bekommt ihr Ding zu machen System.Threading.Thread.Sleep(1); } Debug.WriteLine("Verbindungen erstellt: " + length()); }
private static void generatePoints() { Random rand = new Random(); for (int cityIndex = 0; cityIndex < mNumPoints; cityIndex++) { CTSPPoint createdPoint = new CTSPPoint(rand.Next(1000), rand.Next(1000), ""); CTSPPointList.getInstance().addPoint(createdPoint); } }
/// <summary> /// füllt die Liste der Punkte mit dem Datensatz aus der "*.tsp"-Datei /// </summary> public void fillTSPPointList() { // erstmal den aktuellen Stand an Punkten löschen CTSPPointList.getInstance().removeAll(); CConnectionList.getInstance().removeAll(); Debug.WriteLine("Startspeicher: " + GC.GetTotalMemory(true)); readFile(); }
private void button_Start_Click(object sender, EventArgs e) { CAntAlgorithmParameters antAlgorithmParameters = CAntAlgorithmParameters.getInstance(); antAlgorithmParameters.numberAnts = Convert.ToInt32(uAntsQuantity.Value); antAlgorithmParameters.numberMaxIterations = Convert.ToInt32(uQuantityIterations.Value); antAlgorithmParameters.pheromoneParameter = pheromonValue; antAlgorithmParameters.pheromoneUpdate = heuristicPheromonUpdateValue; antAlgorithmParameters.initialPheromone = initialPheromonValue; antAlgorithmParameters.localInformation = heuristicValue; antAlgorithmParameters.evaporationFactor = evaporationValue; antAlgorithmParameters.bBestTourStop = cStoppLoesung.Checked; antAlgorithmParameters.bLimitStop = cStopSchwellenwert.Checked; antAlgorithmParameters.iLimitStop = 0; if (antAlgorithmParameters.bLimitStop == true) { antAlgorithmParameters.iLimitStop = Convert.ToInt32(tThreshold.Text); } //MessageBox.Show("Ants: " + CAntAlgorithmParameters.getInstance().numberAnts + "\n" + CAntAlgorithmParameters.getInstance().numberMaxIterations + "\n" + CAntAlgorithmParameters.getInstance().pheromoneParameter + " \n" + "usw usw"); if (!(mAntAlgorithmThread == null) && (mAntAlgorithmThread.IsAlive == true) && (button_Start.Text == BUTTON_START_TEXT_STOP)) { mAntAlgorithmThread.Abort(); CIterationList.getInstance().Clear(); GC.Collect(); } if (CTSPPointList.getInstance().length() < 2) { MessageBox.Show("Anzahl der Städte beträgt weniger als 2."); return; } if (((mAntAlgorithmThread == null) || (mAntAlgorithmThread.IsAlive == false)) && (button_Start.Text == BUTTON_START_TEXT_START)) { CAntAlgorithm antAlgorithm = new CAntAlgorithm(mRenderWindow, tNumberOfIteration); mAntAlgorithmThread = new Thread(antAlgorithm.startAlgorithm); mAntAlgorithmThread.Name = "AntAlgorithmThread"; mAntAlgorithmThread.Priority = ThreadPriority.Normal; mAntAlgorithmThread.Start(); mTimerThread = new Thread(this.timerThread); mTimerThread.Name = "TimerThread"; mTimerThread.Priority = ThreadPriority.Lowest; mTimerThread.Start(); } if (button_Start.Text == BUTTON_START_TEXT_START) { button_Start.Text = BUTTON_START_TEXT_STOP; } else { button_Start.Text = BUTTON_START_TEXT_START; } }
private string handleEdgeWeightSection(StreamReader reader) { // bevor wir mit dem Parsen anfangen, prüfen wir erstmal ein paar sachen // Der Typ muss korrekt sein if (mFileHeader.edgeWeightType != E_EDGE_WEIGHT_TYPE.E_EXPLICIT) { throw new Exception("Fileformat Fehler! Datei kann nicht gelesen werden."); } // Damit wir die Verbindungen erzeugen können müssen Punkte vorhanden sein. // Das machen wir aber nur wenn nicht schon Punkte vorhanden sind // (z.B. durch eine DISPLAY_DATA_SECTION) if (CTSPPointList.getInstance().length() == 0) { for (int point = 1; point <= mFileHeader.dimension; point++) { CTSPPointList.getInstance().addPoint(new CTSPPoint(point.ToString())); } // Nachdem alle Punkte eingefügt wurden noch die Liste optimieren, // da sich hier eigentlich nichts mehr ändern sollte CTSPPointList.getInstance().optimizeList(); } // Damit wir später die Verbindungen einfügen können, muss die Liste der Verbindungen // erstmal, für die Anzahl initialisert werden CConnectionList.getInstance().initList(mFileHeader.dimension); int expectedWeightElements = getNumberElementsToRead(); int weightElementsRead = 0; // Es gibt kein wirkliches Stoppkriterum.. es muss mitgezählt werden wieviele Element bereites ausgelesen wurden String actualLine = reader.ReadLine(); while ((actualLine != null) && (weightElementsRead < expectedWeightElements)) { actualLine = actualLine.Trim(); string[] elements = actualLine.Split(COORD_SPLIT_CHARACTERS); elements = removeSpacesInString(elements); foreach (string element in elements) { handleEdgeWeightElement(element, weightElementsRead); // ein Element wurde gelesen weightElementsRead++; } // nächste Zeile lesen actualLine = reader.ReadLine(); } return(actualLine); }
private string handleTourSection(StreamReader reader) { String actualLine = reader.ReadLine(); if (mFileHeader.dimension == 0) { mFileHeader.dimension = Int32.MaxValue; } // Die Anzahl der Knoten in der Datei muss mit der Anzahl der Einträge in der Punktliste übereinstimmen. // Sonst greifen wir eventuell noch auf Punkte zu die es nicht gibt. if (mFileHeader.dimension != CTSPPointList.getInstance().length()) { throw new Exception("Tour-Datei ist nicht kompatibel mit der geladenen TSP-Datei!"); } CTour optTour = new CTour(); int i = 1; while ((!(actualLine == "-1")) && (i <= mFileHeader.dimension)) { actualLine = actualLine.Trim(); // Punkt suchen CTSPPoint point = CTSPPointList.getInstance().getPoint(actualLine); if (point != null) { // Punkt in Tour einfügen optTour.addPoint(point); } else { throw new Exception("Fehler beim auslesen der Optimalen Tour!"); } actualLine = reader.ReadLine(); i++; } // prüfen ob die Tour ein Kreis ist (erstes == letztes Element) if (optTour.getPoint(0) != optTour.getPoint(optTour.getListLength() - 1)) { // Nein, also den Kreis herstellen optTour.addPoint(optTour.getPoint(0)); } // Tour abspeichern CAntAlgorithmParameters.getInstance().optTour = optTour; return(actualLine); }
public void CreateNewAnts() { Random random = new Random(); int numPoints = CTSPPointList.getInstance().length(); for (int i = 0; i < arrayOfAnts.Length; i++) { int randomPointIndex = random.Next(numPoints); CTSPPoint randomPoint = CTSPPointList.getInstance().getPoint(randomPointIndex); arrayOfAnts[i] = new CAnt(randomPoint); } }
/// <summary> /// Kopiert diese Liste und gibt ein neues Objekt zurück /// </summary> /// <returns>neue Instanz dieser Liste</returns> public CTSPPointList copy() { // neues Objekt erstellen CTSPPointList newList = new CTSPPointList(); // Objekt füllen for (int pointIndex = 0; pointIndex < length(); pointIndex++) { newList.addPoint(getPoint(pointIndex)); } newList.optimizeList(); return(newList); }
private void drawPoints() { Gl.glPointSize(5); Gl.glColor3f(1.0f, 0f, 0f); // Städte Zeichnen CTSPPointList pointList = CTSPPointList.getInstance(); for (int pointIndex = 0; pointIndex < pointList.length(); pointIndex++) { CTSPPoint point = pointList.getPoint(pointIndex); Gl.glBegin(Gl.GL_POINTS); Gl.glVertex3d(point.x, point.y, POINT_DRAW_LAYER); Gl.glEnd(); } }
public void handleAnt(object antObject) { CAnt ant = (CAnt)antObject; // Ameisen laufen lassen for (var i = 0; i < CTSPPointList.getInstance().length(); i++) { CTSPPoint nextPoint = decisionNextPoint(ant.CurrentPoint, ant.GetTour().getPoint(0), ant.PointsToVisit); if (nextPoint == null) { nextPoint = ant.GetTour().getPoint(0); } ant.CurrentPoint = nextPoint; } }
protected T_BOUNDS getBounds(CTSPPointList citys) { T_BOUNDS ret = new T_BOUNDS(); if (citys.length() > 0) { ret.left = double.MaxValue; ret.bottom = double.MaxValue; for (int cityIndex = 0; cityIndex < citys.length(); cityIndex++) { CTSPPoint city = citys.getPoint(cityIndex); if (city.x < ret.left) { ret.left = city.x; } if (city.y < ret.bottom) { ret.bottom = city.y; } if (city.x > ret.right) { ret.right = city.x; } if (city.y > ret.top) { ret.top = city.y; } } } else { ret.left = 0; ret.bottom = 0; ret.right = this.Width; ret.top = this.Height; } return(ret); }
private void handleCursorAction(CVector2f position) { if (mCursorAction.add) { try { CMemoryTester.fitMemory(CTSPPointList.getInstance().length() + 1); } catch (CInsufficientMemoryException memoryException) { if (memoryException.getType() == CInsufficientMemoryException.E_EXCEPTION_TYPE.E_32_BIT_ERROR) { MessageBox.Show("Um ein Projekt mit einem Knoten mehr erzeugen zu können, benötigen Sie ca. " + memoryException.getMemoryNeeded() + " MByte. 32-Bit-Anwendungen können aber maximal " + memoryException.getMemoryAvailable() + " MByte verwalten. " + "Bitte verwenden sie die 64-Bit Version oder verwenden Sie ein geringe Anzahl an Punkten.", "Fehler!", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { MessageBox.Show("Auf ihrem System stehen noch " + memoryException.getMemoryAvailable() + " MByte zur Verfügung. Es werden aber ca. " + memoryException.getMemoryNeeded() + " MByte benötigt. " + "Wenn Sie ein Projekt mit einer höheren Anzahl von Punkten verwenden möchten stellen Sie Bitte mehr RAM zur Verfügung.", "Fehler!", MessageBoxButtons.OK, MessageBoxIcon.Error); } } CTSPPointList.getInstance().addPoint(new CTSPPoint(position.x, position.y)); } if (mCursorAction.del) { float precision = (float)((mBounds.right - mBounds.left) / 100); CTSPPoint Point = CTSPPointList.getInstance().getPointsbyCoordinates(position.x, position.y, precision); if (!(Point == null)) { CTSPPointList.getInstance().remove(Point); } } if (mCursorAction.change) { pointToMove.movePoint = false; } }
public void mMouseDown(object sender, EventArgs args) { if (mCursorAction.change) { System.Windows.Forms.MouseEventArgs mouseArgs = (System.Windows.Forms.MouseEventArgs)args; if (mouseArgs.Button == System.Windows.Forms.MouseButtons.Left) { CVector2f position = getPositionFromMouseClick(mouseArgs); float precision = (float)((mBounds.right - mBounds.left) / 100); CTSPPoint Point = CTSPPointList.getInstance().getPointsbyCoordinates(position.x, position.y, precision); if (!(Point == null)) { pointToMove.movePoint = true; pointToMove.pointToMove = Point; } } } }
private string handleDisplayDataSection(StreamReader reader) { if (mFileHeader.displayDataType != E_DISPLAY_DATA_TYPE.E_TWOD_DISPLAY) { throw new Exception("Fehler beim lesen der Anzeigedaten!"); } // da es sein kann das die DisplayDataSection nach der EdgeWeightSection kommt und // die Punkte damit schon angelegt sind müssen zuerst ermittelt werden, ob neue Punkte // angelegt werden müssen oder die bestehenden verwendet werden können bool bCreateNewPoints = CTSPPointList.getInstance().length() == 0; int nodeIndex = 0; string actualLine = reader.ReadLine(); while ((actualLine != null) && (actualLine != "EOF") && (nodeIndex <= mFileHeader.dimension)) { CTSPPoint point = parseLineToPoint(actualLine); if (bCreateNewPoints == true) { CTSPPointList.getInstance().addPoint(point); } else { CTSPPoint storedPoint = CTSPPointList.getInstance().getPoint(nodeIndex); storedPoint.setLabel(point.getLabel()); storedPoint.x = point.x; storedPoint.y = point.y; } nodeIndex++; actualLine = reader.ReadLine(); } // Nachdem alle Punkte eingefügt wurden noch die Liste optimieren, // da sich hier eigentlich nichts mehr ändern sollte CTSPPointList.getInstance().optimizeList(); return(actualLine); }
public static void generateTSP() { try { CProgressManager.setStepsConnections(mNumPoints); // erstmal alles altes löschen CTSPPointList.getInstance().removeAll(); CConnectionList.getInstance().removeAll(); GC.Collect(); CMemoryTester.fitMemory(mNumPoints); generatePoints(); CConnectionList.getInstance().generateFromPointList(CTSPLibFileParser.E_EDGE_WEIGHT_TYPE.E_EUC_2D); } catch (CInsufficientMemoryException memoryException) { if (memoryException.getType() == CInsufficientMemoryException.E_EXCEPTION_TYPE.E_32_BIT_ERROR) { MessageBox.Show("Um ein Projekt mit der angegeben größe erzeugen zu können, benötigen Sie ca. " + memoryException.getMemoryNeeded() + " MByte. 32-Bit-Anwendungen können aber maximal " + memoryException.getMemoryAvailable() + " MByte verwalten. " + "Bitte verwenden sie die 64-Bit Version oder wählen Sie ein geringe Anzahl an Punkten.", "Fehler!", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { MessageBox.Show("Auf ihrem System stehen noch " + memoryException.getMemoryAvailable() + " MByte zur Verfügung. Es werden aber ca. " + memoryException.getMemoryNeeded() + " MByte benötigt. " + "Wenn Sie dieses Projekt mit dieser Anzahl von Punkten erstellen möchten stellen Sie Bitte mehr RAM zur Verfügung.", "Fehler!", MessageBoxButtons.OK, MessageBoxIcon.Error); } } catch (Exception exception) { MessageBox.Show(exception.Message, "Fehler!", MessageBoxButtons.OK, MessageBoxIcon.Error); } CProgressManager.setFinished(); }
public void initViewPort() { InitializeContexts(); Gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); Gl.glMatrixMode(Gl.GL_PROJECTION); Gl.glLoadIdentity(); mBounds = getBounds(CTSPPointList.getInstance()); mBounds.left -= 5; mBounds.right += 5; mBounds.bottom -= 5; mBounds.top += 5; // hier müssen wir bestimmen wie groß die Renderfläche sein soll // wenn z.b. die äußerste Stadt bei 345, 239 liegt, sollte der // Viewport ein wenig größer sein Gl.glOrtho(mBounds.left, mBounds.right, mBounds.bottom, mBounds.top, -100.0f, 100.0f); Gl.glEnable(Gl.GL_DEPTH_TEST); }
private void handleEdgeWeightElement(string element, int elementIndex) { CTSPPointList pointList = CTSPPointList.getInstance(); CConnectionList connList = CConnectionList.getInstance(); float distance = float.Parse(element); switch (mFileHeader.edgeWeightFormat) { case E_EDGE_WEIGHT_FORMAT.E_FULL_MATRIX: { int row = elementIndex / mFileHeader.dimension; int pointIndex = elementIndex % mFileHeader.dimension; // Es werden nur die Punkte unter der Diagonalen betrachtet. // damit werden keine Verbindungen Doppelt eingefügt und Verbindungen // auf den gleichen Punkt, also Distanz = 0, vermieden if (pointIndex < row) { CTSPPoint point1 = pointList.getPoint(row); CTSPPoint point2 = pointList.getPoint(pointIndex); connList.addConnection(new CConnection(point1, point2, distance, CAntAlgorithmParameters.getInstance().initialPheromone)); } break; } case E_EDGE_WEIGHT_FORMAT.E_UPPER_ROW: { int row = 0; while ((elementIndex / (mFileHeader.dimension - 1 - row)) > 0) { elementIndex -= (mFileHeader.dimension - 1 - row); row++; } // Index des Punktes ist der Offset bis zur Diagonalen + den Index des Elementes int pointIndex = row + 1 + elementIndex; CTSPPoint point1 = pointList.getPoint(row); CTSPPoint point2 = pointList.getPoint(pointIndex); connList.addConnection(new CConnection(point1, point2, distance, CAntAlgorithmParameters.getInstance().initialPheromone)); break; } case E_EDGE_WEIGHT_FORMAT.E_UPPER_DIAG_ROW: { int row = 0; while ((elementIndex / (mFileHeader.dimension - row)) > 0) { elementIndex -= (mFileHeader.dimension - row); row++; } // Index des Punktes ist der Offset bis zur Diagonalen + den Index des Elementes int pointIndex = row + elementIndex; if (pointIndex != row) { CTSPPoint point1 = pointList.getPoint(row); CTSPPoint point2 = pointList.getPoint(pointIndex); connList.addConnection(new CConnection(point1, point2, distance, CAntAlgorithmParameters.getInstance().initialPheromone)); } break; } case E_EDGE_WEIGHT_FORMAT.E_LOWER_DIAG_ROW: { int row = 0; int pointIndex = elementIndex; while ((pointIndex / (row + 1)) > 0) { pointIndex -= row + 1; row++; } if (pointIndex != row) { CTSPPoint point1 = pointList.getPoint(pointIndex); CTSPPoint point2 = pointList.getPoint(row); connList.addConnection(new CConnection(point1, point2, distance, CAntAlgorithmParameters.getInstance().initialPheromone)); } break; } } }
public CAnt(CTSPPoint startPoint) { tour = new CTour(); PointsToVisit = CTSPPointList.getInstance().copy(); CurrentPoint = startPoint; }
// Entspricht in der Formel: // Sum l( (t il) ^ alpha * (n il) ^ beta ) private double calculateSumFactorOfPossibleConnections(CTSPPoint currentPoint, CTSPPoint startPoint, CTSPPointList listOfPointsToTravel) { double sumFactorOfPossibleConnections = 0; foreach (CTSPPoint possiblePoint in listOfPointsToTravel) { CConnection connection = mConnectionList.getConnection(currentPoint, possiblePoint); double n_il = calculateLocalInformation(connection); double t_il = calculatePheromoneTrail(connection); sumFactorOfPossibleConnections += n_il * t_il; } // wir müssen natürlich auch den Weg zurück zum Startpunkt beachten, der darf aber nicht in der // Liste der noch zu besuchenden Punkte stehen. // Daher müssen wir diesen nochmal explizit am ende einbeziehen CConnection startConnection = mConnectionList.getConnection(startPoint, currentPoint); if (startConnection != null) { double start_n_il = calculateLocalInformation(startConnection); double start_t_il = calculatePheromoneTrail(startConnection); sumFactorOfPossibleConnections += start_n_il * start_t_il; } return(sumFactorOfPossibleConnections); }
public CTSPPoint decisionNextPoint(CTSPPoint currentPoint, CTSPPoint startPoint, CTSPPointList listOfPointsToTravel) { // Formel: // (t ij) ^ alpha * (n ij) ^ beta // p ij = ---------------------------------- // Sum l( (t il) ^ alpha * (n il) ^ beta ) // // i = Startpunkt // j = Zielpunkt // l = ein Punkt von den noch zu Besuchenden Punkten // zuerst berechnen wir mal den Divisor der Formel, da dieser einmal pro Bewegung berechnet werden muss double sumFactorOfPossibleConnections = calculateSumFactorOfPossibleConnections(currentPoint, startPoint, listOfPointsToTravel); // jetzt berechnen wir die probability p von allen Verbindungen und bestimmen die beste double bestProbability = 0; CTSPPoint bestTarget = null; foreach (CTSPPoint possibleTarget in listOfPointsToTravel) { CConnection connection = mConnectionList.getConnection(currentPoint, possibleTarget); // von diesem Punkt erstmal die Werte für (t ij) ^ alpha und (n ij) ^ beta berechnen. // Damit haben wir dann die Werte für den Dividenten double t_ij = calculatePheromoneTrail(connection); double n_ij = calculateLocalInformation(connection); // die probability berechnen double probability = (t_ij * n_ij) / sumFactorOfPossibleConnections; // die der probability-Wert höher besser? if (probability > bestProbability) { // dann merken wir uns diesen Punkt bestProbability = probability; bestTarget = possibleTarget; } } return(bestTarget); }