Reputation: 57
Hi I am pretty new to the Boost libraries. I want to build a graph from a square two dimensional map that will be used for a star algorithm (the map is an array with 1s and 0s for both wall and normal terrain).
The graph should be undirected and change with the size of the map. Each node has 8 edges (except for sides of the map).
I've gone through a few examples but I don't understand the procedure for building graphs of this size since most examples look like this (look bellow) in the boost graph library documentation.
Any help or ideas will be really appreciated
#include <iostream> // for std::cout
#include <utility> // for std::pair
#include <algorithm> // for std::for_each
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
using namespace boost;
int main(int,char*[])
{
// create a typedef for the Graph type
typedef adjacency_list<vecS, vecS, bidirectionalS> Graph;
// Make convenient labels for the vertices
enum { A, B, C, D, E, N };
const int num_vertices = N;
const char* name = "ABCDE";
// writing out the edges in the graph
typedef std::pair<int, int> Edge;
Edge edge_array[] =
{ Edge(A,B), Edge(A,D), Edge(C,A), Edge(D,C),
Edge(C,E), Edge(B,D), Edge(D,E) };
const int num_edges = sizeof(edge_array)/sizeof(edge_array[0]);
// declare a graph object
Graph g(num_vertices);
// add the edges to the graph object
for (int i = 0; i < num_edges; ++i){
add_edge(edge_array[i].first, edge_array[i].second, g);
}
return 0;
}
Upvotes: 2
Views: 667
Reputation: 393064
On second reading of the question it seems like your question is simply how to add nodes and edges.
Here's a start that queries for the number of rows/columns and creates the square "grid". I use a nodes
matrix on the side to have easy lookup from (x,y) in the grid to the vertex descriptor in the graph.
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
#include <iostream>
using namespace boost;
struct Point {
int x, y;
friend std::ostream& operator<<(std::ostream& os, Point p) {
return os << "[" << p.x << "," << p.y << "]";
}
};
int main() {
using std::vector;
using Graph = adjacency_list<setS, vecS, undirectedS, Point>;
using vertex_descriptor = Graph::vertex_descriptor;
Graph lattuce;
int num_rows;
if (!(std::cin >> num_rows && num_rows > 0))
return 255;
vector<vector<vertex_descriptor> > nodes(num_rows, vector<vertex_descriptor>(num_rows));
for (auto i = 0; i < num_rows; ++i)
for (auto j = 0; j < num_rows; ++j)
nodes[i][j] = add_vertex(Point{i,j}, lattuce);
auto is_valid = [num_rows](Point p) { return (p.x >= 0 && p.x < num_rows) &&
(p.y >= 0 && p.y < num_rows); };
for (auto vd : make_iterator_range(vertices(lattuce))) {
auto p = lattuce[vd];
for (Point neighbour : {
Point { p.x - 1, p.y - 1 }, Point { p.x - 1, p.y + 0 }, Point { p.x - 1, p.y + 1 },
Point { p.x + 0, p.y - 1 }, Point { p.x + 0, p.y + 1 },
Point { p.x + 1, p.y - 1 }, Point { p.x + 1, p.y + 0 }, Point { p.x + 1, p.y + 1 },
})
{
if (is_valid(neighbour))
add_edge(nodes[neighbour.x][neighbour.y], vd, lattuce);
};
}
print_graph(lattuce, get(vertex_bundle, lattuce));
}
Prints, e.g. for input 3
:
[0,0] <--> [0,1] [1,0] [1,1]
[0,1] <--> [0,0] [0,2] [1,0] [1,1] [1,2]
[0,2] <--> [0,1] [1,1] [1,2]
[1,0] <--> [0,0] [0,1] [1,1] [2,0] [2,1]
[1,1] <--> [0,0] [0,1] [0,2] [1,0] [1,2] [2,0] [2,1] [2,2]
[1,2] <--> [0,1] [0,2] [1,1] [2,1] [2,2]
[2,0] <--> [1,0] [1,1] [2,1]
[2,1] <--> [1,0] [1,1] [1,2] [2,0] [2,2]
[2,2] <--> [1,1] [1,2] [2,1]
Upvotes: 1