All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.tsl2.nano.vnet.routing.AbstractRoutingAStar Maven / Gradle / Ivy

Go to download

TSL2 Framework VirtualNetwork (Generic parallelized Network-Mechanism providing implementations for: NeuronalNetwork, Routing, Workflow)

The newest version!
/*
 * File: $HeadURL$
 * Id  : $Id$
 * 
 * created by: Thomas Schneider, Thomas Schneider
 * created on: Nov 25, 2012
 * 
 * Copyright: (c) Thomas Schneider 2012, all rights reserved
 */
package de.tsl2.nano.vnet.routing;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Set;

import de.tsl2.nano.core.messaging.IListener;
import de.tsl2.nano.core.util.Util;
import de.tsl2.nano.structure.Cover;
import de.tsl2.nano.structure.IConnection;
import de.tsl2.nano.structure.INode;
import de.tsl2.nano.vnet.Connection;
import de.tsl2.nano.vnet.ILocatable;
import de.tsl2.nano.vnet.Link;
import de.tsl2.nano.vnet.Node;
import de.tsl2.nano.vnet.Notification;

/**
 * Implementation of A*-Algorithm like http://de.wikipedia.org/wiki/A*-Algorithmus.
 * 

* Using the vnet with its {@link Node}s and {@link Connection}s, a new created route will have new created nodes with * back-connections (weight is negative). *

* to change the 'weight' behavior (e.g. to categorize specific roads) overwrite the {@link #g(Connection)} method. *

* TODO: use ThreadingEventController to do parallel networking. * * @param type of {@link Node} content (=core) * @param connection descriptor (on simple weighted connections, it would be Float) * @author Thomas Schneider, Thomas Schneider * @version $Revision$ */ public abstract class AbstractRoutingAStar & ILocatable & Serializable & Comparable, D extends Comparable> { /** * this priority queue holds all connections to be inspected. the priority is defined by the calculated minimal * distance to the destination. we use a weighted connection - a connection of a real node-connection to use the * float-number as calculated distance. */ PriorityQueue, Float>> openlist = new PriorityQueue, Float>>(); /** closedlist - see description of {@link #openlist} */ Set> closedlist = new HashSet>(); /** * route * * @param start * @param destination * @return */ public Connection route(Node start, Node destination) { Connection currentConnection, route; // Initialisierung der Open List, die Closed List ist noch leer // (die Priorität bzw. der f Wert des Startknotens ist unerheblich) log("starting at: " + start); route = new Connection(start, null); openlist.add(new Link, Float>(route, 0f)); // diese Schleife wird durchlaufen bis entweder // - die optimale Lösung gefunden wurde oder // - feststeht, dass keine Lösung existiert do { // Knoten mit dem geringsten f Wert aus der Open List entfernen currentConnection = openlist.poll().getContent(); // Wurde das Ziel gefunden? if (currentConnection.getDestination().equals(destination)) { log("route finished: " + start + currentConnection); return currentConnection; } // Wenn das Ziel noch nicht gefunden wurde: Nachfolgeknoten // des aktuellen Knotens auf die Open List setzen log("checking connection " + currentConnection); expandNode(currentConnection, destination); // der aktuelle Knoten ist nun abschließend untersucht closedlist.add(currentConnection); } while (!openlist.isEmpty()); // die Open List ist leer, es existiert kein Pfad zum Ziel return null; } /** *

     * überprüft alle Nachfolgeknoten und fügt sie der Open List hinzu, wenn entweder
     * - expandNode 
     * - der Nachfolgeknoten zum ersten Mal gefunden wird oder 
     * - ein besserer Weg zu diesem Knoten gefunden wird
     * 
* * @param currentNode node to evaluate * @param destination */ void expandNode(Connection currentConnection, Node destination) { // distance f float f, g, tentative_g; List> nextConnections = (List>) Util.untyped(currentConnection.getDestination().getConnections()); Node successor; for (Connection con : nextConnections) { successor = con.getDestination(); log_("\t--> " + successor); // wenn der Nachfolgeknoten bereits auf der Closed List ist - tue nichts if (closedlist.contains(con)) { continue; } // g Wert für den neuen Weg berechnen: g Wert des Vorgängers plus // die Kosten der gerade benutzten Kante g = g(con); tentative_g = g(currentConnection) + g; log_("\t g + c = " + tentative_g); // wenn der Nachfolgeknoten bereits auf der Open List ist, // aber der neue Weg nicht besser ist als der alte - tue nichts if (openlist.contains(new Link(con, g)) && tentative_g >= g) { continue; } // Vorgängerzeiger setzen und g Wert merken // f Wert des Knotens in der Open List aktualisieren // bzw. Knoten mit f Wert in die Open List einfügen f = tentative_g + h(successor, destination); log("\t f = " + f); // if (openlist.contains(successor)) { // openlist.decreaseKey(successor, f); // } else { // openlist.add(successor, f); // } Connection next = connect(currentConnection.getDestination(), con.getDestination(), tentative_g); Link, Float> weightedConnection = new Link, Float>(next, f); // openlist.remove(weightedConnection); openlist.add(weightedConnection); } } public Collection> navigate(INode start, IConnection route, List> currentTrack) { if (currentTrack == null) { currentTrack = new LinkedList>(); } currentTrack.add(route); List> connections = route.getDestination().getConnections(); //filter the backward connections IConnection c = null, con; for (Iterator> iterator = connections.iterator(); iterator.hasNext();) { con = iterator.next(); if (isTrack(con)) { c = con; removeTrackMarker(c); break; } } if (c == null) { Collections.reverse(currentTrack); return currentTrack; } return navigate(route.getDestination(), c, currentTrack); } /** to identify a track */ protected abstract boolean isTrack(IConnection con); /** remove the track marker. see {@link #getTrackMarker()}. optional, may do nothing.... */ protected abstract void removeTrackMarker(IConnection connection); /** * successor.connectTo(currentNode, -tentative_g); * * @param successor * @param currentNode * @param f */ protected abstract Connection connect(Node successor, Node currentNode, float f); /** * direct distance to destination * * @param successor current evaluation node * @param destination destination * @return distance */ protected float h(Node successor, Node destination) { return successor.compareTo(destination); } /** * edge length (weight) of given connection * * @param con connection * @return connection length */ protected float g(Connection con) { return con.length(); } protected void log_(String msg) { System.out.print(msg); } protected void log(String msg) { System.out.println(msg); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy