Skip to content

Instantly share code, notes, and snippets.

@cvvergara
Created March 30, 2015 17:49
Show Gist options
  • Save cvvergara/a760bffb807336381bd5 to your computer and use it in GitHub Desktop.
Save cvvergara/a760bffb807336381bd5 to your computer and use it in GitHub Desktop.
Dijkstra in with working only on the the 3 graphs graphs. And stopping when target is reached. Going from 2 to 3 and from 3 to 2
#include <boost/config.hpp>
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include "postgres.h"
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
/*
To be able to distinguish the edges (source,target) from the (target,source)
"cost" column weights are set to 1 for (source,target)
"reverse_cost" column weights are set to 2 for (target,source)
*/
typedef struct {
int64_t id;
int64_t source;
int64_t target;
float8 cost;
float8 reverse_cost;
} pgr_edge_t;
struct Vertex {
int64_t id;
double cost;
};
struct boost_edge_t{
int64_t id;
float8 cost;
int64_t source_id;
int64_t target_id;
} ;
void import_from_file(const std::string &input_file_name, pgr_edge_t *edges, unsigned int *count) {
const char* file_name = input_file_name.c_str();
std::ifstream ifs(file_name);
if (!ifs) {
std::cerr << "The file " << file_name << " can not be opened!" << std::endl;
exit(1);
}
ifs >> (*count);
long edge_id, start_id, end_id;
double edge_weight, reverse_weight;
int i = 0;
while (i < (*count) && ifs >> edge_id) {
if (edge_id == -1) break;
edges[i].id = edge_id;
ifs >> edges[i].source;
ifs >> edges[i].target;
ifs >> edges[i].cost;
ifs >> edges[i].reverse_cost;
i++;
}
ifs.close();
}
using namespace boost;
// define visitor for discover_vertex event
template <class Vertex, class Tag>
struct target_visitor : public default_dijkstra_visitor
{
target_visitor(Vertex u) : v(u) { }
template <class Graph>
void examine_vertex(Vertex u, Graph& g)
{
if( u == v ) {
throw(-1);
}
}
private:
Vertex v;
};
template <class Vertex, class Tag>
target_visitor<Vertex, Tag>
target_visit(Vertex u, Tag) {
return target_visitor<Vertex, Tag>(u);
}
template < class G > void
graph_dijkstra( G & digraph, int64_t start_vertex, int64_t end_vertex) {
typedef typename graph_traits < G >::vertex_descriptor vertex_descriptor;
vertex_descriptor _source = vertex(start_vertex, digraph);
if ((int64_t)_source >= num_vertices(digraph))
{
std::cout << "Starting vertex not found" << std::endl;
return ;
}
vertex_descriptor _target = vertex(end_vertex, digraph);
if ((int64_t)_target >= num_vertices(digraph))
{
//*err_msg = (char *) "Ending vertex not found";
std::cout << "Ending vertex not found" << std::endl;
return ;
}
std::cout << "Number of vertices in the graph" << num_vertices(digraph) << std::endl;
std::vector<vertex_descriptor> predecessors(num_vertices(digraph));
std::vector<float8> distances(num_vertices(digraph));
try {
dijkstra_shortest_paths(digraph, _source,
predecessor_map(&predecessors[0])
.weight_map(get(&boost_edge_t::cost, digraph))
.distance_map(&distances[0]).visitor(target_visit(_target, on_examine_vertex())));
}
catch( ... ) {
}
std::cout<< "distance(" << _target << ")" << distances[_target] << std::endl;
while (_target != _source) {
if (_target == predecessors[_target]) {
//*err_msg = (char *) "No path found";
std::cout << "No Path Found" << std::endl;
return ;
}
_target = predecessors[_target];
std::cout<< "distance(" << _target << ")" << distances[_target] << std::endl;
}
}
template <class G, class E>
static void
graph_add_edge(G &graph, const pgr_edge_t &edge, bool undirectedOnDirected)
{
bool inserted;
E e;
if (edge.cost >= 0) {
tie(e, inserted) = add_edge(edge.source, edge.target, graph);
graph[e].cost = edge.cost;
graph[e].id = edge.id;
}
if (edge.reverse_cost >= 0) {
tie(e, inserted) = add_edge(edge.target, edge.source, graph);
graph[e].cost = edge.reverse_cost;
graph[e].id = edge.id;
}
if (undirectedOnDirected) {
if (edge.cost >= 0) {
tie(e, inserted) = add_edge(edge.target, edge.source, graph);
graph[e].cost = edge.cost;
graph[e].id = edge.id;
}
if (edge.reverse_cost >= 0) {
tie(e, inserted) = add_edge(edge.source, edge.target, graph);
graph[e].cost = edge.reverse_cost;
graph[e].id = edge.id;
}
}
}
template < typename DirectedGraph > void
simulation_undirected_in_directed_graph(pgr_edge_t *data_edges, int count)
{
const int V = 1;
DirectedGraph digraph(V);
typename graph_traits < DirectedGraph >::vertex_descriptor vd;
typedef typename graph_traits < DirectedGraph >::edge_descriptor ed;
typename graph_traits < DirectedGraph >::out_edge_iterator out, out_end;
typename graph_traits < DirectedGraph >::edge_iterator ei;
typename graph_traits < DirectedGraph >::vertex_iterator vi;
bool inserted;
std::cout << "UNDIRECTED ON BOOST::DIRECTED GRAPH DEMO\n";
for (int i=0; i < count; ++i) {
graph_add_edge< DirectedGraph, ed>(digraph, data_edges[i], true);
}
for (vi = vertices(digraph).first; vi!=vertices(digraph).second; ++vi) {
std::cout << "out_edges(" << *vi << "):";
for (boost::tie(out, out_end) = out_edges(*vi, digraph); out != out_end; ++out) {
std::cout << ' ' << *out << "=" << digraph[*out].cost;
}
std::cout << std::endl;
}
std::cout << std::endl;
graph_dijkstra( digraph, 2, 3);
graph_dijkstra( digraph, 3, 2);
}
template < typename DirectedGraph > void
directed_graph_demo(pgr_edge_t *data_edges, int count)
{
const int V = 1;
DirectedGraph digraph(V);
typedef typename graph_traits < DirectedGraph >::vertex_descriptor vertex_descriptor;
typedef typename graph_traits < DirectedGraph >::edge_descriptor edge_descriptor;
typename graph_traits < DirectedGraph >::out_edge_iterator out, out_end;
typename graph_traits < DirectedGraph >::edge_iterator e, ei;
typename graph_traits < DirectedGraph >::vertex_iterator vi;
bool inserted;
std::cout << "DIRECTED GRAPH DEMO\n";
for (int i=0; i < count; ++i) {
graph_add_edge< DirectedGraph, edge_descriptor>(digraph, data_edges[i], false);
}
for (vi = vertices(digraph).first; vi!=vertices(digraph).second; ++vi) {
std::cout << "out_edges(" << *vi << "):";
for (boost::tie(out, out_end) = out_edges(*vi, digraph); out != out_end; ++out) {
std::cout << ' ' << *out << "=" << digraph[*out].cost;
}
std::cout << std::endl;
}
std::cout << std::endl;
graph_dijkstra( digraph, 2, 3);
graph_dijkstra( digraph, 3, 2);
}
// using boost undirectedGraph
template < typename UndirectedGraph > void
undirected_graph_demo(pgr_edge_t *data_edges, int count)
{
const int V = 3;
UndirectedGraph undigraph(V);
typename graph_traits < UndirectedGraph >::vertex_descriptor vd;
typedef typename graph_traits < UndirectedGraph >::edge_descriptor ed;
typename graph_traits < UndirectedGraph >::out_edge_iterator out, out_end;
typename graph_traits < UndirectedGraph >::edge_iterator e, ei;
typename graph_traits < UndirectedGraph >::vertex_iterator vi;
bool inserted;
std::deque< typename graph_traits < UndirectedGraph >::vertex_descriptor > vert;
std::cout << "UNDIRECTED GRAPH DEMO\n";
for (int i=0; i < count; ++i) {
graph_add_edge< UndirectedGraph, ed>(undigraph, data_edges[i],false);
}
for (vi = vertices(undigraph).first; vi!=vertices(undigraph).second; ++vi) {
std::cout << "out_edges(" << *vi << "):";
for (boost::tie(out, out_end) = out_edges(*vi,undigraph); out != out_end; ++out) {
std::cout << ' ' << *out << "=" << undigraph[*out].cost;
}
std::cout << std::endl;
}
std::cout << std::endl;
graph_dijkstra( undigraph, 2, 3);
graph_dijkstra( undigraph, 3, 2);
}
int
main()
{
pgr_edge_t edges[100];
unsigned int count = 0;
std::string fileName("./sampledata.data");
import_from_file(fileName, edges, &count);
typedef adjacency_list < listS, vecS, undirectedS,
no_property, boost_edge_t > UndirectedGraph;
typedef adjacency_list < listS, vecS, directedS,
no_property, boost_edge_t > DirectedGraph;
undirected_graph_demo < UndirectedGraph > (edges, count);
directed_graph_demo < DirectedGraph > (edges, count);
simulation_undirected_in_directed_graph < DirectedGraph > (edges, count);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment