2011-10-23 17 views
0

私は、PythonからCへのGoogleのAIチャレンジ++のための私のボットを書き換えるよ、と私はちょうどではなく、経路探索を処理するために、ブーストのグラフライブラリを使用したいと(グリッド内の)以前のようにPythonで独自のグラフと検索コードをローリングしていました。経路探索ブーストグラフライブラリ

マップは、エッジの周りにラップする単純な正方形グリッドです。

私は前にブーストまたはC++を使用していない(私は非常によくCを知っている)と私は、私は少しの助けを必要と理解することは本当に難しいブーストグラフのドキュメントを見つけることです。私はとのトラブルを抱えている

特定のドキュメント:など

ここでの抜粋です作業のpythonコード:

def do_turn(self, ants): 
    # update path-finding graph 
    for row in range(ants.rows): 
     for col in range(ants.cols): 
      key = (row, col) 
      self.graph[key] = [] 

      def append_if_unoccupied(coord): 
       if ants.passable(coord) and coord not in ants.my_hills(): 
        self.graph[key].append(coord) 

      if row - 1 >= 0: 
       append_if_unoccupied((row - 1, col)) 
      else: 
       append_if_unoccupied((ants.rows + (row - 1), col)) 

      if col - 1 >= 0: 
       append_if_unoccupied((row, col - 1)) 
      else: 
       append_if_unoccupied((row, ants.cols + (col - 1))) 

      if row + 1 < ants.rows: 
       append_if_unoccupied((row + 1, col)) 
      else: 
       append_if_unoccupied((row + 1 - ants.rows, col)) 

      if col + 1 < ants.cols: 
       append_if_unoccupied((row, col + 1)) 
      else: 
       append_if_unoccupied((row, col + 1 - ants.cols)) 

その後、shortest_path(self.graph, loc, dest)(マンハッタンのヒューリスティックとのa *検索)を使用して、他の場所への最短パスを含むリストを取得します。 C + +では、私は何か似て(最短パスのベクトル)をしたいと思います。ここで私が持っているコードは(私はちょうど私が残りを行うことができ、それが障害物なしで、基本的なグリッドに取り組んでき助ける必要がある)、これまでです:

#include <vector> 

#include <boost/config.hpp> 
#include <boost/graph/graph_traits.hpp> 
#include <boost/graph/adjacency_list.hpp> 
//#include <boost/graph/astar_search.hpp> 
#include <boost/graph/dijkstra_shortest_paths.hpp> 

// struct with .row and .col 
#include "Location.h" 

// might not be necessary 
struct Edge {}; 

typedef boost::adjacency_list< 
    boost::listS,  // container for edges 
    boost::vecS,  // container for vertices 
    boost::undirectedS, // directed or undirected edges 
    Location,   // vertex type 
    Edge    // edge type 
> Graph; 

typedef Graph::vertex_descriptor VertexID; 
typedef Graph::edge_descriptor EdgeID; 

const int rows = 100; 
const int cols = 100; 

