All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.uci.ics.jung.graph.SetHypergraph Maven / Gradle / Ivy

There is a newer version: 2.1.1
Show newest version
/*
 * 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 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 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);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy