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

org.jgrapht.alg.RankingPathElementList Maven / Gradle / Ivy

/* ==========================================
 * JGraphT : a free Java graph-theory library
 * ==========================================
 *
 * Project Info:  http://jgrapht.sourceforge.net/
 * Project Creator:  Barak Naveh (http://sourceforge.net/users/barak_naveh)
 *
 * (C) Copyright 2003-2010, by Barak Naveh and Contributors.
 *
 * This program and the accompanying materials are dual-licensed under
 * either
 *
 * (a) the terms of the GNU Lesser General Public License version 2.1
 * as published by the Free Software Foundation, or (at your option) any
 * later version.
 *
 * or (per the licensee's choosing)
 *
 * (b) the terms of the Eclipse Public License v1.0 as published by
 * the Eclipse Foundation.
 */
/* -------------------------
 * RankingPathElementList.java
 * -------------------------
 * (C) Copyright 2007-2010, by France Telecom
 *
 * Original Author:  Guillaume Boulmier and Contributors.
 * Contributor(s):   John V. Sichi
 *
 * $Id$
 *
 * Changes
 * -------
 * 05-Jun-2007 : Initial revision (GB);
 * 05-Jul-2007 : Added support for generics (JVS);
 * 06-Dec-2010 : Bugfixes (GB);
 *
 */
package org.jgrapht.alg;

import java.util.*;

import org.jgrapht.*;
import org.jgrapht.graph.*;


/**
 * List of simple paths in increasing order of weight.
 *
 * @author Guillaume Boulmier
 * @since July 5, 2007
 */
