Commit 00aa9c5d authored by Tiago Peixoto's avatar Tiago Peixoto

Implement search module

This module contains several search algorithms and a visitor interface.
parent 38b991e1
......@@ -12,10 +12,11 @@ Available subpackages
community
correlations
draw
generation
topology
flow
generation
run_action
search_module
spectral
stats
run_action
topology
util
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
<!-- property keys -->
<key id="key0" for="node" attr.name="name" attr.type="string" />
<key id="key1" for="edge" attr.name="weight" attr.type="float" />
<graph id="G" edgedefault="undirected" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst">
<!-- graph properties -->
<!-- vertices -->
<node id="n0">
<data key="key0">Bob</data>
</node>
<node id="n1">
<data key="key0">Alice</data>
</node>
<node id="n2">
<data key="key0">Carol</data>
</node>
<node id="n3">
<data key="key0">Carlos</data>
</node>
<node id="n4">
<data key="key0">Chuck</data>
</node>
<node id="n5">
<data key="key0">Dave</data>
</node>
<node id="n6">
<data key="key0">Eve</data>
</node>
<node id="n7">
<data key="key0">Isaac</data>
</node>
<node id="n8">
<data key="key0">Oscar</data>
</node>
<node id="n9">
<data key="key0">Imothep</data>
</node>
<!-- edges -->
<edge id="e0" source="n0" target="n6">
<data key="key1">0x1.9e7393907213cp+1</data>
</edge>
<edge id="e1" source="n0" target="n4">
<data key="key1">0x1.015b0db294a3dp+2</data>
</edge>
<edge id="e2" source="n0" target="n3">
<data key="key1">0x1.12bcc343cdc2ap+2</data>
</edge>
<edge id="e3" source="n0" target="n7">
<data key="key1">0x1.ba3952afb7e9ep+1</data>
</edge>
<edge id="e4" source="n1" target="n8">
<data key="key1">0x1.0ff8065948f03p+1</data>
</edge>
<edge id="e5" source="n1" target="n5">
<data key="key1">0x1.a872068a0a4e5p+1</data>
</edge>
<edge id="e6" source="n1" target="n3">
<data key="key1">0x1.2816bc78b034fp+2</data>
</edge>
<edge id="e7" source="n2" target="n6">
<data key="key1">0x1.82250c1278b54p+2</data>
</edge>
<edge id="e8" source="n2" target="n9">
<data key="key1">0x1.8bb78dae3ee5ap+0</data>
</edge>
<edge id="e9" source="n3" target="n6">
<data key="key1">0x1.587ad2707187fp+2</data>
</edge>
<edge id="e10" source="n3" target="n9">
<data key="key1">0x1.7df6a3095905ep+2</data>
</edge>
<edge id="e11" source="n4" target="n6">
<data key="key1">0x1.62ac71123a64ap+0</data>
</edge>
<edge id="e12" source="n4" target="n7">
<data key="key1">0x1.2c156b7e6a49p+1</data>
</edge>
<edge id="e13" source="n4" target="n9">
<data key="key1">0x1.543c16e43a9bfp+2</data>
</edge>
<edge id="e14" source="n5" target="n8">
<data key="key1">0x1.5a4ab7454f0e2p+1</data>
</edge>
<edge id="e15" source="n6" target="n7">
<data key="key1">0x1.841d9db6417f3p+1</data>
</edge>
<edge id="e16" source="n6" target="n9">
<data key="key1">0x1.20af02e97ed9ep+2</data>
</edge>
</graph>
</graphml>
.. automodule:: graph_tool.search
:members:
:undoc-members:
## Process this file with automake to produce Makefile.in
SUBDIRS = generation stats clustering community util topology centrality correlations flow layout
SUBDIRS = generation stats clustering community util topology centrality correlations flow layout search
AM_CPPFLAGS =\
-I$(srcdir)/.. \
......
## Process this file with automake to produce Makefile.in
AM_CPPFLAGS = $(MOD_CPPFLAGS)
AM_CFLAGS=$(AM_CXXFLAGS)
libgraph_tool_searchdir = $(MOD_DIR)/search
libgraph_tool_search_LTLIBRARIES = libgraph_tool_search.la
libgraph_tool_search_la_includedir = $(MOD_DIR)/include
libgraph_tool_search_la_LIBADD = $(MOD_LIBADD)
libgraph_tool_search_la_LDFLAGS = $(MOD_LDFLAGS)
libgraph_tool_search_la_SOURCES = \
graph_bfs.cc\
graph_dfs.cc\
graph_dijkstra.cc\
graph_bellman_ford.cc\
graph_astar.cc\
graph_astar_implicit.cc\
graph_search_bind.cc
libgraph_tool_search_la_include_HEADERS =
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2007-2010 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "graph_filtering.hh"
#include "graph_python_interface.hh"
#include <boost/python.hpp>
#include <boost/graph/astar_search.hpp>
#include "graph.hh"
#include "graph_selectors.hh"
#include "graph_util.hh"
#include "graph_astar.hh"
using namespace std;
using namespace boost;
using namespace graph_tool;
struct do_astar_search
{
template <class Graph, class DistanceMap, class WeightMap>
void operator()(const Graph& g, size_t s, DistanceMap dist,
boost::any pred_map, WeightMap weight,
AStarVisitorWrapper vis, pair<AStarCmp, AStarCmb> cmp,
pair<python::object, python::object> range,
pair<python::object, python::object> h) const
{
typedef typename property_traits<DistanceMap>::value_type dtype_t;
dtype_t z = python::extract<dtype_t>(range.first);
dtype_t i = python::extract<dtype_t>(range.second);
typedef typename property_map_type::
apply<int32_t, typeof(get(vertex_index, g))>::type pred_t;
pred_t pred = any_cast<pred_t>(pred_map);
astar_search(g, vertex(s, g), AStarH<dtype_t>(h.first, h.second),
visitor(vis).weight_map(weight).
predecessor_map(pred).
distance_map(dist).distance_compare(cmp.first).
distance_combine(cmp.second).distance_inf(i).
distance_zero(z));
}
};
void a_star_search(GraphInterface& g, python::object gi, size_t source,
boost::any dist_map, boost::any pred_map, boost::any weight,
python::object vis, python::object cmp, python::object cmb,
python::object zero, python::object inf, python::object h)
{
run_action<graph_tool::detail::all_graph_views,mpl::true_>()
(g, bind<void>(do_astar_search(), _1, source, _2, pred_map, _3,
AStarVisitorWrapper(gi, vis), make_pair(AStarCmp(cmp),
AStarCmb(cmb)),
make_pair(zero, inf), make_pair(gi, h)),
writable_vertex_scalar_properties(),
edge_scalar_properties())
(dist_map, weight);
}
void export_astar()
{
using namespace boost::python;
def("astar_search", &a_star_search);
}
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2007-2010 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "graph_filtering.hh"
#include "graph_python_interface.hh"
#include <boost/python.hpp>
#include "graph.hh"
#include "graph_selectors.hh"
#include "graph_util.hh"
namespace graph_tool
{
using namespace std;
using namespace boost;
// this is to avoid using GraphWrap as the underlying graph type
struct get_graph_t
{
template <class Graph>
struct apply
{
typedef Graph type;
};
template <class Graph>
struct apply<GraphWrap<Graph> >
{
typedef Graph type;
};
};
class AStarVisitorWrapper
{
public:
AStarVisitorWrapper(python::object& gi, python::object vis)
: _gi(gi), _vis(vis) {}
template <class Vertex, class Graph>
void initialize_vertex(Vertex u, Graph& g)
{
_vis.attr("initialize_vertex")(PythonVertex(_gi, u));
}
template <class Vertex, class Graph>
void discover_vertex(Vertex u, Graph& g)
{
_vis.attr("discover_vertex")(PythonVertex(_gi, u));
}
template <class Vertex, class Graph>
void examine_vertex(Vertex u, Graph& g)
{
_vis.attr("examine_vertex")(PythonVertex(_gi, u));
}
template <class Edge, class Graph>
void examine_edge(Edge e, Graph& g)
{
_vis.attr("examine_edge")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
}
template <class Edge, class Graph>
void edge_relaxed(Edge e, Graph& g)
{
_vis.attr("edge_relaxed")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
}
template <class Edge, class Graph>
void edge_not_relaxed(Edge e, Graph& g)
{
_vis.attr("edge_not_relaxed")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
}
template <class Edge, class Graph>
void black_target(Edge e, Graph& g)
{
_vis.attr("black_target")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
}
template <class Vertex, class Graph>
void finish_vertex(Vertex u, Graph& g)
{
_vis.attr("finish_vertex")(PythonVertex(_gi, u));
}
private:
python::object _gi, _vis;
};
class AStarCmp
{
public:
AStarCmp(python::object cmp): _cmp(cmp) {}
template <class Value1, class Value2>
bool operator()(const Value1& v1, const Value2& v2) const
{
return extract<bool>(_cmp(v1, v2));
}
private:
python::object _cmp;
};
class AStarCmb
{
public:
AStarCmb(python::object cmb): _cmb(cmb) {}
template <class Value1, class Value2 >
Value1 operator()(const Value1& v1, const Value2& v2) const
{
return python::extract<Value1>(_cmb(v1, v2));
}
private:
python::object _cmb;
};
template <class Value>
class AStarH
{
public:
AStarH(python::object gi, python::object h): _gi(gi), _h(h) {}
Value operator()(GraphInterface::vertex_t v) const
{
return python::extract<Value>(_h(PythonVertex(_gi, v)));
}
private:
python::object _gi, _h;
};
} // namespace graph_tool
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2007-2010 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "graph_filtering.hh"
#include "graph_python_interface.hh"
#include <boost/python.hpp>
#include <boost/graph/astar_search.hpp>
#include "graph.hh"
#include "graph_selectors.hh"
#include "graph_util.hh"
#include "graph_astar.hh"
using namespace std;
using namespace boost;
using namespace graph_tool;
struct do_astar_search
{
template <class Graph, class DistanceMap, class WeightMap>
void operator()(const Graph& g, size_t s, DistanceMap dist,
pair<boost::any, boost::any> pc, WeightMap weight,
AStarVisitorWrapper vis, pair<AStarCmp, AStarCmb> cmp,
pair<python::object, python::object> range,
pair<python::object, python::object> h) const
{
typedef typename property_traits<DistanceMap>::value_type dtype_t;
dtype_t z = python::extract<dtype_t>(range.first);
dtype_t i = python::extract<dtype_t>(range.second);
checked_vector_property_map<default_color_type,
typeof(get(vertex_index, g))>
color(get(vertex_index, g._g));
typedef typename property_map_type::
apply<int32_t, typeof(get(vertex_index, g))>::type pred_t;
astar_search_no_init(g, vertex(s, g),
AStarH<dtype_t>(h.first, h.second), vis,
any_cast<pred_t>(pc.first),
any_cast<DistanceMap>(pc.second), dist, weight,
color, get(vertex_index, g), cmp.first,
cmp.second, i, z);
}
};
void a_star_search_implicit(GraphInterface& g, python::object gi, size_t source,
boost::any dist_map, boost::any pred,
boost::any cost, boost::any weight,
python::object vis, python::object cmp,
python::object cmb, python::object zero,
python::object inf, python::object h)
{
run_action<graph_tool::detail::all_graph_views,mpl::true_>()
(g, bind<void>(do_astar_search(), _1, source, _2, make_pair(pred, cost),
_3,
AStarVisitorWrapper(gi, vis), make_pair(AStarCmp(cmp),
AStarCmb(cmb)),
make_pair(zero, inf), make_pair(gi, h)),
writable_vertex_scalar_properties(),
edge_scalar_properties())
(dist_map, weight);
}
void export_astar_implicit()
{
using namespace boost::python;
def("astar_search_implicit", &a_star_search_implicit);
}
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2007-2010 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "graph_filtering.hh"
#include "graph_python_interface.hh"
#include <boost/python.hpp>
#include <boost/graph/bellman_ford_shortest_paths.hpp>
#include "graph.hh"
#include "graph_selectors.hh"
#include "graph_util.hh"
using namespace std;
using namespace boost;
using namespace graph_tool;
class BFVisitorWrapper
{
public:
BFVisitorWrapper(python::object gi, python::object vis)
: _gi(gi), _vis(vis) {}
template <class Edge, class Graph>
void examine_edge(Edge e, Graph& g)
{
_vis.attr("examine_edge")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
}
template <class Edge, class Graph>
void edge_relaxed(Edge e, Graph& g)
{
_vis.attr("edge_relaxed")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
}
template <class Edge, class Graph>
void edge_not_relaxed(Edge e, Graph& g)
{
_vis.attr("edge_not_relaxed")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
}
template <class Edge, class Graph>
void edge_minimized(Edge e, Graph& g)
{
_vis.attr("edge_minimized")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
}
template <class Edge, class Graph>
void edge_not_minimized(Edge e, Graph& g)
{
_vis.attr("edge_not_minimized")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
}
private:
python::object _gi, _vis;
};
class BFCmp
{
public:
BFCmp(python::object cmp): _cmp(cmp) {}
template <class Value1, class Value2>
bool operator()(const Value1& v1, const Value2& v2) const
{
return extract<bool>(_cmp(v1, v2));
}
private:
python::object _cmp;
};
class BFCmb
{
public:
BFCmb(python::object cmb): _cmb(cmb) {}
template <class Value1, class Value2 >
Value1 operator()(const Value1& v1, const Value2& v2) const
{
return python::extract<Value1>(_cmb(v1, v2));
}
private:
python::object _cmb;
};
struct do_bf_search
{
template <class Graph, class DistanceMap, class WeightMap>
void operator()(const Graph& g, size_t s, DistanceMap dist,
boost::any pred_map, WeightMap weight, BFVisitorWrapper vis,
pair<BFCmp, BFCmb> cm,
pair<python::object, python::object> range, bool& ret) const
{
typedef typename property_traits<DistanceMap>::value_type dtype_t;
dtype_t z = python::extract<dtype_t>(range.first);
dtype_t i = python::extract<dtype_t>(range.second);
typedef typename property_map_type::
apply<int32_t, typeof(get(vertex_index, g))>::type pred_t;
pred_t pred = any_cast<pred_t>(pred_map);
ret = bellman_ford_shortest_paths
(g, HardNumVertices()(g),
root_vertex(vertex(s, g)).visitor(vis).weight_map(weight).
distance_map(dist).
predecessor_map(pred).
distance_compare(cm.first).
distance_combine(cm.second).distance_inf(i).
distance_zero(z));
}
};
bool bellman_ford_search(GraphInterface& g, python::object gi, size_t source,
boost::any dist_map, boost::any pred_map,
boost::any weight, python::object vis,
python::object cmp, python::object cmb,
python::object zero, python::object inf)
{
bool ret = false;
run_action<graph_tool::detail::all_graph_views,mpl::true_>()
(g, bind<void>(do_bf_search(), _1, source, _2, pred_map, _3,
BFVisitorWrapper(gi, vis),
make_pair(BFCmp(cmp), BFCmb(cmb)), make_pair(zero, inf),
ref(ret)),
writable_vertex_scalar_properties(),
edge_scalar_properties())
(dist_map, weight);
return ret;
}
void export_bellman_ford()
{
using namespace boost::python;
def("bellman_ford_search", &bellman_ford_search);
}
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2007-2010 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "graph_filtering.hh"
#include "graph_python_interface.hh"
#include <boost/python.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include "graph.hh"
#include "graph_selectors.hh"
#include "graph_util.hh"
using namespace std;
using namespace boost;
using namespace graph_tool;
class BFSVisitorWrapper
{
public:
BFSVisitorWrapper(python::object gi, python::object vis)
: _gi(gi), _vis(vis) {}
template <class Vertex, class Graph>
void initialize_vertex(Vertex u, Graph& g)
{
_vis.attr("initialize_vertex")(PythonVertex(_gi, u));
}
template <class Vertex, class Graph>
void discover_vertex(Vertex u, Graph& g)
{
_vis.attr("discover_vertex")(PythonVertex(_gi, u));
}
template <class Vertex, class Graph>
void examine_vertex(Vertex u, Graph& g)
{
_vis.attr("examine_vertex")(PythonVertex(_gi, u));
}
template <class Edge, class Graph>
void examine_edge(Edge e, Graph& g)
{
_vis.attr("examine_edge")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
}
template <class Edge, class Graph>
void tree_edge(Edge e, Graph& g)
{
_vis.attr("tree_edge")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
}
template <class Edge, class Graph>
void non_tree_edge(Edge e, Graph& g)
{
_vis.attr("non_tree_edge")
(PythonEdge<typename Graph::orig_graph_t>(_gi, e));
}
template <class Edge, class Graph>
void gray_target(Edge e, Graph& g)
{
_vis.attr("gray_target")