abstractbasegraph.java
来自「JAVA图论的算法包。用过觉得还不错」· Java 代码 · 共 1,223 行 · 第 1/3 页
JAVA
1,223 行
/**
* @see DirectedGraph#incomingEdgesOf(Object)
*/
public Set<E> incomingEdgesOf(V vertex)
{
return specifics.incomingEdgesOf(vertex);
}
/**
* @see DirectedGraph#outDegreeOf(Object)
*/
public int outDegreeOf(V vertex)
{
return specifics.outDegreeOf(vertex);
}
/**
* @see DirectedGraph#outgoingEdgesOf(Object)
*/
public Set<E> outgoingEdgesOf(V vertex)
{
return specifics.outgoingEdgesOf(vertex);
}
/**
* @see Graph#removeEdge(Object, Object)
*/
public E removeEdge(V sourceVertex, V targetVertex)
{
E e = getEdge(sourceVertex, targetVertex);
if (e != null) {
specifics.removeEdgeFromTouchingVertices(e);
edgeMap.remove(e);
}
return e;
}
/**
* @see Graph#removeEdge(Object)
*/
public boolean removeEdge(E e)
{
if (containsEdge(e)) {
specifics.removeEdgeFromTouchingVertices(e);
edgeMap.remove(e);
return true;
} else {
return false;
}
}
/**
* @see Graph#removeVertex(Object)
*/
public boolean removeVertex(V v)
{
if (containsVertex(v)) {
Set<E> touchingEdgesList = edgesOf(v);
// cannot iterate over list - will cause
// ConcurrentModificationException
removeAllEdges(new ArrayList<E>(touchingEdgesList));
specifics.getVertexSet().remove(v); // remove the vertex itself
return true;
} else {
return false;
}
}
/**
* @see Graph#vertexSet()
*/
public Set<V> vertexSet()
{
if (unmodifiableVertexSet == null) {
unmodifiableVertexSet =
Collections.unmodifiableSet(specifics.getVertexSet());
}
return unmodifiableVertexSet;
}
/**
* @see Graph#getEdgeWeight(Object)
*/
public double getEdgeWeight(E e)
{
if (e instanceof DefaultWeightedEdge) {
return ((DefaultWeightedEdge) e).weight;
} else {
return WeightedGraph.DEFAULT_EDGE_WEIGHT;
}
}
/**
* @see WeightedGraph#setEdgeWeight(Object, double)
*/
public void setEdgeWeight(E e, double weight)
{
assert (e instanceof DefaultWeightedEdge) : e.getClass();
((DefaultWeightedEdge) e).weight = weight;
}
private Specifics createSpecifics()
{
if (this instanceof DirectedGraph) {
return new DirectedSpecifics();
} else if (this instanceof UndirectedGraph) {
return new UndirectedSpecifics();
} else {
throw new IllegalArgumentException(
"must be instance of either DirectedGraph or UndirectedGraph");
}
}
//~ Inner Classes ----------------------------------------------------------
/**
* .
*
* @author Barak Naveh
*/
private abstract class Specifics
implements Serializable
{
private static final long serialVersionUID = 785196247314761183L;
public abstract void addVertex(V vertex);
public abstract Set<V> getVertexSet();
/**
* .
*
* @param sourceVertex
* @param targetVertex
*
* @return
*/
public abstract Set<E> getAllEdges(V sourceVertex,
V targetVertex);
/**
* .
*
* @param sourceVertex
* @param targetVertex
*
* @return
*/
public abstract E getEdge(V sourceVertex, V targetVertex);
/**
* Adds the specified edge to the edge containers of its source and
* target vertices.
*
* @param e
*/
public abstract void addEdgeToTouchingVertices(E e);
/**
* .
*
* @param vertex
*
* @return
*/
public abstract int degreeOf(V vertex);
/**
* .
*
* @param vertex
*
* @return
*/
public abstract Set<E> edgesOf(V vertex);
/**
* .
*
* @param vertex
*
* @return
*/
public abstract int inDegreeOf(V vertex);
/**
* .
*
* @param vertex
*
* @return
*/
public abstract Set<E> incomingEdgesOf(V vertex);
/**
* .
*
* @param vertex
*
* @return
*/
public abstract int outDegreeOf(V vertex);
/**
* .
*
* @param vertex
*
* @return
*/
public abstract Set<E> outgoingEdgesOf(V vertex);
/**
* Removes the specified edge from the edge containers of its source and
* target vertices.
*
* @param e
*/
public abstract void removeEdgeFromTouchingVertices(E e);
}
private static class ArrayListFactory<VV, EE>
implements EdgeSetFactory<VV, EE>,
Serializable
{
private static final long serialVersionUID = 5936902837403445985L;
/**
* @see EdgeSetFactory.createEdgeSet
*/
public Set<EE> createEdgeSet(VV vertex)
{
// NOTE: use size 1 to keep memory usage under control
// for the common case of vertices with low degree
return new ArrayUnenforcedSet<EE>(1);
}
}
/**
* A container for vertex edges.
*
* <p>In this edge container we use array lists to minimize memory toll.
* However, for high-degree vertices we replace the entire edge container
* with a direct access subclass (to be implemented).</p>
*
* @author Barak Naveh
*/
private static class DirectedEdgeContainer<VV, EE>
implements Serializable
{
private static final long serialVersionUID = 7494242245729767106L;
Set<EE> incoming;
Set<EE> outgoing;
private transient Set<EE> unmodifiableIncoming = null;
private transient Set<EE> unmodifiableOutgoing = null;
DirectedEdgeContainer(EdgeSetFactory<VV, EE> edgeSetFactory,
VV vertex)
{
incoming = edgeSetFactory.createEdgeSet(vertex);
outgoing = edgeSetFactory.createEdgeSet(vertex);
}
/**
* A lazy build of unmodifiable incoming edge set.
*
* @return
*/
public Set<EE> getUnmodifiableIncomingEdges()
{
if (unmodifiableIncoming == null) {
unmodifiableIncoming = Collections.unmodifiableSet(incoming);
}
return unmodifiableIncoming;
}
/**
* A lazy build of unmodifiable outgoing edge set.
*
* @return
*/
public Set<EE> getUnmodifiableOutgoingEdges()
{
if (unmodifiableOutgoing == null) {
unmodifiableOutgoing = Collections.unmodifiableSet(outgoing);
}
return unmodifiableOutgoing;
}
/**
* .
*
* @param e
*/
public void addIncomingEdge(EE e)
{
incoming.add(e);
}
/**
* .
*
* @param e
*/
public void addOutgoingEdge(EE e)
{
outgoing.add(e);
}
/**
* .
*
* @param e
*/
public void removeIncomingEdge(EE e)
{
incoming.remove(e);
}
/**
* .
*
* @param e
*/
public void removeOutgoingEdge(EE e)
{
outgoing.remove(e);
}
}
/**
* .
*
* @author Barak Naveh
*/
private class DirectedSpecifics
extends Specifics
implements Serializable
{
private static final long serialVersionUID = 8971725103718958232L;
private static final String NOT_IN_DIRECTED_GRAPH =
"no such operation in a directed graph";
private Map<V, DirectedEdgeContainer<V, E>> vertexMapDirected =
new LinkedHashMap<V, DirectedEdgeContainer<V, E>>();
public void addVertex(V v)
{
// add with a lazy edge container entry
vertexMapDirected.put(v, null);
}
public Set<V> getVertexSet()
{
return vertexMapDirected.keySet();
}
/**
* @see Graph#getAllEdges(Object, Object)
*/
public Set<E> getAllEdges(V sourceVertex, V targetVertex)
{
Set<E> edges = null;
if (containsVertex(sourceVertex)
&& containsVertex(targetVertex))
{
edges = new ArrayUnenforcedSet<E>();
DirectedEdgeContainer<V, E> ec = getEdgeContainer(sourceVertex);
Iterator<E> iter = ec.outgoing.iterator();
while (iter.hasNext()) {
E e = iter.next();
if (getEdgeTarget(e).equals(targetVertex)) {
edges.add(e);
}
}
}
return edges;
}
/**
* @see Graph#getEdge(Object, Object)
*/
public E getEdge(V sourceVertex, V targetVertex)
{
if (containsVertex(sourceVertex)
&& containsVertex(targetVertex))
{
DirectedEdgeContainer<V, E> ec = getEdgeContainer(sourceVertex);
Iterator<E> iter = ec.outgoing.iterator();
while (iter.hasNext()) {
E e = iter.next();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?