final class RankingPathElementList
    extends AbstractPathElementList>
{
    

    /**
     * Vertex that paths of the list must not disconnect.
     */
    private V guardVertexToNotDisconnect = null;

    private Map, Boolean> path2disconnect =
        new HashMap, Boolean>();

    

    /**
     * Creates a list with an empty path. The list size is 1.
     *
     * @param maxSize max number of paths the list is able to store.
     */
    RankingPathElementList(
        Graph graph,
        int maxSize,
        RankingPathElement pathElement)
    {
        super(graph, maxSize, pathElement);
    }

    /**
     * Creates paths obtained by concatenating the specified edge to the
     * specified paths.
     *
     * @param prevPathElementList paths, list of 
     * RankingPathElement.
     * @param edge edge reaching the end vertex of the created paths.
     * @param maxSize maximum number of paths the list is able to store.
     */
    RankingPathElementList(
        Graph graph,
        int maxSize,
        RankingPathElementList elementList,
        E edge)
    {
        this(graph, maxSize, elementList, edge, null);

        assert (!this.pathElements.isEmpty());
    }

    /**
     * Creates paths obtained by concatenating the specified edge to the
     * specified paths.
     *
     * @param prevPathElementList paths, list of 
     * RankingPathElement.
     * @param edge edge reaching the end vertex of the created paths.
     * @param maxSize maximum number of paths the list is able to store.
     */
    RankingPathElementList(
        Graph graph,
        int maxSize,
        RankingPathElementList elementList,
        E edge,
        V guardVertexToNotDisconnect)
    {
        super(graph, maxSize, elementList, edge);
        this.guardVertexToNotDisconnect = guardVertexToNotDisconnect;

        // loop over the path elements in increasing order of weight.
        for (int i = 0; (i < elementList.size()) && (size() < maxSize); i++) {
            RankingPathElement prevPathElement = elementList.get(i);

            if (isNotValidPath(prevPathElement, edge)) {
                // go to the next path element in the loop
                continue;
            }

            double weight = calculatePathWeight(prevPathElement, edge);
            RankingPathElement newPathElement =
                new RankingPathElement(
                    this.graph,
                    prevPathElement,
                    edge,
                    weight);

            // the new path is inserted at the end of the list.
            this.pathElements.add(newPathElement);
        }
    }

    /**
     * Creates an empty list. The list size is 0.
     *
     * @param maxSize max number of paths the list is able to store.
     */
    RankingPathElementList(Graph graph, int maxSize, V vertex)
    {
        super(graph, maxSize, vertex);
    }

    

    /**
     * 

Adds paths in the list at vertex y. Candidate paths are obtained by * concatenating the specified edge (v->y) to the paths * elementList at vertex v.

* * Complexity = * *
    *
  • w/o guard-vertex: O(k*np) where k is the * max size limit of the list and np is the maximum number of * vertices in the paths stored in the list
  • *
  • with guard-vertex: O(k*(m+n)) where k is * the max size limit of the list, m is the number of edges of * the graph and n is the number of vertices of the graph, * O(m+n) being the complexity of the * ConnectivityInspector to check whether a path exists towards the * guard-vertex
  • *
* * @param elementList list of paths at vertex v. * @param edge edge (v->y). * * @return true if at least one path has been added in the * list, false otherwise. */ public boolean addPathElements( RankingPathElementList elementList, E edge) { assert (this.vertex.equals( Graphs.getOppositeVertex( this.graph, edge, elementList.getVertex()))); boolean pathAdded = false; // loop over the paths elements of the list at vertex v. for ( int vIndex = 0, yIndex = 0; vIndex < elementList.size(); vIndex++) { RankingPathElement prevPathElement = elementList.get(vIndex); if (isNotValidPath(prevPathElement, edge)) { // checks if path is simple and if guard-vertex is not // disconnected. continue; } double newPathWeight = calculatePathWeight(prevPathElement, edge); RankingPathElement newPathElement = new RankingPathElement( this.graph, prevPathElement, edge, newPathWeight); // loop over the paths of the list at vertex y from yIndex to the // end. RankingPathElement yPathElement = null; for (; yIndex < size(); yIndex++) { yPathElement = get(yIndex); // case when the new path is shorter than the path Py stored at // index y if (newPathWeight < yPathElement.getWeight()) { this.pathElements.add(yIndex, newPathElement); pathAdded = true; // ensures max size limit is not exceeded. if (size() > this.maxSize) { this.pathElements.remove(this.maxSize); } break; } // case when the new path is of the same length as the path Py // stored at index y if (newPathWeight == yPathElement.getWeight()) { this.pathElements.add(yIndex + 1, newPathElement); pathAdded = true; // ensures max size limit is not exceeded. if (size() > this.maxSize) { this.pathElements.remove(this.maxSize); } break; } } // case when the new path is longer than the longest path in the // list (Py stored at the last index y) if (newPathWeight > yPathElement.getWeight()) { // ensures max size limit is not exceeded. if (size() < this.maxSize) { // the new path is inserted at the end of the list. this.pathElements.add(newPathElement); pathAdded = true; } else { // max size limit is reached -> end of the loop over the // paths elements of the list at vertex v. break; } } } return pathAdded; } /** * @return list of RankingPathElement. */ List> getPathElements() { return this.pathElements; } /** * Costs taken into account are the weights stored in Edge * objects. * * @param pathElement * @param edge the edge via which the vertex was encountered. * * @return the cost obtained by concatenation. * * @see Graph#getEdgeWeight(E) */ private double calculatePathWeight( RankingPathElement pathElement, E edge) { double pathWeight = this.graph.getEdgeWeight(edge); // otherwise it's the start vertex. if ((pathElement.getPrevEdge() != null)) { pathWeight += pathElement.getWeight(); } return pathWeight; } /** * Ensures that paths of the list do not disconnect the guard-vertex. * * @return true if the specified path element disconnects the * guard-vertex, false otherwise. */ private boolean isGuardVertexDisconnected( RankingPathElement prevPathElement) { if (this.guardVertexToNotDisconnect == null) { return false; } if (this.path2disconnect.containsKey(prevPathElement)) { return this.path2disconnect.get(prevPathElement); } ConnectivityInspector connectivityInspector; MaskFunctor connectivityMask; if (this.graph instanceof DirectedGraph) { connectivityMask = new PathMask(prevPathElement); DirectedMaskSubgraph connectivityGraph = new DirectedMaskSubgraph( (DirectedGraph) this.graph, connectivityMask); connectivityInspector = new ConnectivityInspector( connectivityGraph); } else { connectivityMask = new PathMask(prevPathElement); UndirectedMaskSubgraph connectivityGraph = new UndirectedMaskSubgraph( (UndirectedGraph) this.graph, connectivityMask); connectivityInspector = new ConnectivityInspector( connectivityGraph); } if (connectivityMask.isVertexMasked(this.guardVertexToNotDisconnect)) { // the guard-vertex was already in the path element -> invalid path this.path2disconnect.put(prevPathElement, true); return true; } if (!connectivityInspector.pathExists( this.vertex, this.guardVertexToNotDisconnect)) { this.path2disconnect.put(prevPathElement, true); return true; } this.path2disconnect.put(prevPathElement, false); return false; } private boolean isNotValidPath( RankingPathElement prevPathElement, E edge) { return !isSimplePath(prevPathElement, edge) || isGuardVertexDisconnected(prevPathElement); } /** * Ensures that paths of the list are simple (check that the vertex was not * already in the path element). * * @param prevPathElement * @param edge * * @return true if the resulting path (obtained by * concatenating the specified edge to the specified path) is simple, * false otherwise. */ private boolean isSimplePath( RankingPathElement prevPathElement, E edge) { V endVertex = Graphs.getOppositeVertex( this.graph, edge, prevPathElement.getVertex()); assert (endVertex.equals(this.vertex)); RankingPathElement pathElementToTest = prevPathElement; do { if (pathElementToTest.getVertex().equals(endVertex)) { return false; } else { pathElementToTest = pathElementToTest.getPrevPathElement(); } } while (pathElementToTest != null); return true; } private static class PathMask implements MaskFunctor { private Set maskedEdges; private Set maskedVertices; /** * Creates a mask for all the edges and the vertices of the path * (including the 2 extremity vertices). * * @param pathElement */ PathMask(RankingPathElement pathElement) { this.maskedEdges = new HashSet(); this.maskedVertices = new HashSet(); while (pathElement.getPrevEdge() != null) { this.maskedEdges.add(pathElement.getPrevEdge()); this.maskedVertices.add(pathElement.getVertex()); pathElement = pathElement.getPrevPathElement(); } this.maskedVertices.add(pathElement.getVertex()); } // implement MaskFunctor @Override public boolean isEdgeMasked(E edge) { return this.maskedEdges.contains(edge); } // implement MaskFunctor @Override public boolean isVertexMasked(V vertex) { return this.maskedVertices.contains(vertex); } } } // End RankingPathElementList.java




© 2015 - 2024 Weber Informatics LLC | Privacy Policy