Browse Source

dfs and bfs

Former-commit-id: ea8448e169b56db04941cceb882524afa95473e4
Alec Jacobson 8 năm trước cách đây
mục cha
commit
ce0c1eb7c7
3 tập tin đã thay đổi với 148 bổ sung1 xóa
  1. 93 0
      include/igl/bfs.cpp
  2. 54 0
      include/igl/bfs.h
  3. 1 1
      include/igl/dfs.cpp

+ 93 - 0
include/igl/bfs.cpp

@@ -0,0 +1,93 @@
+#include "bfs.h"
+#include "list_to_matrix.h"
+#include <vector>
+#include <queue>
+
+template <
+  typename AType,
+  typename DerivedD,
+  typename DerivedP>
+IGL_INLINE void igl::bfs(
+  const AType & A,
+  const size_t s,
+  Eigen::PlainObjectBase<DerivedD> & D,
+  Eigen::PlainObjectBase<DerivedP> & P)
+{
+  std::vector<typename DerivedD::Scalar> vD;
+  std::vector<typename DerivedP::Scalar> vP;
+  bfs(A,s,vD,vP);
+  list_to_matrix(vD,D);
+  list_to_matrix(vP,P);
+}
+
+template <
+  typename AType,
+  typename DType,
+  typename PType>
+IGL_INLINE void igl::bfs(
+  const std::vector<std::vector<AType> > & A,
+  const size_t s,
+  std::vector<DType> & D,
+  std::vector<PType> & P)
+{
+  // number of nodes
+  int N = s+1;
+  for(const auto & Ai : A) for(const auto & a : Ai) N = std::max(N,a+1);
+  std::vector<bool> seen(N,false);
+  P.resize(N,-1);
+  std::queue<std::pair<int,int> > Q;
+  Q.push({s,-1});
+  while(!Q.empty())
+  {
+    const int f = Q.front().first;
+    const int p = Q.front().second;
+    Q.pop();
+    if(seen[f])
+    {
+      continue;
+    }
+    D.push_back(f);
+    P[f] = p;
+    seen[f] = true;
+    for(const auto & n : A[f]) Q.push({n,f});
+  }
+}
+
+
+template <
+  typename AType,
+  typename DType,
+  typename PType>
+IGL_INLINE void igl::bfs(
+  const Eigen::SparseMatrix<AType> & A,
+  const size_t s,
+  std::vector<DType> & D,
+  std::vector<PType> & P)
+{
+  // number of nodes
+  int N = A.rows();
+  assert(A.rows() == A.cols());
+  std::vector<bool> seen(N,false);
+  P.resize(N,-1);
+  std::queue<std::pair<int,int> > Q;
+  Q.push({s,-1});
+  while(!Q.empty())
+  {
+    const int f = Q.front().first;
+    const int p = Q.front().second;
+    Q.pop();
+    if(seen[f])
+    {
+      continue;
+    }
+    D.push_back(f);
+    P[f] = p;
+    seen[f] = true;
+    for(typename Eigen::SparseMatrix<AType>::InnerIterator it (A,f); it; ++it)
+    {
+      if(it.value()) Q.push({it.index(),f});
+    }
+  }
+
+}
+

+ 54 - 0
include/igl/bfs.h

@@ -0,0 +1,54 @@
+#ifndef IGL_BFS_H
+#define IGL_BFS_H
+#include "igl_inline.h"
+#include <Eigen/Core>
+#include <vector>
+#include <Eigen/Sparse>
+namespace igl
+{
+  // Traverse a **directed** graph represented by an adjacency list using
+  // breadth first search
+  //
+  // Inputs:
+  //   A  #V list of adjacency lists  or #V by #V adjacency matrix
+  //   s  starting node (index into A)
+  // Outputs:
+  //   D  #V list of indices into rows of A in the order in which graph nodes
+  //     are discovered.
+  //   P  #V list of indices into rows of A of predecessor in resulting
+  //     spanning tree {-1 indicates root/not discovered), order corresponds to
+  //     V **not** D.
+  template <
+    typename AType,
+    typename DerivedD,
+    typename DerivedP>
+  IGL_INLINE void bfs(
+    const AType & A,
+    const size_t s,
+    Eigen::PlainObjectBase<DerivedD> & D,
+    Eigen::PlainObjectBase<DerivedP> & P);
+
+  template <
+    typename AType,
+    typename DType,
+    typename PType>
+  IGL_INLINE void bfs(
+    const std::vector<std::vector<AType> > & A,
+    const size_t s,
+    std::vector<DType> & D,
+    std::vector<PType> & P);
+  template <
+    typename AType,
+    typename DType,
+    typename PType>
+  IGL_INLINE void bfs(
+    const Eigen::SparseMatrix<AType> & A,
+    const size_t s,
+    std::vector<DType> & D,
+    std::vector<PType> & P);
+}
+#ifndef IGL_STATIC_LIBRARY
+#  include "bfs.cpp"
+#endif
+#endif
+

+ 1 - 1
include/igl/dfs.cpp

@@ -36,7 +36,7 @@ IGL_INLINE void igl::dfs(
   std::vector<CType> & C)
 {
   // number of nodes
-  int N = 0;
+  int N = s+1;
   for(const auto & Ai : A) for(const auto & a : Ai) N = std::max(N,a+1);
   std::vector<bool> seen(N,false);
   P.resize(N,-1);