/* * This file is part of the Trickl Open Source Libraries. * * Trickl Open Source Libraries - http://open.trickl.com/ * * Copyright (C) 2011 Tim Gee. * * Trickl Open Source Libraries are free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Trickl Open Source Libraries are distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this project. If not, see <http://www.gnu.org/licenses/>. */ package com.trickl.graph.planar; import com.trickl.graph.edges.DirectedEdge; import java.util.Collection; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.NoSuchElementException; import java.util.Set; import org.jgrapht.EdgeFactory; import org.jgrapht.Graphs; /** * Define the planar subgraph of another planar graph. * WARNING: In it's current implementation, the boundary is not maintained * if edges are added or removed to the subgraph. * @author tgee * @param <V> * @param <E> */ public class PlanarSubGraph<V, E> implements PlanarGraph<V, E> { PlanarGraph<V, E> graph; Set<V> vertices; DirectedEdge<V> boundary; public PlanarSubGraph(PlanarGraph<V, E> graph, Set<V> vertices, V boundarySource, V boundaryTarget) { this.graph = graph; this.vertices = vertices; this.boundary = new DirectedEdge<V>(boundarySource, boundaryTarget); } @Override public E addEdge(V sourceVertex, V targetVertex, V beforeVertex, V afterVertex) { throw new UnsupportedOperationException("Not supported yet."); } @Override public boolean addEdge(V sourceVertex, V targetVertex, V beforeVertex, V afterVertex, E e) { throw new UnsupportedOperationException("Not supported yet."); } @Override public V getNextVertex(V source, V target) { if (!containsEdge(source, target)) { throw new NoSuchElementException("Edge not found."); } V next = graph.getNextVertex(source, target); while (!vertices.contains(next)) { next = graph.getNextVertex(next, target); } return next; } @Override public V getPrevVertex(V source, V target) { if (!containsEdge(source, target)) { throw new NoSuchElementException("Edge not found."); } V prev = graph.getPrevVertex(source, target); while (!vertices.contains(prev)) { prev = graph.getPrevVertex(source, prev); } return prev; } @Override public boolean isBoundary(V source, V target) { List<V> boundaryVertices = PlanarGraphs.getBoundaryVertices(this); int sourceIndex = boundaryVertices.indexOf(source); if (sourceIndex < 0) return false; int targetIndex = (sourceIndex + 1) % boundaryVertices.size(); return boundaryVertices.get(targetIndex).equals(target); } @Override public Set<E> getAllEdges(V source, V target) { Set<E> edges = new HashSet<E>(); if (vertices.contains(source) && vertices.contains(target)) { edges.addAll(graph.getAllEdges(source, target)); } return edges; } @Override public E getEdge(V source, V target) { E edge = null; if (containsEdge(source, target)) { edge = graph.getEdge(source, target); } return edge; } @Override public EdgeFactory<V, E> getEdgeFactory() { return graph.getEdgeFactory(); } @Override public E addEdge(V source, V target) { throw new UnsupportedOperationException("Not supported yet."); } @Override public boolean addEdge(V source, V target, E edge) { throw new UnsupportedOperationException("Not supported yet."); } @Override public boolean addVertex(V vertex) { return graph.addVertex(vertex) && vertices.add(vertex); } @Override public boolean containsEdge(V source, V target) { return (vertices.contains(source) && vertices.contains(target) && graph.containsEdge(source, target)); } @Override public boolean containsEdge(E edge) { return (vertices.contains(graph.getEdgeSource(edge)) && vertices.contains(graph.getEdgeTarget(edge)) && graph.containsEdge(edge)); } @Override public boolean containsVertex(V vertex) { return vertices.contains(vertex); } @Override public Set<E> edgeSet() { Set<E> edges = new HashSet<E>(); for (V vertex : vertices) { edges.addAll(edgesOf(vertex)); } return edges; } @Override public Set<E> edgesOf(V v) { Set<E> edges = new LinkedHashSet<E>(); if (vertices.contains(v)) { for (E edge : graph.edgesOf(v)) { V target = Graphs.getOppositeVertex(graph, edge, v); if (vertices.contains(target)) { edges.add(edge); } } } return edges; } @Override public boolean removeAllEdges(Collection<? extends E> edges) { boolean removed = false; for (E edge : edges) { removed = removed && removeEdge(edge); } return removed; } @Override public Set<E> removeAllEdges(V source, V target) { Set<E> edges = new HashSet<E>(); for (E edge : getAllEdges(source, target)) { edges.add(edge); removeEdge(edge); } return edges; } @Override public boolean removeAllVertices(Collection<? extends V> vertices) { boolean removed = false; for (V vertex : vertices) { removed = removed && removeVertex(vertex); } return removed; } @Override public E removeEdge(V source, V target) { E edge = getEdge(source, target); if (edge != null) graph.removeEdge(source, target); return edge; } @Override public boolean removeEdge(E edge) { return containsEdge(edge) && graph.removeEdge(edge); } @Override public boolean removeVertex(V vertex) { return vertices.remove(vertex) && graph.removeVertex(vertex); } @Override public Set<V> vertexSet() { return vertices; } @Override public V getEdgeSource(E edge) { return containsEdge(edge) ? graph.getEdgeSource(edge) : null; } @Override public V getEdgeTarget(E edge) { return containsEdge(edge) ? graph.getEdgeTarget(edge) : null; } @Override public double getEdgeWeight(E edge) { return containsEdge(edge) ? graph.getEdgeWeight(edge) : null; } @Override public DirectedEdge<V> getBoundary() { return boundary; } @Override public void setBoundary(V source, V target) { if (!containsEdge(source, target)) { throw new NoSuchElementException("Edge not in graph."); } this.boundary = new DirectedEdge<V>(source, target); } }