int main() { 
    Graph graph; 

    // this is probably useless since the graph stores everything 
    // haven't looked for a way around it yet 
    std::vector<std::vector<VertexID>> grid; 

    // create the grid/graph 
    for (int row = 0; row < rows; row++) { 
     grid.resize(rows); 
     for (int col = 0; col < cols; col++) { 
      grid[row].resize(cols); 

      VertexID vID = boost::add_vertex(graph); 
      graph[vID].row = row; 
      graph[vID].col = col; 

      grid[row][col] = vID; 
     } 
    } 

    // add the edges 
    for (int row = 0; row < rows; row++) { 
     for (int col = 0; col < cols; col++) { 
      // add edges for the squares in the grid (it wraps around) 
      // right now all the squares are traversable but that won't always 
      // be the case 
      int c_row, c_col; 

      if (row - 1 >= 0) { 
       c_row = row - 1; 
       c_col = col; 
      } else { 
       c_row = rows + (row - 1); 
       c_col = col; 
      } 
      boost::add_edge(grid[c_row][c_col], grid[row][col], graph); 

      if (col - 1 >= 0) { 
       c_row = row; 
       c_col = col - 1; 
      } else { 
       c_row = row; 
       c_col = cols + (col - 1); 
      } 
      boost::add_edge(grid[c_row][c_col], grid[row][col], graph); 

      if (row + 1 < rows) { 
       c_row = row + 1; 
       c_col = col; 
      } else { 
       c_row = row + 1 - rows; 
       c_col = col; 
      } 
      boost::add_edge(grid[c_row][c_col], grid[row][col], graph); 

      if (col + 1 < cols) { 
       c_row = row; 
       c_col = col + 1; 
      } else { 
       c_row = row; 
       c_col = col + 1 - cols; 
      } 
      boost::add_edge(grid[c_row][c_col], grid[row][col], graph); 
     } 
     // having trouble figuring out use these 
     //boost::astar_search(graph, grid[c] 
     //auto indexmap = get(vertex_index, graph); 
     //dijkstra_shortest_paths(graph, grid[0][0], &p[0], &d[0], weightmap, indexmap, 
          //std::less<int>(), closed_plus<int>(), 
          //(std::numeric_limits<int>::max)(), 0, 
          //default_dijkstra_visitor()); 
    } 
    return 0; 
} 

答えて

3

あなたはBGLを利用するためにC++に切り替える必要がありません。 graph_toolの形でのpythonのためのそれの本当に素敵ラッピングがあります。もちろんshortest pathが含まれています。

5

役立つはず:

boost::astar_search 
    (
     m_navmesh, start, 
     distance_heuristic(m_navmesh, goal), 
     boost::predecessor_map(&p[0]) 
     .distance_map(&d[0]) 
     .visitor(astar_goal_visitor(goal)) 
     .weight_map(get(&NavMeshConnection::dist, m_navmesh)) 
    ); 

この関数は、あなたが自分で作成する必要がファンクタである距離のヒューリスティックを、取ります

// euclidean distance heuristic 
class distance_heuristic : public boost::astar_heuristic <NavMeshGraph, float> { 
public: 
    distance_heuristic(const NavMeshGraph & l, TriangleDescriptor goal) 
    : m_graph(l), m_goal(goal) 
    {} 

    float operator()(TriangleDescriptor u) { 
     const NavMeshTriangle & U = m_graph[u]; 
     const NavMeshTriangle & V = m_graph[m_goal]; 
     float dx = U.pos.x - V.pos.x; 
     float dy = U.pos.y - V.pos.y; 
     return ::sqrt(dx * dx + dy * dy); 
    } 

private: 
    const NavMeshGraph & m_graph; 
    TriangleDescriptor m_goal; 
}; 

あなたはまた、訪問者が必要になります。

// visitor that terminates when we find the goal 
class astar_goal_visitor : public boost::default_astar_visitor { 
public: 
    astar_goal_visitor(TriangleDescriptor goal) : m_goal(goal) 
    {} 

    void examine_vertex(TriangleDescriptor u, const NavMeshGraph & g) 
    { 
     if (u == m_goal) 
      throw found_goal(); 
    } 

private: 
    TriangleDescriptor m_goal; 
}; 

found_gloalは返すものに応じて、単純な構造体やもっと複雑なものにすることができます:最良の方法は、その後に取得され

try { 

    boost::astar_search 
    (
     ... 
    ); 


} catch (found_goal fg) { // found a path to the goal 

:あなたはtry/catchブロックでブースト:: astar_searchを()ラップする必要がありますのでオブジェクトは、訪問者にスローされ

struct found_goal {}; 

このようなキャッチブロック:

std::list<TriangleDescriptor> shortest_path; 
    for (TriangleDescriptor v = goal;; v = p[v]) { 
     shortest_path.push_front(v); 
     if (p[v] == v) 
      break; 
    } 

あなたは重い適応が必要ですが、少なくともこれはあなたの方法でブーストを得るのに十分であるはずです。ところで

は、Djikstraは完全に類似していません。他のすべてのノードからすべての可能なパスを返します。これはスピードは悪いが、前処理には優れている:あなたの世界は静的で、O(1)の中で次の最良ノードを返す経路探索行列をあらかじめ構築することができる。

関連する問題