// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2016 Alec Jacobson // // This Source Code Form is subject to the terms of the Mozilla Public License // v. 2.0. If a copy of the MPL was not distributed with this file, You can // obtain one at http://mozilla.org/MPL/2.0/. #include "dijkstra.h" template IGL_INLINE int igl::dijkstra( const IndexType &source, const std::set &targets, const std::vector >& VV, const std::vector& weights, Eigen::PlainObjectBase &min_distance, Eigen::PlainObjectBase &previous) { int numV = VV.size(); min_distance.setConstant(numV, 1, std::numeric_limits::infinity()); min_distance[source] = 0; previous.setConstant(numV, 1, -1); std::set > vertex_queue; vertex_queue.insert(std::make_pair(min_distance[source], source)); while (!vertex_queue.empty()) { typename DerivedD::Scalar dist = vertex_queue.begin()->first; IndexType u = vertex_queue.begin()->second; vertex_queue.erase(vertex_queue.begin()); if (targets.find(u)!= targets.end()) return u; // Visit each edge exiting u const std::vector &neighbors = VV[u]; for (std::vector::const_iterator neighbor_iter = neighbors.begin(); neighbor_iter != neighbors.end(); neighbor_iter++) { IndexType v = *neighbor_iter; typename DerivedD::Scalar distance_through_u = dist + weights[u]; if (distance_through_u < min_distance[v]) { vertex_queue.erase(std::make_pair(min_distance[v], v)); min_distance[v] = distance_through_u; previous[v] = u; vertex_queue.insert(std::make_pair(min_distance[v], v)); } } } //we should never get here return -1; } template IGL_INLINE int igl::dijkstra( const IndexType &source, const std::set &targets, const std::vector >& VV, Eigen::PlainObjectBase &min_distance, Eigen::PlainObjectBase &previous) { std::vector weights(VV.size(), 1.0); return dijkstra(source, targets, VV, weights, min_distance, previous); } template IGL_INLINE void igl::dijkstra( const IndexType &vertex, const Eigen::MatrixBase &previous, std::vector &path) { IndexType source = vertex; path.clear(); for ( ; source != -1; source = previous[source]) path.push_back(source); } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation template int igl::dijkstra, Eigen::Matrix >(int const&, std::set, std::allocator > const&, std::vector >, std::allocator > > > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::dijkstra >(int const&, Eigen::MatrixBase > const&, std::vector >&); #endif