/* * Copyright 2008 Network Engine for Objects in Lund AB [neotechnology.com] * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.neo4j.graphalgo.shortestpath; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import org.neo4j.graphdb.Direction; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.RelationshipType; /** * Dijkstra class identical to {@link Dijkstra} except that it searches only * from the start node. Theoretical complexity is identical, but in practice * this has to traverse more of the network, i.e. runs slower. * @author Patrik Larsson * @param <CostType> * The datatype the edge weights will be represented by. */ public class SingleDirectionDijkstra<CostType> extends Dijkstra<CostType> { public SingleDirectionDijkstra( CostType startCost, Node startNode, Node endNode, CostEvaluator<CostType> costEvaluator, CostAccumulator<CostType> costAccumulator, Comparator<CostType> costComparator, Direction relationDirection, RelationshipType... costRelationTypes ) { super( startCost, startNode, endNode, costEvaluator, costAccumulator, costComparator, relationDirection, costRelationTypes ); } /** * Internal calculate method that will do the calculation. This can however * be called externally to manually trigger the calculation. */ @Override public boolean calculate() { // Don't do it more than once if ( doneCalculation ) { return true; } doneCalculation = true; // Special case when path length is zero if ( startNode.equals( endNode ) ) { foundPathsMiddleNodes = new HashSet<Node>(); foundPathsMiddleNodes.add( startNode ); foundPathsCost = costAccumulator.addCosts( startCost, startCost ); return true; } HashMap<Node,CostType> seen1 = new HashMap<Node,CostType>(); HashMap<Node,CostType> seen2 = new HashMap<Node,CostType>(); HashMap<Node,CostType> dists1 = new HashMap<Node,CostType>(); HashMap<Node,CostType> dists2 = new HashMap<Node,CostType>(); DijstraIterator iter1 = new DijstraIterator( startNode, predecessors1, seen1, seen2, dists1, dists2, false ); dists2.put( endNode, startCost ); seen2.put( endNode, startCost ); while ( iter1.hasNext() && !limitReached() ) { iter1.next(); if ( iter1.isDone() ) // A path was found { return true; } } return false; } }