package rpi.goldsd.graph; import java.util.Enumeration; import rpi.goldsd.container.*; /** * The Edge class is used to represent a single undirected * edge between two vertices. An edge is associated with either * zero or one GraphBase objects. * * @see GraphBase * @see DirectedEdge * @version 2.0, 4/19/98 * @author David Goldschmidt */ public class Edge implements Hashable { protected static final IntSequence I = new IntSequence(); protected static final Enumeration keys = I.sequence(); /* ****************** CONSTRUCTOR METHODS ****************** */ /** * Constructs an undirected edge with the given pair of endpoint * vertices, the initial Hashable object to be associated with * this undirected edge, and the initial weight. * @param startVertex the first endpoint vertex of this undirected edge. * @param endVertex the second endpoint vertex of this undirected edge. * @param data the Hashable object to be associated with this * undirected edge. * @param isWeighted indicates whether this edge is a directed edge. * @param weight the initial weight of this undirected edge. */ protected Edge( Vertex startVertex, Vertex endVertex, Hashable data, boolean isWeighted, double weight ) { this.associatedGraph = null; this.startVertex = startVertex; this.endVertex = endVertex; this.data = data; this.isWeighted = isWeighted; if ( isWeighted ) this.weight = weight; } /** * Constructs an undirected edge with the given pair of endpoint * vertices, the initial Hashable object to be associated with * this undirected edge, and the initial weight. * @param startVertex the first endpoint vertex of this undirected edge. * @param endVertex the second endpoint vertex of this undirected edge. * @param data the Hashable object to be associated with this * undirected edge. * @param weight the initial weight of this undirected edge. */ public Edge( Vertex startVertex, Vertex endVertex, Hashable data, double weight ) { this( startVertex, endVertex, data, true, weight ); } /** * Constructs an undirected edge with the given pair of endpoint * vertices, and the initial weight. * @param startVertex the first endpoint vertex of this undirected edge. * @param endVertex the second endpoint vertex of this undirected edge. * @param weight the initial weight of this undirected edge. */ public Edge( Vertex startVertex, Vertex endVertex, double weight ) { this( startVertex, endVertex, (Hashable)keys.nextElement(), true, weight ); } /** * Constructs an undirected edge with the given pair of endpoint * vertices, the initial Hashable object to be associated with * this undirected edge. * @param startVertex the first endpoint vertex of this undirected edge. * @param endVertex the second endpoint vertex of this undirected edge. * @param data the Hashable object to be associated with this * undirected edge. */ public Edge( Vertex startVertex, Vertex endVertex, Hashable data ) { this( startVertex, endVertex, data, false, 0.0 ); } /** * Constructs an undirected edge with the given pair of endpoint * vertices. * @param startVertex the first endpoint vertex of this undirected edge. * @param endVertex the second endpoint vertex of this undirected edge. */ public Edge( Vertex startVertex, Vertex endVertex ) { this( startVertex, endVertex, (Hashable)keys.nextElement(), false, 0.0 ); } /** * The default constructor is not to be used, since an undirected edge * must have a given start and end vertex. */ protected Edge() { } /* ****************** ACCESSOR METHODS ****************** */ /** * Returns a reference to the Hashable object that is * associated with this undirected edge. * @return a reference to the Hashable object that is * associated with this undirected edge. */ public Hashable data() { return data; } /** * Returns the second vertex endpoint of this undirected edge. * Note that the name endVertex does not imply a directed edge. * @return the second vertex endpoint of this undirected edge. */ public Vertex endVertex() { return endVertex; } /** * Returns a reference to the graph that contains this undirected * edge, if any. * @return a reference to the graph that contains this undirected * edge; or null if this undirected edge is not * associated with a graph. */ public GraphBase graph() { return associatedGraph; } /** * Returns the hash value of the Hashable data associated with * this edge. * @return the hash value of the Hashable data associated with * this edge. */ public int hash() { return data.hash(); } /** * Returns the hash value of the Hashable data associated with * this edge. * @param tableSize the size of the table that will potentially hold this * Edge object and others. * @return the hash value of the Hashable data associated with * this edge. */ public int hash( int tableSize ) { return data.hash( tableSize ); } /** * Tests if two edges are "equal" based on their Hashable data * objects. * @param C the right-hand side of the comparison. * @return true if this edge is "equal" to the given edge * C based on the Hashable data objects; * false otherwise. */ public boolean isEqualTo( Comparable C ) { if ( C instanceof Edge ) return data.isEqualTo( ((Edge)C).data() ); else return data.isEqualTo( C ); } /** * Tests if this undirected edge is associated with a graph. * @return true if this undirected edge is associated * with a graph; false otherwise. */ public boolean isInGraph() { return ( associatedGraph != null ); } /** * Tests if this undirected edge is associated with the given graph. * @param G the graph to test. * @return true if this undirected edge is associated with * the given graph G; false otherwise. */ public boolean isInGraph( GraphBase G ) { return ( associatedGraph == G ); } /** * Tests if one edge is "less than" another based on their Hashable * data objects. * @param C the right-hand side of the comparison. * @return true if this edge is "less than" the given edge * C based on the Hashable data objects; * false otherwise. */ public boolean isLessThan( Comparable C ) { if ( C instanceof Edge ) return data.isLessThan( ((Edge)C).data() ); else return data.isLessThan( C ); } /** * Tests if this undirected edge is a self-loop. * @return true if this undirected edge is a self-loop (i.e. both * endpoint vertices are the same); false otherwise. */ public boolean isSelfLoop() { return ( startVertex == endVertex ); } /** * Tests if this undirected edge is a weighted edge. * @return true if this undirected edge is a weighted * edge; false otherwise. */ public boolean isWeighted() { return isWeighted; } /** * Returns the first vertex endpoint of this undirected edge. * Note that the name startVertex does not imply a directed edge. * @return the first vertex endpoint of this undirected edge. */ public Vertex startVertex() { return startVertex; } /** * Returns a String representation of this undirected edge. * The toString() method is applied to the Hashable * object that is associated with this edge. * @return a String representation of this undirected edge. */ public String toString() { String s = "" + data; if ( isWeighted ) s += "[W" + weight + "]"; return s; } /** * Traverses this undirected edge from a given vertex, returning * the destination vertex. * @param V the vertex from which the traversal begins. * @return the vertex this undirected edge is adjacent to from V; * or null if V is not one of the endpoint * vertices of this undirected edge. */ public Vertex traverseFrom( Vertex V ) { if ( startVertex == V ) return endVertex; else if ( endVertex == V ) return startVertex; else return null; } /** * Returns the weight of this undirected edge, if any. * @return the weight of this undirected edge; or null * if there is no weight associated with this undirected edge. */ public double weight() { return weight; } /* ****************** MUTATOR METHODS ****************** */ /** * Sets the Hashable object that is associated with this edge. * @param data the new Hashable object. * @return the old Hashable object associated with this edge. */ public Hashable setData( Hashable data ) { Hashable oldData = this.data; if ( isInGraph() ) associatedGraph.rehash( oldData, data, this ); else this.data = data; return oldData; } /** * Sets the associatedGraph reference to the given graph G. * @param G the graph that this undirected edge is to be associated with. */ protected void setInGraph( GraphBase G ) { associatedGraph = G; } /** * Sets the weight of this edge. * @param weight the weight to be associated with this edge. * @return the old weight of this edge; or null if there * was no weight associated with this edge. */ public double setWeight( double weight ) { double oldWeight = this.weight; this.weight = weight; return oldWeight; } /* ****************** CLASS ATTRIBUTES ****************** */ /** * A reference to the graph that this undirected edge is associated * with; or null if this undirected edge is not associated * with a graph. */ protected GraphBase associatedGraph; /** * A reference to the Hashable object associated with this * undirected edge. */ protected Hashable data; /** * A reference to the second vertex endpoint associated with this * undirected edge. */ protected Vertex endVertex; /** A flag used to indicate whether this edge is weighted. */ protected boolean isWeighted; /** * A reference to the first vertex endpoint associated with this * undirected edge. */ protected Vertex startVertex; /** The weight associated with this undirected edge. */ protected double weight; /** Used by the static Algorithms class. */ protected int status; }