Edge.java

/*
 *     YAV (Yet another Visualiser)
 *     (c) 2004 by Robin Quast
 *    Version 1.0 (04.03.2004)
 *    
 *  erstellt im Rahmen der Diplomarbeit
 * "Theorie und Java- Realisierung
 *  ausgewählter Algorithmen zur
 *  Bestimmung kürzester Wege in Graphen"
 *
 *  betreut durch Prof. Dr. Lenze
 *  an der Fachhochschule Dortmund
 *  im SS 2003/ WS 2003/2004
 *
 *  @(#)Edge.java  1.0 04/03/09
 */

import java.*;
import java.io.*;


/** Mit Hilfe dieser Klasse kann ein Objekt vom Typ Edge (Kante) erzeugt werden.
 * Diese Kante soll eine Kante in einem greichteten Graphen darstellen, die 
 * mit Kosten "cost"s versehen ist. Die Kante hat die Richtung von "tail" nach "head".
 * Die Kosten werden als Integer- Wert angeben. Auf tail, head und cost kann direkt 
 * zugegriffen werden. Das kann u.a. Performace Steigerungen zur Folge haben (im 
 * Vergleich zu dem Weg über getTail() und getHead() und setTail()...)
 */
public class Edge 
implements Comparable, Serializable
{
  public Node head;   // Ziel
  public Node tail;   // Quelle
  public int cost;   // Kosten
  
  /** Konstruktor, der eine Kante erstellt, der noch keine Knoten zugewiesen wurde, 
   * bzw. die zugewiesenen Knoten den Wert -1 haben. Die Kosten für diese Kante werden
   * auf 0 gesetzt.
   */
  public Edge () {  
    head= new Node (-1);
    tail= new Node (-1);
    cost=0;
  }
  
  /** Konstruktor, der eine Kante mit dem Startknoten ntail  und 
   * den Zielknoten nhead erstellt. Die Kante ist also eine gerichtete Kante, die
   * von ntail nach nhead gerichtet ist. Die Kosten für diese Kante werden auf
   * 0 gesetzt. Es wird also im Konstruktor zunächst ein Konten tail und ein Head mit
   * den übergebenen Integer Werten erstellt.
   */
  public Edge (int ntail,int nhead) {
    head = new Node (nhead);
    tail = new Node (ntail);
    cost=0;
  }

  /** Konstruktor, der eine Kante mit dem Startknoten ntail und 
   * den Zielknoten nhead erstellt. Die Kante ist also eine gerichtete Kante, die
   * von ntail nach nhead gerichtet ist. Die Kosten für diese Kante werden auf
   * 0 gesetzt. 
   */
  public Edge (Node ntail,Node nhead) {
    head = new Node (nhead);
    tail = new Node (ntail);
    cost=0;
  }
  
  /** Konstruktor, der eine Kante mit dem Startknoten ntail und 
   * den Zielknoten nhead erstellt. Die Kante ist also eine gerichtete Kante, die
   * von ntail nach nhead gerichtet ist. Die Kosten für diese Kante werden auf
   * den übergebenen Wert c gesetzt. Es werden die Knoten tail und head mit den 
   * übergebenen Parametern erzeugt.
   */
  public Edge (int ntail,int nhead,int c) {
    head = new Node (nhead);
    tail = new Node (ntail);
    cost=c;
  }
  
  /** Konstruktor, der eine Kante mit dem Startknoten ntail und 
   * den Zielknoten nhead erstellt. Die Kante ist also eine gerichtete Kante, die
   * von ntail nach nhead gerichtet ist. Die Kosten für diese Kante werden auf
   * den übergebenen Wert c gesetzt. 
   */
  public Edge (Node ntail,Node nhead,int c) {
    head = new Node (nhead);
    tail = new Node (ntail);
    cost=c;
  }
  
   /** Vergleicht die übergebene Kante, die durch die Knoten ntail und nhead 
    * sowie den Kosten c dargestellt werden, mit der aktuellen Kante. 
    * Stimmen diese überein, so wird true zurückgegeben.
    */
  public boolean equal (Node ntail, Node nhead, int c) {
    return (tail.value == ntail.value&& (head.value == nhead.value&& (cost == c);
  }
  
   /** Vergleicht die übergebene Kante mit der aktuellen Kante. 
    * Stimmen diese überein, so wird true zurückgegeben.
    */
  public boolean equal (Edge e) {
    return equal(e.tail,e.head,e.cost);
  }
  
  /** Gibt den Head Knoten wieder. (Ziel) Dieser Knoten kann auch über die 
   * Klassenvariabeln head erreicht werden.
   */
  public Node getHead() {
    return head;
  }
  
  /** Mit dieser Methode wird der Wert, bzw. der Name des Head Knotens 
   * zurückgegeben.
   */
  public int getHeadValue() {
    return head.getValue();
  }
  
  /** Gibt den Tail Knoten wieder. (Quelle) Dieser Knoten kann auch über die 
   * Klassenvariabeln Tail erreicht werden.
   */
  public Node getTail() {
    return tail;
  }

  /** Gibt die Kosten einer Kante zurück.
   */
  public int getCost() {
    return cost;
  }

  /** Vergleicht zwei Kanten miteinander. Dies ist nützlich z.B. zum Sortieren
   * innerhalb einer Tabelle.<br>
   <ul>
   <li>Es gilt also sind alle Werte gleich, dann wird 0 zur&uuml;ckgegeben.</li>
   <li>Ist der Tail Knoten der &uuml;bergebenen Kante kleiner als Tail Knoten dieser 
   *     Kante, dann wird 1 zur&uuml;ckgegeben.</li>
   <li>Sind die tailknoten gleich, jedoch der Head Knoten der &uuml;bergebenen Kante
   *     ist kleiner als der Head Knoten, dann wird 1 zur&uuml;ckgegeben.</li>
   <li>Stimmen die Knoten Head und Tail der &uuml;bergebenen Kante mit den Knoten der 
   *     Kante &uuml;berein, dann wird 1 zur&uuml;ckgegeben, wenn die Kosten der &uuml;bergebenen 
   *     Kante kleiner als die Kosten der Kante selbst sind.</li>
   <li>In allen anderen F&auml;llen wird -1 zur&uuml;ckgegeben.</li>
   */
  public int compareTo (Edge e) {
    int rc=-1// Annahme this ist kleiner als e
    if (e.getTailValue()<tail.getValue()) rc=1;
    if ((e.getTailValue()==tail.getValue()) && (e.getHeadValue()<head.getValue())) rc=1;
    if ((e.getTailValue()==tail.getValue()) && (e.getHeadValue()==head.getValue()) && (e.getCost()<cost) ) rc=1;
    if ((e.getTailValue()==tail.getValue()) && (e.getHeadValue()==head.getValue()) && (e.getCost()==cost) )rc=0;
    return rc;
  }

  /** Vergleicht zwei Kanten miteinander (siehe compareTo(Edge e)). Das 
   * &uuml;bergebene Object muss in die Klasse Edge wandelbar sein.
   */
  public int compareTo (Object edge) {
    return compareTo((Edgeedge);
  }

  /** Setzt die Kosten der Kante.
   */
  public void setCost(int value) {
    cost= value ;
  }
  
  /** Gibt den Tail Knotenwert zur&uuml;ck.
   */
  public int getTailValue() {
    return tail.getValue();
  }
  
  /** Pr&uuml;ft, ob Tail oder Head gleich dem Knoten sind.
   */
  public boolean hasNode(Node n) {
    return hasNode(n.getValue());
  }
  
  /** Pr&uuml;ft, ob Head oder Tail gleich dem Knotenwert <i>n</I> sind.
   */
  public boolean hasNode(int n) {
    if ((tail.getValue()==n|| (head.getValue()==n)) return true;
    else return false;
  }
  
  /** Erzeugt einen String, der die Kante graphisch darstellen soll.
   * Die Ausgabe kann z.B. so aussehen <br> 2 -(3)-> 4 <br>
   * f&uuml;r eine Kante von 2 nach 4 mit den Kosten 3.
   */
  public String toString() {
    return tail.value + " -("+ cost +")-> " + head.value;
  }
  
  /** Erzeugt einen String, der den Head Konten und die Kosten ausgibt.
   */
  public String headCost2String() {
    return head.value + ","+ cost;
  }
  
  /** Methode, die die Allgemeinen Funktionen testet und demonstriert.
   */
    public static void main(String[] args) {
    // test
     
    System.out.println("Testen der Edge Klasse.\n");
    System.out.println("Erzeugen der Kanten 1,2 und 2,3 und 2,3 \n");
    
    Edge einzwei = new Edge (1,2);
    Edge zweidrei = new Edge (2,3);
    Node nzwei = new Node (2);
    Node ndrei = new Node (3);
    Edge edge_zweidrei = new Edge (nzwei,ndrei);
    Edge cost_zweidrei = new Edge (nzwei,ndrei,3);
    
    System.out.println("einzwei.toString() " + einzwei.toString());
    System.out.println("zweidrei.toString() " + zweidrei.toString());
    System.out.println("edge_zweidrei.toString() " + edge_zweidrei.toString());
    System.out.println("cost_zweidrei.toString() " + cost_zweidrei.toString());
    System.out.println("cost_zweidrei.toString() " + cost_zweidrei.headCost2String()+"\n");
    System.out.println("einzwei = zweidrei " + einzwei.equal(zweidrei));
    System.out.println("zweidrei = edge_zweidrei " + zweidrei.equal(edge_zweidrei+"\n");
    System.out.println("zweidrei = cost_zweidrei " + zweidrei.equal(cost_zweidrei+"\n");
    
    System.out.println(zweidrei +".compareTo("+einzwei+")="+zweidrei.compareTo(einzwei));
    System.out.println("zweidrei.hasNode(1)="+zweidrei.hasNode(1));
    System.out.println("zweidrei.hasNode(2)="+zweidrei.hasNode(2));
  }

}