edu.uci.ics.jung.graph.SetHypergraph Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jung-graph-impl Show documentation
Show all versions of jung-graph-impl Show documentation
Graph implementations for the JUNG project
/*
* Created on Feb 4, 2007
*
* Copyright (c) 2007, The JUNG Authors
*
* All rights reserved.
*
* This software is open-source under the BSD license; see either
* "license.txt" or
* https://github.com/jrtom/jung/blob/master/LICENSE for a description.
*/
package edu.uci.ics.jung.graph;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.google.common.base.Supplier;
import edu.uci.ics.jung.graph.util.EdgeType;
/**
* An implementation of Hypergraph
that is suitable for sparse graphs and
* permits parallel edges.
*/
@SuppressWarnings("serial")
public class SetHypergraph
implements Hypergraph, MultiGraph, Serializable
{
protected Map> vertices; // Map of vertices to incident hyperedge sets
protected Map> edges; // Map of hyperedges to incident vertex sets
/**
* Returns a Factory
which creates instances of this class.
* @param vertex type of the hypergraph to be created
* @param edge type of the hypergraph to be created
* @return a Factory
which creates instances of this class
*/
public static Supplier> getFactory() {
return new Supplier> () {
public Hypergraph get() {
return new SetHypergraph();
}
};
}
/**
* Creates a SetHypergraph
and initializes the internal data structures.
*/
public SetHypergraph()
{
vertices = new HashMap>();
edges = new HashMap>();
}
/**
* Adds hyperedge
to this graph and connects them to the vertex collection to_attach
.
* Any vertices in to_attach
that appear more than once will only appear once in the
* incident vertex collection for hyperedge
, that is, duplicates will be ignored.
*
* @see Hypergraph#addEdge(Object, Collection)
*/
public boolean addEdge(H hyperedge, Collection extends V> to_attach)
{
if (hyperedge == null)
throw new IllegalArgumentException("input hyperedge may not be null");
if (to_attach == null)
throw new IllegalArgumentException("endpoints may not be null");
if(to_attach.contains(null))
throw new IllegalArgumentException("cannot add an edge with a null endpoint");
Set new_endpoints = new HashSet(to_attach);
if (edges.containsKey(hyperedge))
{
Collection attached = edges.get(hyperedge);
if (!attached.equals(new_endpoints))
{
throw new IllegalArgumentException("Edge " + hyperedge +
" exists in this graph with endpoints " + attached);
}
else
return false;
}
edges.put(hyperedge, new_endpoints);
for (V v : to_attach)
{
// add v if it's not already in the graph
addVertex(v);
// associate v with hyperedge
vertices.get(v).add(hyperedge);
}
return true;
}
/**
* @see Hypergraph#addEdge(Object, Collection, EdgeType)
*/
public boolean addEdge(H hyperedge, Collection extends V> to_attach,
EdgeType edge_type)
{
if (edge_type != EdgeType.UNDIRECTED)
throw new IllegalArgumentException("Edge type for this " +
"implementation must be EdgeType.HYPER, not " +
edge_type);
return addEdge(hyperedge, to_attach);
}
/**
* @see Hypergraph#getEdgeType(Object)
*/
public EdgeType getEdgeType(H edge)
{
if (containsEdge(edge))
return EdgeType.UNDIRECTED;
else
return null;
}
public boolean containsVertex(V vertex) {
return vertices.keySet().contains(vertex);
}
public boolean containsEdge(H edge) {
return edges.keySet().contains(edge);
}
public Collection getEdges()
{
return edges.keySet();
}
public Collection getVertices()
{
return vertices.keySet();
}
public int getEdgeCount()
{
return edges.size();
}
public int getVertexCount()
{
return vertices.size();
}
public Collection getNeighbors(V vertex)
{
if (!containsVertex(vertex))
return null;
Set neighbors = new HashSet();
for (H hyperedge : vertices.get(vertex))
{
neighbors.addAll(edges.get(hyperedge));
}
return neighbors;
}
public Collection getIncidentEdges(V vertex)
{
return vertices.get(vertex);
}
public Collection getIncidentVertices(H edge)
{
return edges.get(edge);
}
public H findEdge(V v1, V v2)
{
if (!containsVertex(v1) || !containsVertex(v2))
return null;
for (H h : getIncidentEdges(v1))
{
if (isIncident(v2, h))
return h;
}
return null;
}
public Collection findEdgeSet(V v1, V v2)
{
if (!containsVertex(v1) || !containsVertex(v2))
return null;
Collection edges = new ArrayList();
for (H h : getIncidentEdges(v1))
{
if (isIncident(v2, h))
edges.add(h);
}
return Collections.unmodifiableCollection(edges);
}
public boolean addVertex(V vertex)
{
if(vertex == null)
throw new IllegalArgumentException("cannot add a null vertex");
if (containsVertex(vertex))
return false;
vertices.put(vertex, new HashSet());
return true;
}
public boolean removeVertex(V vertex)
{
if (!containsVertex(vertex))
return false;
for (H hyperedge : vertices.get(vertex))
{
edges.get(hyperedge).remove(vertex);
}
vertices.remove(vertex);
return true;
}
public boolean removeEdge(H hyperedge)
{
if (!containsEdge(hyperedge))
return false;
for (V vertex : edges.get(hyperedge))
{
vertices.get(vertex).remove(hyperedge);
}
edges.remove(hyperedge);
return true;
}
public boolean isNeighbor(V v1, V v2)
{
if (!containsVertex(v1) || !containsVertex(v2))
return false;
if (vertices.get(v2).isEmpty())
return false;
for (H hyperedge : vertices.get(v1))
{
if (edges.get(hyperedge).contains(v2))
return true;
}
return false;
}
public boolean isIncident(V vertex, H edge)
{
if (!containsVertex(vertex) || !containsEdge(edge))
return false;
return vertices.get(vertex).contains(edge);
}
public int degree(V vertex)
{
if (!containsVertex(vertex))
return 0;
return vertices.get(vertex).size();
}
public int getNeighborCount(V vertex)
{
if (!containsVertex(vertex))
return 0;
return getNeighbors(vertex).size();
}
public int getIncidentCount(H edge)
{
if (!containsEdge(edge))
return 0;
return edges.get(edge).size();
}
public int getEdgeCount(EdgeType edge_type)
{
if (edge_type == EdgeType.UNDIRECTED)
return edges.size();
return 0;
}
public Collection getEdges(EdgeType edge_type)
{
if (edge_type == EdgeType.UNDIRECTED)
return edges.keySet();
return null;
}
public EdgeType getDefaultEdgeType()
{
return EdgeType.UNDIRECTED;
}
public Collection getInEdges(V vertex)
{
return getIncidentEdges(vertex);
}
public Collection getOutEdges(V vertex)
{
return getIncidentEdges(vertex);
}
public int inDegree(V vertex)
{
return degree(vertex);
}
public int outDegree(V vertex)
{
return degree(vertex);
}
public V getDest(H directed_edge)
{
return null;
}
public V getSource(H directed_edge)
{
return null;
}
public Collection getPredecessors(V vertex)
{
return getNeighbors(vertex);
}
public Collection getSuccessors(V vertex)
{
return getNeighbors(vertex);
}
}