Skip to content

Commit

Permalink
Merge pull request #27 from levinkov/master
Browse files Browse the repository at this point in the history
adding command line tools for lifting MP and solving LMP
  • Loading branch information
bjoern-andres committed Feb 12, 2016
2 parents 26ec62c + 384024a commit a7d458c
Show file tree
Hide file tree
Showing 12 changed files with 872 additions and 212 deletions.
24 changes: 23 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
cmake_minimum_required(VERSION 2.6)

set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)

project(graph)

include_directories(include)

file(GLOB headers
include/andres/*.hxx
include/andres/ilp/*.hxx
Expand Down Expand Up @@ -134,7 +138,6 @@ endif()

if((COMPILER_SUPPORTS_CXX0X OR COMPILER_SUPPORTS_CXX11) AND GUROBI_FOUND AND HDF5_FOUND)
include_directories(src)
include_directories(src/command-line-tools)

add_executable(solve-mp src/command-line-tools/solve-mp.cxx ${headers})
target_link_libraries(solve-mp ${HDF5_LIBRARIES} ${GUROBI_LIBRARIES})
Expand All @@ -144,4 +147,23 @@ if((COMPILER_SUPPORTS_CXX0X OR COMPILER_SUPPORTS_CXX11) AND GUROBI_FOUND AND HDF

add_executable(solve-mp-grid-graph src/command-line-tools/solve-mp-grid-graph.cxx ${headers})
target_link_libraries(solve-mp-grid-graph ${HDF5_LIBRARIES} ${GUROBI_LIBRARIES})
endif()

if((COMPILER_SUPPORTS_CXX0X OR COMPILER_SUPPORTS_CXX11) AND HDF5_FOUND)
include_directories(src)

add_executable(test-probabilistic-lifting src/command-line-tools/test-probabilistic-lifting.cxx ${headers})
add_test(test-probabilistic-lifting test-probabilistic-lifting)

add_executable(lift-mp src/command-line-tools/lift-mp.cxx ${headers})
target_link_libraries(lift-mp ${HDF5_LIBRARIES})

add_executable(lift-mp-grid-graph src/command-line-tools/lift-mp-grid-graph.cxx ${headers})
target_link_libraries(lift-mp-grid-graph ${HDF5_LIBRARIES})

add_executable(solve-lmp src/command-line-tools/solve-lmp.cxx ${headers})
target_link_libraries(solve-lmp ${HDF5_LIBRARIES} ${GUROBI_LIBRARIES})

add_executable(solve-lmp-grid-graph src/command-line-tools/solve-lmp-grid-graph.cxx ${headers})
target_link_libraries(solve-lmp-grid-graph ${HDF5_LIBRARIES} ${GUROBI_LIBRARIES})
endif()
30 changes: 30 additions & 0 deletions include/andres/functional.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,36 @@ private:
const argument_type oneMinusEpsilon_;
};

template<typename T, typename U>
struct NegativeLogProbabilityToInverseProbability {
typedef T argument_type;
typedef U result_type;

result_type operator()(argument_type x) const {
return 1-::exp(-x );
}
};

template<typename T, typename U>
struct ProbabilityToNegativeLogInverseProbability {
typedef T argument_type;
typedef U result_type;

result_type operator()(argument_type x) const {
return -::log( 1-x );
}
};

template<typename T, typename U>
struct ProbabilityToLogit {
typedef T argument_type;
typedef U result_type;

result_type operator()(argument_type x) const {
return ::log( (1-x)/x );
}
};

} // namespace andres

#endif // #ifndef ANDRES_FUNCTIONAL_HXX
127 changes: 1 addition & 126 deletions include/andres/graph/lifting.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@

#include "grid-graph.hxx"
#include "bfs.hxx"
#include "shortest-paths.hxx"
#include "fast-marching.hxx"


namespace andres {
namespace graph {
Expand Down Expand Up @@ -224,130 +223,6 @@ lift(
}
}
}
}
/// Lift edge values from a source graph to a target graph.
template<class SOURCE_GRAPH, class TARGET_GRAPH, class SOURCE_EDGE_VALUE_ITERATOR, class TARGET_EDGE_VALUE_ITERATOR>
void
liftEdgeValues(
const SOURCE_GRAPH& sourceGraph,
const TARGET_GRAPH& targetGraph,
const SOURCE_EDGE_VALUE_ITERATOR sit,
TARGET_EDGE_VALUE_ITERATOR tit
) {
typedef std::size_t size_type;
typedef typename std::iterator_traits<SOURCE_EDGE_VALUE_ITERATOR>::value_type value_type;

if(sourceGraph.numberOfVertices() != targetGraph.numberOfVertices())
throw std::runtime_error("number of vertices mismatch between source and target graph.");

class SSSPVisitor
{
public:
SSSPVisitor(std::vector<char>& target_vertices, std::size_t number_of_target_vertices) :
target_vertices_(target_vertices), vertices_left_(number_of_target_vertices)
{ }

bool operator()(typename std::vector<value_type>::iterator distances, typename std::vector<size_type>::iterator parents, std::size_t v)
{
if (target_vertices_[v])
{
target_vertices_[v] = 0;
--vertices_left_;
}

return vertices_left_;
}

private:
std::vector<char>& target_vertices_;
std::size_t vertices_left_ { 0 };
};

std::vector<value_type> distances(sourceGraph.numberOfVertices());
std::vector<size_type> parents(sourceGraph.numberOfVertices());
std::vector<char> target_vertices(sourceGraph.numberOfVertices());
std::vector<std::size_t> target_vertices_edges(sourceGraph.numberOfVertices());

#pragma omp parallel for firstprivate(distances, parents, target_vertices, target_vertices_edges)
for(long int i = 0; i < targetGraph.numberOfVertices(); ++i)
{
std::fill(target_vertices.begin(), target_vertices.end(), char());

for (auto it = targetGraph.adjacenciesFromVertexBegin(i); it != targetGraph.adjacenciesFromVertexEnd(i); ++it)
{
target_vertices[it->vertex()] = 1;
target_vertices_edges[it->vertex()] = it->edge();
}

SSSPVisitor visitor(target_vertices, targetGraph.numberOfEdgesFromVertex(i));

sssp(
sourceGraph,
DefaultSubgraphMask<>(),
i,
sit,
distances.begin(), // buffer
parents.begin(), // buffer
visitor
);

#pragma omp critical
{
for (auto it = targetGraph.adjacenciesFromVertexBegin(i); it != targetGraph.adjacenciesFromVertexEnd(i); ++it)
tit[it->edge()] = distances[it->vertex()];
}
}

// restore original edge weights
for (std::size_t e = 0; e < sourceGraph.numberOfEdges(); ++e)
{
auto v0 = sourceGraph.vertexOfEdge(e, 0);
auto v1 = sourceGraph.vertexOfEdge(e, 1);

tit[targetGraph.findEdge(v0, v1).second] = sit[e];
}
}

/// Lift edge values from a 2-dimensional grid graph to a target graph.
template<class SOURCE_GRAPH_VISITOR, class TARGET_GRAPH, class SOURCE_EDGE_VALUE_ITERATOR, class TARGET_EDGE_VALUE_ITERATOR>
void
liftEdgeValues(
const GridGraph<2, SOURCE_GRAPH_VISITOR>& sourceGraph,
const TARGET_GRAPH& targetGraph,
SOURCE_EDGE_VALUE_ITERATOR sit,
TARGET_EDGE_VALUE_ITERATOR tit,
const std::size_t interpolationOrder = 0
) {
typedef std::size_t size_type;
typedef typename std::iterator_traits<TARGET_EDGE_VALUE_ITERATOR>::value_type target_value_type;

if(sourceGraph.numberOfVertices() != targetGraph.numberOfVertices()) {
throw std::runtime_error("number of vertices mismatch between source and target graph.");
}

std::size_t cnt = 0;
FastMarchingBuffers<target_value_type, size_type> buffers(sourceGraph.numberOfVertices());

#pragma omp parallel for firstprivate(buffers)
for(size_type v = 0; v < targetGraph.numberOfVertices(); ++v)
fastMarching(
sourceGraph,
sit,
v,
targetGraph,
tit,
interpolationOrder,
buffers
);

// restore original edge weights
for (std::size_t e = 0; e < sourceGraph.numberOfEdges(); ++e)
{
auto v0 = sourceGraph.vertexOfEdge(e, 0);
auto v1 = sourceGraph.vertexOfEdge(e, 1);

tit[targetGraph.findEdge(v0, v1).second] = sit[e];
}
}

} // namespace graph
Expand Down
80 changes: 1 addition & 79 deletions src/andres/graph/unit-test/lifting.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "andres/graph/graph.hxx"
#include "andres/graph/lifting.hxx"


inline void test(const bool condition) {
if(!condition) throw std::logic_error("test failed.");
}
Expand Down Expand Up @@ -123,89 +124,10 @@ void testLiftGridGraphL2Metric() {
}
}

void testLiftEdgeValuesSPSP() {
typedef std::size_t size_type;

// build cycle
const size_type numberOfVertices = 10;
andres::graph::Graph<> graph;
graph.insertVertices(numberOfVertices);
for(size_type v = 0; v < graph.numberOfVertices(); ++v)
{
const int w = (v + 1) % graph.numberOfVertices();
graph.insertEdge(v, w);
}

// define (two unit) edge values
std::vector<unsigned int> edgeValues(graph.numberOfEdges(), 2);

// lift graph
const size_type distanceUpperBound = 4;
andres::graph::Graph<> graphLifted;
andres::graph::lift(graph, graphLifted, distanceUpperBound);

// lift edge weights (by means of SPSP)
std::vector<unsigned int> edgeValuesLifted(graphLifted.numberOfEdges());
andres::graph::liftEdgeValues(graph, graphLifted, edgeValues.begin(), edgeValuesLifted.begin());

// test lifted edge values
for(size_type e = 0; e < graphLifted.numberOfEdges(); ++e)
{
const size_type v = graphLifted.vertexOfEdge(e, 0);
const size_type w = graphLifted.vertexOfEdge(e, 1);
const size_type distance = diff(v, w, graph.numberOfVertices());
test(edgeValuesLifted[e] == distance * 2);
}
}

void testLiftEdgeValuesFastMarching() {
typedef std::size_t size_type;
typedef andres::graph::GridGraph<2> GraphType;
typedef GraphType::VertexCoordinate VertexCoordinate;
typedef andres::graph::Graph<> LiftedGraphType;

// build grid graph
GraphType graph = {5, 4};

// define (two unit) edge values
std::vector<unsigned int> edgeValues(graph.numberOfEdges(), 2);

// lift graph
const size_type distanceUpperBound = 4;
LiftedGraphType graphLifted;
andres::graph::lift(graph, graphLifted, distanceUpperBound);

// lift edge values (by menas of fast marching)
const size_type interpolationOrder = 0;
std::vector<unsigned int> edgeValuesLiftedFM(graphLifted.numberOfEdges());
andres::graph::liftEdgeValues(graph, graphLifted, edgeValues.begin(), edgeValuesLiftedFM.begin(), interpolationOrder);

// lift edge values (by menas of SPSP)
std::vector<unsigned int> edgeValuesLiftedSPSP(graphLifted.numberOfEdges());
andres::graph::liftEdgeValues<
GraphType,
LiftedGraphType,
std::vector<unsigned int>::const_iterator,
std::vector<unsigned int>::iterator
>(
graph,
graphLifted,
edgeValues.begin(),
edgeValuesLiftedSPSP.begin()
);

// test lifted edge values
VertexCoordinate cv, cw;
for(size_type e = 0; e < graphLifted.numberOfEdges(); ++e)
test(edgeValuesLiftedFM[e] == edgeValuesLiftedSPSP[e]);
}

int main() {
testLiftGraph();
testLiftGridGraphPathLengthMetric();
testLiftGridGraphL2Metric();
testLiftEdgeValuesSPSP();
testLiftEdgeValuesFastMarching();

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@
#include <vector>
#include <type_traits>

#include "grid-graph.hxx"
#include <andres/graph/grid-graph.hxx>

namespace andres {
namespace graph {

/// \cond SUPPRESS DOXYGEN
namespace detail {
Expand Down Expand Up @@ -270,7 +268,4 @@ fastMarching(
}
}

} // namespace graph
} // namespace andres

#endif // #ifndef ANDRES_GRAPH_FAST_MARCHING_HXX
Loading

0 comments on commit a7d458c

Please sign in to comment.