package edu.hawaii.ics.yucheng;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
/**
* A solution, or partial solution, for a graph. This class is immutable.
*/
final class GraphSolution implements Iterable<Edge> {
public static final int NO_ROOT = -1;
public static final float NO_WEIGHT = Float.MAX_VALUE;
/**
* Returns true if the edge is a duplicate in a collection.
*
* @param edges The collection of edges.
*
* @param edge The edge to find.
*
* @return True indicates the edge is a duplicate.
*/
private static boolean isDuplicateEdge(final Collection<Edge> edges,
final Edge edge) {
for (final Edge e : edges)
if (edge.compareTo(e) == 0)
return true;
return false;
}
private final ArrayList<Edge> myEdges;
private final int myRoot;
private final float myWeight;
/**
* Initializes a new instance of the class.
*
* @param edges The edges.
*/
public GraphSolution(final Collection<Edge> edges) {
this(edges, NO_ROOT);
}
/**
* Initializes a new instance of the class.
*
* @param edges The edges.
*
* @param root The root edge.
*/
public GraphSolution(final Collection<Edge> edges, final int root) {
this(edges, root, NO_WEIGHT);
}
/**
* Initializes a new instance of the class.
*
* @param edges The edges.
*
* @param root The root edge.
*
* @param weight The calculated weight.
*/
public GraphSolution(final Collection<Edge> edges, final int root,
final float weight) {
if (edges == null)
throw new NullPointerException("edges");
myEdges = new ArrayList<Edge>();
for (final Edge e : edges) {
if (e == null)
throw new GraphException("Null edge detected");
if (isDuplicateEdge(myEdges, e))
throw new GraphException("Duplicate edge detected");
myEdges.add(e);
}
if (root != NO_ROOT) {
if (root > myEdges.size())
throw new GraphException("Root index too large");
if (root < 0)
throw new GraphException("Root index too small");
}
myRoot = root;
myWeight = weight;
Collections.sort(myEdges);
}
/**
* Returns true if the solution has a root specified.
*
* @return True if the solution has a root specified and false otherwise.
*/
public boolean hasRoot() {
return myRoot != NO_ROOT;
}
/**
* Returns true if the solution has a weight specified.
*
* @return True if the solution has a weight specified and false otherwise.
*/
public boolean hasWeight() {
return myWeight != NO_WEIGHT;
}
/**
* Returns an iterator for the edges in the solution.
*
* @return An edge iterator.
*/
public Iterator<Edge> iterator() {
return myEdges.iterator();
}
/**
* Returns the root vertex.
*
* @return The root vertex.
*/
public int root() {
if (!hasRoot())
throw new GraphException("No root available.");
return myRoot;
}
/**
* Returns the calculated weight.
*
* @return The calculated weight.
*/
public float weight() {
if (!hasWeight())
throw new GraphException("No weight available.");
return myWeight;
}
}