Add Chromium-only Blender WebEngine parity work
This commit is contained in:
161
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/CMakeLists.txt
vendored
Normal file
161
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
INCLUDE_DIRECTORIES(
|
||||
${PROJECT_SOURCE_DIR}
|
||||
${PROJECT_BINARY_DIR}
|
||||
)
|
||||
|
||||
LINK_DIRECTORIES(
|
||||
${PROJECT_BINARY_DIR}/lemon
|
||||
)
|
||||
|
||||
SET(TEST_WITH_VALGRIND "NO" CACHE STRING
|
||||
"Run the test with valgrind (YES/NO).")
|
||||
SET(VALGRIND_FLAGS "" CACHE STRING "Valgrind flags used by the tests.")
|
||||
|
||||
SET(TESTS
|
||||
adaptors_test
|
||||
arc_look_up_test
|
||||
bellman_ford_test
|
||||
bfs_test
|
||||
bpgraph_test
|
||||
circulation_test
|
||||
connectivity_test
|
||||
counter_test
|
||||
dfs_test
|
||||
digraph_test
|
||||
dijkstra_test
|
||||
dim_test
|
||||
edge_set_test
|
||||
error_test
|
||||
euler_test
|
||||
fractional_matching_test
|
||||
gomory_hu_test
|
||||
graph_copy_test
|
||||
graph_test
|
||||
graph_utils_test
|
||||
hao_orlin_test
|
||||
heap_test
|
||||
kruskal_test
|
||||
lgf_reader_writer_test
|
||||
lgf_test
|
||||
maps_test
|
||||
matching_test
|
||||
max_cardinality_search_test
|
||||
max_clique_test
|
||||
max_flow_test
|
||||
min_cost_arborescence_test
|
||||
min_cost_flow_test
|
||||
min_mean_cycle_test
|
||||
nagamochi_ibaraki_test
|
||||
path_test
|
||||
planarity_test
|
||||
radix_sort_test
|
||||
random_test
|
||||
suurballe_test
|
||||
time_measure_test
|
||||
tsp_test
|
||||
unionfind_test
|
||||
)
|
||||
|
||||
IF(LEMON_HAVE_LP)
|
||||
IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
|
||||
ADD_EXECUTABLE(lp_test lp_test.cc)
|
||||
ELSE()
|
||||
ADD_EXECUTABLE(lp_test EXCLUDE_FROM_ALL lp_test.cc)
|
||||
ENDIF()
|
||||
|
||||
SET(LP_TEST_LIBS lemon)
|
||||
|
||||
IF(LEMON_HAVE_GLPK)
|
||||
SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES})
|
||||
ENDIF()
|
||||
IF(LEMON_HAVE_CPLEX)
|
||||
SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${ILOG_LIBRARIES})
|
||||
ENDIF()
|
||||
IF(LEMON_HAVE_CLP)
|
||||
SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
|
||||
ENDIF()
|
||||
IF(LEMON_HAVE_SOPLEX)
|
||||
SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${SOPLEX_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS})
|
||||
ADD_TEST(lp_test lp_test)
|
||||
ADD_DEPENDENCIES(check lp_test)
|
||||
|
||||
IF(WIN32 AND LEMON_HAVE_GLPK)
|
||||
GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
|
||||
GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
|
||||
ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
IF(WIN32 AND LEMON_HAVE_CPLEX)
|
||||
GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
|
||||
GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
|
||||
ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${ILOG_CPLEX_DLL} ${TARGET_PATH}
|
||||
)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF(LEMON_HAVE_MIP)
|
||||
IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
|
||||
ADD_EXECUTABLE(mip_test mip_test.cc)
|
||||
ELSE()
|
||||
ADD_EXECUTABLE(mip_test EXCLUDE_FROM_ALL mip_test.cc)
|
||||
ENDIF()
|
||||
|
||||
SET(MIP_TEST_LIBS lemon)
|
||||
|
||||
IF(LEMON_HAVE_GLPK)
|
||||
SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${GLPK_LIBRARIES})
|
||||
ENDIF()
|
||||
IF(LEMON_HAVE_CPLEX)
|
||||
SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${ILOG_LIBRARIES})
|
||||
ENDIF()
|
||||
IF(LEMON_HAVE_CBC)
|
||||
SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${COIN_CBC_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
TARGET_LINK_LIBRARIES(mip_test ${MIP_TEST_LIBS})
|
||||
ADD_TEST(mip_test mip_test)
|
||||
ADD_DEPENDENCIES(check mip_test)
|
||||
|
||||
IF(WIN32 AND LEMON_HAVE_GLPK)
|
||||
GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
|
||||
GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
|
||||
ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
IF(WIN32 AND LEMON_HAVE_CPLEX)
|
||||
GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
|
||||
GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
|
||||
ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${ILOG_CPLEX_DLL} ${TARGET_PATH}
|
||||
)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
FOREACH(TEST_NAME ${TESTS})
|
||||
IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
|
||||
ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
|
||||
ELSE()
|
||||
ADD_EXECUTABLE(${TEST_NAME} EXCLUDE_FROM_ALL ${TEST_NAME}.cc)
|
||||
ENDIF()
|
||||
TARGET_LINK_LIBRARIES(${TEST_NAME} lemon)
|
||||
IF(TEST_WITH_VALGRIND)
|
||||
ADD_TEST(${TEST_NAME}
|
||||
valgrind --error-exitcode=1 ${VALGRIND_FLAGS}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME} )
|
||||
ELSE()
|
||||
ADD_TEST(${TEST_NAME} ${TEST_NAME})
|
||||
ENDIF()
|
||||
ADD_DEPENDENCIES(check ${TEST_NAME})
|
||||
ENDFOREACH()
|
||||
1468
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/adaptors_test.cc
vendored
Normal file
1468
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/adaptors_test.cc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
84
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/arc_look_up_test.cc
vendored
Normal file
84
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/arc_look_up_test.cc
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "lemon/list_graph.h"
|
||||
#include "lemon/lgf_reader.h"
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
const std::string lgf =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"6\n"
|
||||
"@arcs\n"
|
||||
"label\n"
|
||||
"5 6 0\n"
|
||||
"5 4 1\n"
|
||||
"4 6 2\n"
|
||||
"3 4 3\n"
|
||||
"3 4 4\n"
|
||||
"3 2 5\n"
|
||||
"3 5 6\n"
|
||||
"3 5 7\n"
|
||||
"3 5 8\n"
|
||||
"3 5 9\n"
|
||||
"2 4 10\n"
|
||||
"2 4 11\n"
|
||||
"2 4 12\n"
|
||||
"2 4 13\n"
|
||||
"1 2 14\n"
|
||||
"1 2 15\n"
|
||||
"1 0 16\n"
|
||||
"1 3 17\n"
|
||||
"1 3 18\n"
|
||||
"1 3 19\n"
|
||||
"1 3 20\n"
|
||||
"0 2 21\n"
|
||||
"0 2 22\n"
|
||||
"0 2 23\n"
|
||||
"0 2 24\n";
|
||||
|
||||
|
||||
int main() {
|
||||
ListDigraph graph;
|
||||
std::istringstream lgfs(lgf);
|
||||
DigraphReader<ListDigraph>(graph, lgfs).run();
|
||||
|
||||
AllArcLookUp<ListDigraph> lookup(graph);
|
||||
|
||||
int numArcs = countArcs(graph);
|
||||
|
||||
int arcCnt = 0;
|
||||
for(ListDigraph::NodeIt n1(graph); n1 != INVALID; ++n1)
|
||||
for(ListDigraph::NodeIt n2(graph); n2 != INVALID; ++n2)
|
||||
for(ListDigraph::Arc a = lookup(n1, n2); a != INVALID;
|
||||
a = lookup(n1, n2, a))
|
||||
++arcCnt;
|
||||
check(arcCnt==numArcs, "Wrong total number of arcs");
|
||||
|
||||
return 0;
|
||||
}
|
||||
289
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/bellman_ford_test.cc
vendored
Normal file
289
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/bellman_ford_test.cc
vendored
Normal file
@@ -0,0 +1,289 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/concepts/digraph.h>
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/list_graph.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/bellman_ford.h>
|
||||
#include <lemon/path.h>
|
||||
|
||||
#include "graph_test.h"
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
char test_lgf[] =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"@arcs\n"
|
||||
" length\n"
|
||||
"0 1 3\n"
|
||||
"1 2 -3\n"
|
||||
"1 2 -5\n"
|
||||
"1 3 -2\n"
|
||||
"0 2 -1\n"
|
||||
"1 2 -4\n"
|
||||
"0 3 2\n"
|
||||
"4 2 -5\n"
|
||||
"2 3 1\n"
|
||||
"@attributes\n"
|
||||
"source 0\n"
|
||||
"target 3\n";
|
||||
|
||||
|
||||
void checkBellmanFordCompile()
|
||||
{
|
||||
typedef int Value;
|
||||
typedef concepts::Digraph Digraph;
|
||||
typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
|
||||
typedef BellmanFord<Digraph, LengthMap> BF;
|
||||
typedef Digraph::Node Node;
|
||||
typedef Digraph::Arc Arc;
|
||||
|
||||
Digraph gr;
|
||||
Node s, t, n;
|
||||
Arc e;
|
||||
Value l;
|
||||
::lemon::ignore_unused_variable_warning(l);
|
||||
int k=3;
|
||||
bool b;
|
||||
::lemon::ignore_unused_variable_warning(b);
|
||||
BF::DistMap d(gr);
|
||||
BF::PredMap p(gr);
|
||||
LengthMap length;
|
||||
concepts::Path<Digraph> pp;
|
||||
|
||||
{
|
||||
BF bf_test(gr,length);
|
||||
const BF& const_bf_test = bf_test;
|
||||
|
||||
bf_test.run(s);
|
||||
bf_test.run(s,k);
|
||||
|
||||
bf_test.init();
|
||||
bf_test.addSource(s);
|
||||
bf_test.addSource(s, 1);
|
||||
b = bf_test.processNextRound();
|
||||
b = bf_test.processNextWeakRound();
|
||||
|
||||
bf_test.start();
|
||||
bf_test.checkedStart();
|
||||
bf_test.limitedStart(k);
|
||||
|
||||
l = const_bf_test.dist(t);
|
||||
e = const_bf_test.predArc(t);
|
||||
s = const_bf_test.predNode(t);
|
||||
b = const_bf_test.reached(t);
|
||||
d = const_bf_test.distMap();
|
||||
p = const_bf_test.predMap();
|
||||
pp = const_bf_test.path(t);
|
||||
pp = const_bf_test.negativeCycle();
|
||||
|
||||
for (BF::ActiveIt it(const_bf_test); it != INVALID; ++it) {}
|
||||
}
|
||||
{
|
||||
BF::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
|
||||
::SetDistMap<concepts::ReadWriteMap<Node,Value> >
|
||||
::SetOperationTraits<BellmanFordDefaultOperationTraits<Value> >
|
||||
::Create bf_test(gr,length);
|
||||
|
||||
LengthMap length_map;
|
||||
concepts::ReadWriteMap<Node,Arc> pred_map;
|
||||
concepts::ReadWriteMap<Node,Value> dist_map;
|
||||
|
||||
bf_test
|
||||
.lengthMap(length_map)
|
||||
.predMap(pred_map)
|
||||
.distMap(dist_map);
|
||||
|
||||
bf_test.run(s);
|
||||
bf_test.run(s,k);
|
||||
|
||||
bf_test.init();
|
||||
bf_test.addSource(s);
|
||||
bf_test.addSource(s, 1);
|
||||
b = bf_test.processNextRound();
|
||||
b = bf_test.processNextWeakRound();
|
||||
|
||||
bf_test.start();
|
||||
bf_test.checkedStart();
|
||||
bf_test.limitedStart(k);
|
||||
|
||||
l = bf_test.dist(t);
|
||||
e = bf_test.predArc(t);
|
||||
s = bf_test.predNode(t);
|
||||
b = bf_test.reached(t);
|
||||
pp = bf_test.path(t);
|
||||
pp = bf_test.negativeCycle();
|
||||
}
|
||||
}
|
||||
|
||||
void checkBellmanFordFunctionCompile()
|
||||
{
|
||||
typedef int Value;
|
||||
typedef concepts::Digraph Digraph;
|
||||
typedef Digraph::Arc Arc;
|
||||
typedef Digraph::Node Node;
|
||||
typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
|
||||
|
||||
Digraph g;
|
||||
bool b;
|
||||
::lemon::ignore_unused_variable_warning(b);
|
||||
|
||||
bellmanFord(g,LengthMap()).run(Node());
|
||||
b = bellmanFord(g,LengthMap()).run(Node(),Node());
|
||||
bellmanFord(g,LengthMap())
|
||||
.predMap(concepts::ReadWriteMap<Node,Arc>())
|
||||
.distMap(concepts::ReadWriteMap<Node,Value>())
|
||||
.run(Node());
|
||||
b=bellmanFord(g,LengthMap())
|
||||
.predMap(concepts::ReadWriteMap<Node,Arc>())
|
||||
.distMap(concepts::ReadWriteMap<Node,Value>())
|
||||
.path(concepts::Path<Digraph>())
|
||||
.dist(Value())
|
||||
.run(Node(),Node());
|
||||
}
|
||||
|
||||
|
||||
template <typename Digraph, typename Value>
|
||||
void checkBellmanFord() {
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
typedef typename Digraph::template ArcMap<Value> LengthMap;
|
||||
|
||||
Digraph gr;
|
||||
Node s, t;
|
||||
LengthMap length(gr);
|
||||
|
||||
std::istringstream input(test_lgf);
|
||||
digraphReader(gr, input).
|
||||
arcMap("length", length).
|
||||
node("source", s).
|
||||
node("target", t).
|
||||
run();
|
||||
|
||||
BellmanFord<Digraph, LengthMap>
|
||||
bf(gr, length);
|
||||
bf.run(s);
|
||||
Path<Digraph> p = bf.path(t);
|
||||
|
||||
check(bf.reached(t) && bf.dist(t) == -1, "Bellman-Ford found a wrong path.");
|
||||
check(p.length() == 3, "path() found a wrong path.");
|
||||
check(checkPath(gr, p), "path() found a wrong path.");
|
||||
check(pathSource(gr, p) == s, "path() found a wrong path.");
|
||||
check(pathTarget(gr, p) == t, "path() found a wrong path.");
|
||||
|
||||
ListPath<Digraph> path;
|
||||
Value dist = 0;
|
||||
bool reached = bellmanFord(gr,length).path(path).dist(dist).run(s,t);
|
||||
|
||||
check(reached && dist == -1, "Bellman-Ford found a wrong path.");
|
||||
check(path.length() == 3, "path() found a wrong path.");
|
||||
check(checkPath(gr, path), "path() found a wrong path.");
|
||||
check(pathSource(gr, path) == s, "path() found a wrong path.");
|
||||
check(pathTarget(gr, path) == t, "path() found a wrong path.");
|
||||
|
||||
for(ArcIt e(gr); e!=INVALID; ++e) {
|
||||
Node u=gr.source(e);
|
||||
Node v=gr.target(e);
|
||||
check(!bf.reached(u) || (bf.dist(v) - bf.dist(u) <= length[e]),
|
||||
"Wrong output. dist(target)-dist(source)-arc_length=" <<
|
||||
bf.dist(v) - bf.dist(u) - length[e]);
|
||||
}
|
||||
|
||||
for(NodeIt v(gr); v!=INVALID; ++v) {
|
||||
if (bf.reached(v)) {
|
||||
check(v==s || bf.predArc(v)!=INVALID, "Wrong tree.");
|
||||
if (bf.predArc(v)!=INVALID ) {
|
||||
Arc e=bf.predArc(v);
|
||||
Node u=gr.source(e);
|
||||
check(u==bf.predNode(v),"Wrong tree.");
|
||||
check(bf.dist(v) - bf.dist(u) == length[e],
|
||||
"Wrong distance! Difference: " <<
|
||||
bf.dist(v) - bf.dist(u) - length[e]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void checkBellmanFordNegativeCycle() {
|
||||
DIGRAPH_TYPEDEFS(SmartDigraph);
|
||||
|
||||
SmartDigraph gr;
|
||||
IntArcMap length(gr);
|
||||
|
||||
Node n1 = gr.addNode();
|
||||
Node n2 = gr.addNode();
|
||||
Node n3 = gr.addNode();
|
||||
Node n4 = gr.addNode();
|
||||
|
||||
Arc a1 = gr.addArc(n1, n2);
|
||||
Arc a2 = gr.addArc(n2, n2);
|
||||
|
||||
length[a1] = 2;
|
||||
length[a2] = -1;
|
||||
|
||||
{
|
||||
BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
|
||||
bf.run(n1);
|
||||
StaticPath<SmartDigraph> p = bf.negativeCycle();
|
||||
check(p.length() == 1 && p.front() == p.back() && p.front() == a2,
|
||||
"Wrong negative cycle.");
|
||||
}
|
||||
|
||||
length[a2] = 0;
|
||||
|
||||
{
|
||||
BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
|
||||
bf.run(n1);
|
||||
check(bf.negativeCycle().empty(),
|
||||
"Negative cycle should not be found.");
|
||||
}
|
||||
|
||||
length[gr.addArc(n1, n3)] = 5;
|
||||
length[gr.addArc(n4, n3)] = 1;
|
||||
length[gr.addArc(n2, n4)] = 2;
|
||||
length[gr.addArc(n3, n2)] = -4;
|
||||
|
||||
{
|
||||
BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
|
||||
bf.init();
|
||||
bf.addSource(n1);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
check(bf.negativeCycle().empty(),
|
||||
"Negative cycle should not be found.");
|
||||
bf.processNextRound();
|
||||
}
|
||||
StaticPath<SmartDigraph> p = bf.negativeCycle();
|
||||
check(p.length() == 3, "Wrong negative cycle.");
|
||||
check(length[p.nth(0)] + length[p.nth(1)] + length[p.nth(2)] == -1,
|
||||
"Wrong negative cycle.");
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
checkBellmanFord<ListDigraph, int>();
|
||||
checkBellmanFord<SmartDigraph, double>();
|
||||
checkBellmanFordNegativeCycle();
|
||||
return 0;
|
||||
}
|
||||
239
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/bfs_test.cc
vendored
Normal file
239
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/bfs_test.cc
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/concepts/digraph.h>
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/list_graph.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/bfs.h>
|
||||
#include <lemon/path.h>
|
||||
|
||||
#include "graph_test.h"
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
char test_lgf[] =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"@arcs\n"
|
||||
" label\n"
|
||||
"0 1 0\n"
|
||||
"1 2 1\n"
|
||||
"2 3 2\n"
|
||||
"3 4 3\n"
|
||||
"0 3 4\n"
|
||||
"0 3 5\n"
|
||||
"5 2 6\n"
|
||||
"@attributes\n"
|
||||
"source 0\n"
|
||||
"target 4\n";
|
||||
|
||||
void checkBfsCompile()
|
||||
{
|
||||
typedef concepts::Digraph Digraph;
|
||||
typedef Bfs<Digraph> BType;
|
||||
typedef Digraph::Node Node;
|
||||
typedef Digraph::Arc Arc;
|
||||
|
||||
Digraph G;
|
||||
Node s, t, n;
|
||||
Arc e;
|
||||
int l, i;
|
||||
::lemon::ignore_unused_variable_warning(l,i);
|
||||
bool b;
|
||||
BType::DistMap d(G);
|
||||
BType::PredMap p(G);
|
||||
Path<Digraph> pp;
|
||||
concepts::ReadMap<Node,bool> nm;
|
||||
|
||||
{
|
||||
BType bfs_test(G);
|
||||
const BType& const_bfs_test = bfs_test;
|
||||
|
||||
bfs_test.run(s);
|
||||
bfs_test.run(s,t);
|
||||
bfs_test.run();
|
||||
|
||||
bfs_test.init();
|
||||
bfs_test.addSource(s);
|
||||
n = bfs_test.processNextNode();
|
||||
n = bfs_test.processNextNode(t, b);
|
||||
n = bfs_test.processNextNode(nm, n);
|
||||
n = const_bfs_test.nextNode();
|
||||
b = const_bfs_test.emptyQueue();
|
||||
i = const_bfs_test.queueSize();
|
||||
|
||||
bfs_test.start();
|
||||
bfs_test.start(t);
|
||||
bfs_test.start(nm);
|
||||
|
||||
l = const_bfs_test.dist(t);
|
||||
e = const_bfs_test.predArc(t);
|
||||
s = const_bfs_test.predNode(t);
|
||||
b = const_bfs_test.reached(t);
|
||||
d = const_bfs_test.distMap();
|
||||
p = const_bfs_test.predMap();
|
||||
pp = const_bfs_test.path(t);
|
||||
}
|
||||
{
|
||||
BType
|
||||
::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
|
||||
::SetDistMap<concepts::ReadWriteMap<Node,int> >
|
||||
::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
|
||||
::SetStandardProcessedMap
|
||||
::SetProcessedMap<concepts::WriteMap<Node,bool> >
|
||||
::Create bfs_test(G);
|
||||
|
||||
concepts::ReadWriteMap<Node,Arc> pred_map;
|
||||
concepts::ReadWriteMap<Node,int> dist_map;
|
||||
concepts::ReadWriteMap<Node,bool> reached_map;
|
||||
concepts::WriteMap<Node,bool> processed_map;
|
||||
|
||||
bfs_test
|
||||
.predMap(pred_map)
|
||||
.distMap(dist_map)
|
||||
.reachedMap(reached_map)
|
||||
.processedMap(processed_map);
|
||||
|
||||
bfs_test.run(s);
|
||||
bfs_test.run(s,t);
|
||||
bfs_test.run();
|
||||
|
||||
bfs_test.init();
|
||||
bfs_test.addSource(s);
|
||||
n = bfs_test.processNextNode();
|
||||
n = bfs_test.processNextNode(t, b);
|
||||
n = bfs_test.processNextNode(nm, n);
|
||||
n = bfs_test.nextNode();
|
||||
b = bfs_test.emptyQueue();
|
||||
i = bfs_test.queueSize();
|
||||
|
||||
bfs_test.start();
|
||||
bfs_test.start(t);
|
||||
bfs_test.start(nm);
|
||||
|
||||
l = bfs_test.dist(t);
|
||||
e = bfs_test.predArc(t);
|
||||
s = bfs_test.predNode(t);
|
||||
b = bfs_test.reached(t);
|
||||
pp = bfs_test.path(t);
|
||||
}
|
||||
}
|
||||
|
||||
void checkBfsFunctionCompile()
|
||||
{
|
||||
typedef int VType;
|
||||
typedef concepts::Digraph Digraph;
|
||||
typedef Digraph::Arc Arc;
|
||||
typedef Digraph::Node Node;
|
||||
|
||||
Digraph g;
|
||||
bool b;
|
||||
::lemon::ignore_unused_variable_warning(b);
|
||||
|
||||
bfs(g).run(Node());
|
||||
b=bfs(g).run(Node(),Node());
|
||||
bfs(g).run();
|
||||
bfs(g)
|
||||
.predMap(concepts::ReadWriteMap<Node,Arc>())
|
||||
.distMap(concepts::ReadWriteMap<Node,VType>())
|
||||
.reachedMap(concepts::ReadWriteMap<Node,bool>())
|
||||
.processedMap(concepts::WriteMap<Node,bool>())
|
||||
.run(Node());
|
||||
b=bfs(g)
|
||||
.predMap(concepts::ReadWriteMap<Node,Arc>())
|
||||
.distMap(concepts::ReadWriteMap<Node,VType>())
|
||||
.reachedMap(concepts::ReadWriteMap<Node,bool>())
|
||||
.processedMap(concepts::WriteMap<Node,bool>())
|
||||
.path(concepts::Path<Digraph>())
|
||||
.dist(VType())
|
||||
.run(Node(),Node());
|
||||
bfs(g)
|
||||
.predMap(concepts::ReadWriteMap<Node,Arc>())
|
||||
.distMap(concepts::ReadWriteMap<Node,VType>())
|
||||
.reachedMap(concepts::ReadWriteMap<Node,bool>())
|
||||
.processedMap(concepts::WriteMap<Node,bool>())
|
||||
.run();
|
||||
}
|
||||
|
||||
template <class Digraph>
|
||||
void checkBfs() {
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
|
||||
Digraph G;
|
||||
Node s, t;
|
||||
|
||||
std::istringstream input(test_lgf);
|
||||
digraphReader(G, input).
|
||||
node("source", s).
|
||||
node("target", t).
|
||||
run();
|
||||
|
||||
Bfs<Digraph> bfs_test(G);
|
||||
bfs_test.run(s);
|
||||
|
||||
check(bfs_test.dist(t)==2,"Bfs found a wrong path.");
|
||||
|
||||
Path<Digraph> p = bfs_test.path(t);
|
||||
check(p.length()==2,"path() found a wrong path.");
|
||||
check(checkPath(G, p),"path() found a wrong path.");
|
||||
check(pathSource(G, p) == s,"path() found a wrong path.");
|
||||
check(pathTarget(G, p) == t,"path() found a wrong path.");
|
||||
|
||||
|
||||
for(ArcIt a(G); a!=INVALID; ++a) {
|
||||
Node u=G.source(a);
|
||||
Node v=G.target(a);
|
||||
check( !bfs_test.reached(u) ||
|
||||
(bfs_test.dist(v) <= bfs_test.dist(u)+1),
|
||||
"Wrong output. " << G.id(u) << "->" << G.id(v));
|
||||
}
|
||||
|
||||
for(NodeIt v(G); v!=INVALID; ++v) {
|
||||
if (bfs_test.reached(v)) {
|
||||
check(v==s || bfs_test.predArc(v)!=INVALID, "Wrong tree.");
|
||||
if (bfs_test.predArc(v)!=INVALID ) {
|
||||
Arc a=bfs_test.predArc(v);
|
||||
Node u=G.source(a);
|
||||
check(u==bfs_test.predNode(v),"Wrong tree.");
|
||||
check(bfs_test.dist(v) - bfs_test.dist(u) == 1,
|
||||
"Wrong distance. Difference: "
|
||||
<< std::abs(bfs_test.dist(v) - bfs_test.dist(u) - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
NullMap<Node,Arc> myPredMap;
|
||||
bfs(G).predMap(myPredMap).run(s);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
checkBfs<ListDigraph>();
|
||||
checkBfs<SmartDigraph>();
|
||||
return 0;
|
||||
}
|
||||
456
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/bpgraph_test.cc
vendored
Normal file
456
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/bpgraph_test.cc
vendored
Normal file
@@ -0,0 +1,456 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/concepts/bpgraph.h>
|
||||
#include <lemon/list_graph.h>
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/full_graph.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
#include "graph_test.h"
|
||||
|
||||
using namespace lemon;
|
||||
using namespace lemon::concepts;
|
||||
|
||||
template <class BpGraph>
|
||||
void checkBpGraphBuild() {
|
||||
TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
|
||||
|
||||
BpGraph G;
|
||||
checkGraphNodeList(G, 0);
|
||||
checkGraphRedNodeList(G, 0);
|
||||
checkGraphBlueNodeList(G, 0);
|
||||
checkGraphEdgeList(G, 0);
|
||||
checkGraphArcList(G, 0);
|
||||
|
||||
G.reserveNode(3);
|
||||
G.reserveEdge(3);
|
||||
|
||||
RedNode
|
||||
rn1 = G.addRedNode();
|
||||
checkGraphNodeList(G, 1);
|
||||
checkGraphRedNodeList(G, 1);
|
||||
checkGraphBlueNodeList(G, 0);
|
||||
checkGraphEdgeList(G, 0);
|
||||
checkGraphArcList(G, 0);
|
||||
|
||||
BlueNode
|
||||
bn1 = G.addBlueNode(),
|
||||
bn2 = G.addBlueNode();
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphRedNodeList(G, 1);
|
||||
checkGraphBlueNodeList(G, 2);
|
||||
checkGraphEdgeList(G, 0);
|
||||
checkGraphArcList(G, 0);
|
||||
|
||||
Edge e1 = G.addEdge(rn1, bn2);
|
||||
check(G.redNode(e1) == rn1 && G.blueNode(e1) == bn2, "Wrong edge");
|
||||
check(G.u(e1) == rn1 && G.v(e1) == bn2, "Wrong edge");
|
||||
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphRedNodeList(G, 1);
|
||||
checkGraphBlueNodeList(G, 2);
|
||||
checkGraphEdgeList(G, 1);
|
||||
checkGraphArcList(G, 2);
|
||||
|
||||
checkGraphIncEdgeArcLists(G, rn1, 1);
|
||||
checkGraphIncEdgeArcLists(G, bn1, 0);
|
||||
checkGraphIncEdgeArcLists(G, bn2, 1);
|
||||
|
||||
checkGraphConEdgeList(G, 1);
|
||||
checkGraphConArcList(G, 2);
|
||||
|
||||
Edge
|
||||
e2 = G.addEdge(bn1, rn1),
|
||||
e3 = G.addEdge(rn1, bn2);
|
||||
::lemon::ignore_unused_variable_warning(e2,e3);
|
||||
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphRedNodeList(G, 1);
|
||||
checkGraphBlueNodeList(G, 2);
|
||||
checkGraphEdgeList(G, 3);
|
||||
checkGraphArcList(G, 6);
|
||||
|
||||
checkGraphIncEdgeArcLists(G, rn1, 3);
|
||||
checkGraphIncEdgeArcLists(G, bn1, 1);
|
||||
checkGraphIncEdgeArcLists(G, bn2, 2);
|
||||
|
||||
checkGraphConEdgeList(G, 3);
|
||||
checkGraphConArcList(G, 6);
|
||||
|
||||
checkArcDirections(G);
|
||||
|
||||
checkNodeIds(G);
|
||||
checkRedNodeIds(G);
|
||||
checkBlueNodeIds(G);
|
||||
checkArcIds(G);
|
||||
checkEdgeIds(G);
|
||||
|
||||
checkGraphNodeMap(G);
|
||||
checkGraphRedNodeMap(G);
|
||||
checkGraphBlueNodeMap(G);
|
||||
checkGraphArcMap(G);
|
||||
checkGraphEdgeMap(G);
|
||||
}
|
||||
|
||||
template <class BpGraph>
|
||||
void checkBpGraphErase() {
|
||||
TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
|
||||
|
||||
BpGraph G;
|
||||
RedNode
|
||||
n1 = G.addRedNode(), n4 = G.addRedNode();
|
||||
BlueNode
|
||||
n2 = G.addBlueNode(), n3 = G.addBlueNode();
|
||||
Edge
|
||||
e1 = G.addEdge(n1, n2), e2 = G.addEdge(n1, n3),
|
||||
e3 = G.addEdge(n4, n2), e4 = G.addEdge(n4, n3);
|
||||
::lemon::ignore_unused_variable_warning(e1,e3,e4);
|
||||
|
||||
// Check edge deletion
|
||||
G.erase(e2);
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphRedNodeList(G, 2);
|
||||
checkGraphBlueNodeList(G, 2);
|
||||
checkGraphEdgeList(G, 3);
|
||||
checkGraphArcList(G, 6);
|
||||
|
||||
checkGraphIncEdgeArcLists(G, n1, 1);
|
||||
checkGraphIncEdgeArcLists(G, n2, 2);
|
||||
checkGraphIncEdgeArcLists(G, n3, 1);
|
||||
checkGraphIncEdgeArcLists(G, n4, 2);
|
||||
|
||||
checkGraphConEdgeList(G, 3);
|
||||
checkGraphConArcList(G, 6);
|
||||
|
||||
// Check node deletion
|
||||
G.erase(n3);
|
||||
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphRedNodeList(G, 2);
|
||||
checkGraphBlueNodeList(G, 1);
|
||||
checkGraphEdgeList(G, 2);
|
||||
checkGraphArcList(G, 4);
|
||||
|
||||
checkGraphIncEdgeArcLists(G, n1, 1);
|
||||
checkGraphIncEdgeArcLists(G, n2, 2);
|
||||
checkGraphIncEdgeArcLists(G, n4, 1);
|
||||
|
||||
checkGraphConEdgeList(G, 2);
|
||||
checkGraphConArcList(G, 4);
|
||||
|
||||
}
|
||||
|
||||
template <class BpGraph>
|
||||
void checkBpGraphAlter() {
|
||||
TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
|
||||
|
||||
BpGraph G;
|
||||
RedNode
|
||||
n1 = G.addRedNode(), n4 = G.addRedNode();
|
||||
BlueNode
|
||||
n2 = G.addBlueNode(), n3 = G.addBlueNode();
|
||||
Edge
|
||||
e1 = G.addEdge(n1, n2), e2 = G.addEdge(n1, n3),
|
||||
e3 = G.addEdge(n4, n2), e4 = G.addEdge(n4, n3);
|
||||
::lemon::ignore_unused_variable_warning(e1,e3,e4);
|
||||
|
||||
G.changeRed(e2, n4);
|
||||
check(G.redNode(e2) == n4, "Wrong red node");
|
||||
check(G.blueNode(e2) == n3, "Wrong blue node");
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphRedNodeList(G, 2);
|
||||
checkGraphBlueNodeList(G, 2);
|
||||
checkGraphEdgeList(G, 4);
|
||||
checkGraphArcList(G, 8);
|
||||
|
||||
checkGraphIncEdgeArcLists(G, n1, 1);
|
||||
checkGraphIncEdgeArcLists(G, n2, 2);
|
||||
checkGraphIncEdgeArcLists(G, n3, 2);
|
||||
checkGraphIncEdgeArcLists(G, n4, 3);
|
||||
|
||||
checkGraphConEdgeList(G, 4);
|
||||
checkGraphConArcList(G, 8);
|
||||
|
||||
G.changeBlue(e2, n2);
|
||||
check(G.redNode(e2) == n4, "Wrong red node");
|
||||
check(G.blueNode(e2) == n2, "Wrong blue node");
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphRedNodeList(G, 2);
|
||||
checkGraphBlueNodeList(G, 2);
|
||||
checkGraphEdgeList(G, 4);
|
||||
checkGraphArcList(G, 8);
|
||||
|
||||
checkGraphIncEdgeArcLists(G, n1, 1);
|
||||
checkGraphIncEdgeArcLists(G, n2, 3);
|
||||
checkGraphIncEdgeArcLists(G, n3, 1);
|
||||
checkGraphIncEdgeArcLists(G, n4, 3);
|
||||
|
||||
checkGraphConEdgeList(G, 4);
|
||||
checkGraphConArcList(G, 8);
|
||||
}
|
||||
|
||||
|
||||
template <class BpGraph>
|
||||
void checkBpGraphSnapshot() {
|
||||
TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
|
||||
|
||||
BpGraph G;
|
||||
RedNode
|
||||
n1 = G.addRedNode();
|
||||
BlueNode
|
||||
n2 = G.addBlueNode(),
|
||||
n3 = G.addBlueNode();
|
||||
Edge
|
||||
e1 = G.addEdge(n1, n2),
|
||||
e2 = G.addEdge(n1, n3);
|
||||
::lemon::ignore_unused_variable_warning(e1,e2);
|
||||
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphRedNodeList(G, 1);
|
||||
checkGraphBlueNodeList(G, 2);
|
||||
checkGraphEdgeList(G, 2);
|
||||
checkGraphArcList(G, 4);
|
||||
|
||||
typename BpGraph::Snapshot snapshot(G);
|
||||
|
||||
RedNode n4 = G.addRedNode();
|
||||
G.addEdge(n4, n2);
|
||||
G.addEdge(n4, n3);
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphRedNodeList(G, 2);
|
||||
checkGraphBlueNodeList(G, 2);
|
||||
checkGraphEdgeList(G, 4);
|
||||
checkGraphArcList(G, 8);
|
||||
|
||||
snapshot.restore();
|
||||
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphRedNodeList(G, 1);
|
||||
checkGraphBlueNodeList(G, 2);
|
||||
checkGraphEdgeList(G, 2);
|
||||
checkGraphArcList(G, 4);
|
||||
|
||||
checkGraphIncEdgeArcLists(G, n1, 2);
|
||||
checkGraphIncEdgeArcLists(G, n2, 1);
|
||||
checkGraphIncEdgeArcLists(G, n3, 1);
|
||||
|
||||
checkGraphConEdgeList(G, 2);
|
||||
checkGraphConArcList(G, 4);
|
||||
|
||||
checkNodeIds(G);
|
||||
checkRedNodeIds(G);
|
||||
checkBlueNodeIds(G);
|
||||
checkArcIds(G);
|
||||
checkEdgeIds(G);
|
||||
|
||||
checkGraphNodeMap(G);
|
||||
checkGraphRedNodeMap(G);
|
||||
checkGraphBlueNodeMap(G);
|
||||
checkGraphArcMap(G);
|
||||
checkGraphEdgeMap(G);
|
||||
|
||||
G.addRedNode();
|
||||
snapshot.save(G);
|
||||
|
||||
G.addEdge(G.addRedNode(), G.addBlueNode());
|
||||
|
||||
snapshot.restore();
|
||||
snapshot.save(G);
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphRedNodeList(G, 2);
|
||||
checkGraphBlueNodeList(G, 2);
|
||||
checkGraphEdgeList(G, 2);
|
||||
checkGraphArcList(G, 4);
|
||||
|
||||
G.addEdge(G.addRedNode(), G.addBlueNode());
|
||||
|
||||
snapshot.restore();
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphRedNodeList(G, 2);
|
||||
checkGraphBlueNodeList(G, 2);
|
||||
checkGraphEdgeList(G, 2);
|
||||
checkGraphArcList(G, 4);
|
||||
}
|
||||
|
||||
template <typename BpGraph>
|
||||
void checkBpGraphValidity() {
|
||||
TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
|
||||
BpGraph g;
|
||||
|
||||
RedNode
|
||||
n1 = g.addRedNode();
|
||||
BlueNode
|
||||
n2 = g.addBlueNode(),
|
||||
n3 = g.addBlueNode();
|
||||
|
||||
Edge
|
||||
e1 = g.addEdge(n1, n2),
|
||||
e2 = g.addEdge(n1, n3);
|
||||
::lemon::ignore_unused_variable_warning(e2);
|
||||
|
||||
check(g.valid(n1), "Wrong validity check");
|
||||
check(g.valid(e1), "Wrong validity check");
|
||||
check(g.valid(g.direct(e1, true)), "Wrong validity check");
|
||||
|
||||
check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
|
||||
check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
|
||||
check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
|
||||
}
|
||||
|
||||
void checkConcepts() {
|
||||
{ // Checking graph components
|
||||
checkConcept<BaseBpGraphComponent, BaseBpGraphComponent >();
|
||||
|
||||
checkConcept<IDableBpGraphComponent<>,
|
||||
IDableBpGraphComponent<> >();
|
||||
|
||||
checkConcept<IterableBpGraphComponent<>,
|
||||
IterableBpGraphComponent<> >();
|
||||
|
||||
checkConcept<AlterableBpGraphComponent<>,
|
||||
AlterableBpGraphComponent<> >();
|
||||
|
||||
checkConcept<MappableBpGraphComponent<>,
|
||||
MappableBpGraphComponent<> >();
|
||||
|
||||
checkConcept<ExtendableBpGraphComponent<>,
|
||||
ExtendableBpGraphComponent<> >();
|
||||
|
||||
checkConcept<ErasableBpGraphComponent<>,
|
||||
ErasableBpGraphComponent<> >();
|
||||
|
||||
checkConcept<ClearableBpGraphComponent<>,
|
||||
ClearableBpGraphComponent<> >();
|
||||
|
||||
}
|
||||
{ // Checking skeleton graph
|
||||
checkConcept<BpGraph, BpGraph>();
|
||||
}
|
||||
{ // Checking SmartBpGraph
|
||||
checkConcept<BpGraph, SmartBpGraph>();
|
||||
checkConcept<AlterableBpGraphComponent<>, SmartBpGraph>();
|
||||
checkConcept<ExtendableBpGraphComponent<>, SmartBpGraph>();
|
||||
checkConcept<ClearableBpGraphComponent<>, SmartBpGraph>();
|
||||
}
|
||||
}
|
||||
|
||||
void checkFullBpGraph(int redNum, int blueNum) {
|
||||
typedef FullBpGraph BpGraph;
|
||||
BPGRAPH_TYPEDEFS(BpGraph);
|
||||
|
||||
BpGraph G(redNum, blueNum);
|
||||
checkGraphNodeList(G, redNum + blueNum);
|
||||
checkGraphRedNodeList(G, redNum);
|
||||
checkGraphBlueNodeList(G, blueNum);
|
||||
checkGraphEdgeList(G, redNum * blueNum);
|
||||
checkGraphArcList(G, 2 * redNum * blueNum);
|
||||
|
||||
G.resize(redNum, blueNum);
|
||||
checkGraphNodeList(G, redNum + blueNum);
|
||||
checkGraphRedNodeList(G, redNum);
|
||||
checkGraphBlueNodeList(G, blueNum);
|
||||
checkGraphEdgeList(G, redNum * blueNum);
|
||||
checkGraphArcList(G, 2 * redNum * blueNum);
|
||||
|
||||
for (RedNodeIt n(G); n != INVALID; ++n) {
|
||||
checkGraphOutArcList(G, n, blueNum);
|
||||
checkGraphInArcList(G, n, blueNum);
|
||||
checkGraphIncEdgeList(G, n, blueNum);
|
||||
}
|
||||
|
||||
for (BlueNodeIt n(G); n != INVALID; ++n) {
|
||||
checkGraphOutArcList(G, n, redNum);
|
||||
checkGraphInArcList(G, n, redNum);
|
||||
checkGraphIncEdgeList(G, n, redNum);
|
||||
}
|
||||
|
||||
checkGraphConArcList(G, 2 * redNum * blueNum);
|
||||
checkGraphConEdgeList(G, redNum * blueNum);
|
||||
|
||||
checkArcDirections(G);
|
||||
|
||||
checkNodeIds(G);
|
||||
checkRedNodeIds(G);
|
||||
checkBlueNodeIds(G);
|
||||
checkArcIds(G);
|
||||
checkEdgeIds(G);
|
||||
|
||||
checkGraphNodeMap(G);
|
||||
checkGraphRedNodeMap(G);
|
||||
checkGraphBlueNodeMap(G);
|
||||
checkGraphArcMap(G);
|
||||
checkGraphEdgeMap(G);
|
||||
|
||||
for (int i = 0; i < G.redNum(); ++i) {
|
||||
check(G.red(G.redNode(i)), "Wrong node");
|
||||
check(G.index(G.redNode(i)) == i, "Wrong index");
|
||||
}
|
||||
|
||||
for (int i = 0; i < G.blueNum(); ++i) {
|
||||
check(G.blue(G.blueNode(i)), "Wrong node");
|
||||
check(G.index(G.blueNode(i)) == i, "Wrong index");
|
||||
}
|
||||
|
||||
for (NodeIt u(G); u != INVALID; ++u) {
|
||||
for (NodeIt v(G); v != INVALID; ++v) {
|
||||
Edge e = G.edge(u, v);
|
||||
Arc a = G.arc(u, v);
|
||||
if (G.red(u) == G.red(v)) {
|
||||
check(e == INVALID, "Wrong edge lookup");
|
||||
check(a == INVALID, "Wrong arc lookup");
|
||||
} else {
|
||||
check((G.u(e) == u && G.v(e) == v) ||
|
||||
(G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
|
||||
check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void checkGraphs() {
|
||||
{ // Checking ListGraph
|
||||
checkBpGraphBuild<ListBpGraph>();
|
||||
checkBpGraphErase<ListBpGraph>();
|
||||
checkBpGraphAlter<ListBpGraph>();
|
||||
checkBpGraphSnapshot<ListBpGraph>();
|
||||
checkBpGraphValidity<ListBpGraph>();
|
||||
}
|
||||
{ // Checking SmartGraph
|
||||
checkBpGraphBuild<SmartBpGraph>();
|
||||
checkBpGraphSnapshot<SmartBpGraph>();
|
||||
checkBpGraphValidity<SmartBpGraph>();
|
||||
}
|
||||
{ // Checking FullBpGraph
|
||||
checkFullBpGraph(6, 8);
|
||||
checkFullBpGraph(7, 4);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
checkConcepts();
|
||||
checkGraphs();
|
||||
return 0;
|
||||
}
|
||||
169
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/circulation_test.cc
vendored
Normal file
169
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/circulation_test.cc
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "test_tools.h"
|
||||
#include <lemon/list_graph.h>
|
||||
#include <lemon/circulation.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/concepts/digraph.h>
|
||||
#include <lemon/concepts/maps.h>
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
char test_lgf[] =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"@arcs\n"
|
||||
" lcap ucap\n"
|
||||
"0 1 2 10\n"
|
||||
"0 2 2 6\n"
|
||||
"1 3 4 7\n"
|
||||
"1 4 0 5\n"
|
||||
"2 4 1 3\n"
|
||||
"3 5 3 8\n"
|
||||
"4 5 3 7\n"
|
||||
"@attributes\n"
|
||||
"source 0\n"
|
||||
"sink 5\n";
|
||||
|
||||
void checkCirculationCompile()
|
||||
{
|
||||
typedef int VType;
|
||||
typedef concepts::Digraph Digraph;
|
||||
|
||||
typedef Digraph::Node Node;
|
||||
typedef Digraph::Arc Arc;
|
||||
typedef concepts::ReadMap<Arc,VType> CapMap;
|
||||
typedef concepts::ReadMap<Node,VType> SupplyMap;
|
||||
typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
|
||||
typedef concepts::WriteMap<Node,bool> BarrierMap;
|
||||
|
||||
typedef Elevator<Digraph, Digraph::Node> Elev;
|
||||
typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
|
||||
|
||||
Digraph g;
|
||||
Node n;
|
||||
Arc a;
|
||||
CapMap lcap, ucap;
|
||||
SupplyMap supply;
|
||||
FlowMap flow;
|
||||
BarrierMap bar;
|
||||
VType v;
|
||||
bool b;
|
||||
::lemon::ignore_unused_variable_warning(v,b);
|
||||
|
||||
typedef Circulation<Digraph, CapMap, CapMap, SupplyMap>
|
||||
::SetFlowMap<FlowMap>
|
||||
::SetElevator<Elev>
|
||||
::SetStandardElevator<LinkedElev>
|
||||
::Create CirculationType;
|
||||
CirculationType circ_test(g, lcap, ucap, supply);
|
||||
const CirculationType& const_circ_test = circ_test;
|
||||
|
||||
circ_test
|
||||
.lowerMap(lcap)
|
||||
.upperMap(ucap)
|
||||
.supplyMap(supply)
|
||||
.flowMap(flow);
|
||||
|
||||
const CirculationType::Elevator& elev = const_circ_test.elevator();
|
||||
circ_test.elevator(const_cast<CirculationType::Elevator&>(elev));
|
||||
CirculationType::Tolerance tol = const_circ_test.tolerance();
|
||||
circ_test.tolerance(tol);
|
||||
|
||||
circ_test.init();
|
||||
circ_test.greedyInit();
|
||||
circ_test.start();
|
||||
circ_test.run();
|
||||
|
||||
v = const_circ_test.flow(a);
|
||||
const FlowMap& fm = const_circ_test.flowMap();
|
||||
b = const_circ_test.barrier(n);
|
||||
const_circ_test.barrierMap(bar);
|
||||
|
||||
::lemon::ignore_unused_variable_warning(fm);
|
||||
}
|
||||
|
||||
template <class G, class LM, class UM, class DM>
|
||||
void checkCirculation(const G& g, const LM& lm, const UM& um,
|
||||
const DM& dm, bool find)
|
||||
{
|
||||
Circulation<G, LM, UM, DM> circ(g, lm, um, dm);
|
||||
bool ret = circ.run();
|
||||
if (find) {
|
||||
check(ret, "A feasible solution should have been found.");
|
||||
check(circ.checkFlow(), "The found flow is corrupt.");
|
||||
check(!circ.checkBarrier(), "A barrier should not have been found.");
|
||||
} else {
|
||||
check(!ret, "A feasible solution should not have been found.");
|
||||
check(circ.checkBarrier(), "The found barrier is corrupt.");
|
||||
}
|
||||
}
|
||||
|
||||
int main (int, char*[])
|
||||
{
|
||||
typedef ListDigraph Digraph;
|
||||
DIGRAPH_TYPEDEFS(Digraph);
|
||||
|
||||
Digraph g;
|
||||
IntArcMap lo(g), up(g);
|
||||
IntNodeMap delta(g, 0);
|
||||
Node s, t;
|
||||
|
||||
std::istringstream input(test_lgf);
|
||||
DigraphReader<Digraph>(g,input).
|
||||
arcMap("lcap", lo).
|
||||
arcMap("ucap", up).
|
||||
node("source",s).
|
||||
node("sink",t).
|
||||
run();
|
||||
|
||||
delta[s] = 7; delta[t] = -7;
|
||||
checkCirculation(g, lo, up, delta, true);
|
||||
|
||||
delta[s] = 13; delta[t] = -13;
|
||||
checkCirculation(g, lo, up, delta, true);
|
||||
|
||||
delta[s] = 6; delta[t] = -6;
|
||||
checkCirculation(g, lo, up, delta, false);
|
||||
|
||||
delta[s] = 14; delta[t] = -14;
|
||||
checkCirculation(g, lo, up, delta, false);
|
||||
|
||||
delta[s] = 7; delta[t] = -13;
|
||||
checkCirculation(g, lo, up, delta, true);
|
||||
|
||||
delta[s] = 5; delta[t] = -15;
|
||||
checkCirculation(g, lo, up, delta, true);
|
||||
|
||||
delta[s] = 10; delta[t] = -11;
|
||||
checkCirculation(g, lo, up, delta, true);
|
||||
|
||||
delta[s] = 11; delta[t] = -10;
|
||||
checkCirculation(g, lo, up, delta, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
316
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/connectivity_test.cc
vendored
Normal file
316
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/connectivity_test.cc
vendored
Normal file
@@ -0,0 +1,316 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/connectivity.h>
|
||||
#include <lemon/list_graph.h>
|
||||
#include <lemon/adaptors.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
typedef ListDigraph Digraph;
|
||||
typedef Undirector<Digraph> Graph;
|
||||
|
||||
{
|
||||
Digraph d;
|
||||
Digraph::NodeMap<int> order(d);
|
||||
Graph g(d);
|
||||
|
||||
check(stronglyConnected(d), "The empty digraph is strongly connected");
|
||||
check(countStronglyConnectedComponents(d) == 0,
|
||||
"The empty digraph has 0 strongly connected component");
|
||||
check(connected(g), "The empty graph is connected");
|
||||
check(countConnectedComponents(g) == 0,
|
||||
"The empty graph has 0 connected component");
|
||||
|
||||
check(biNodeConnected(g), "The empty graph is bi-node-connected");
|
||||
check(countBiNodeConnectedComponents(g) == 0,
|
||||
"The empty graph has 0 bi-node-connected component");
|
||||
check(biEdgeConnected(g), "The empty graph is bi-edge-connected");
|
||||
check(countBiEdgeConnectedComponents(g) == 0,
|
||||
"The empty graph has 0 bi-edge-connected component");
|
||||
|
||||
check(dag(d), "The empty digraph is DAG.");
|
||||
check(checkedTopologicalSort(d, order), "The empty digraph is DAG.");
|
||||
check(loopFree(d), "The empty digraph is loop-free.");
|
||||
check(parallelFree(d), "The empty digraph is parallel-free.");
|
||||
check(simpleGraph(d), "The empty digraph is simple.");
|
||||
|
||||
check(acyclic(g), "The empty graph is acyclic.");
|
||||
check(tree(g), "The empty graph is tree.");
|
||||
check(bipartite(g), "The empty graph is bipartite.");
|
||||
check(loopFree(g), "The empty graph is loop-free.");
|
||||
check(parallelFree(g), "The empty graph is parallel-free.");
|
||||
check(simpleGraph(g), "The empty graph is simple.");
|
||||
}
|
||||
|
||||
{
|
||||
Digraph d;
|
||||
Digraph::NodeMap<int> order(d);
|
||||
Graph g(d);
|
||||
Digraph::Node n = d.addNode();
|
||||
::lemon::ignore_unused_variable_warning(n);
|
||||
|
||||
check(stronglyConnected(d), "This digraph is strongly connected");
|
||||
check(countStronglyConnectedComponents(d) == 1,
|
||||
"This digraph has 1 strongly connected component");
|
||||
check(connected(g), "This graph is connected");
|
||||
check(countConnectedComponents(g) == 1,
|
||||
"This graph has 1 connected component");
|
||||
|
||||
check(biNodeConnected(g), "This graph is bi-node-connected");
|
||||
check(countBiNodeConnectedComponents(g) == 0,
|
||||
"This graph has 0 bi-node-connected component");
|
||||
check(biEdgeConnected(g), "This graph is bi-edge-connected");
|
||||
check(countBiEdgeConnectedComponents(g) == 1,
|
||||
"This graph has 1 bi-edge-connected component");
|
||||
|
||||
check(dag(d), "This digraph is DAG.");
|
||||
check(checkedTopologicalSort(d, order), "This digraph is DAG.");
|
||||
check(loopFree(d), "This digraph is loop-free.");
|
||||
check(parallelFree(d), "This digraph is parallel-free.");
|
||||
check(simpleGraph(d), "This digraph is simple.");
|
||||
|
||||
check(acyclic(g), "This graph is acyclic.");
|
||||
check(tree(g), "This graph is tree.");
|
||||
check(bipartite(g), "This graph is bipartite.");
|
||||
check(loopFree(g), "This graph is loop-free.");
|
||||
check(parallelFree(g), "This graph is parallel-free.");
|
||||
check(simpleGraph(g), "This graph is simple.");
|
||||
}
|
||||
|
||||
{
|
||||
ListGraph g;
|
||||
ListGraph::NodeMap<bool> map(g);
|
||||
|
||||
ListGraph::Node n1 = g.addNode();
|
||||
ListGraph::Node n2 = g.addNode();
|
||||
|
||||
ListGraph::Edge e1 = g.addEdge(n1, n2);
|
||||
::lemon::ignore_unused_variable_warning(e1);
|
||||
check(biNodeConnected(g), "Graph is bi-node-connected");
|
||||
|
||||
ListGraph::Node n3 = g.addNode();
|
||||
::lemon::ignore_unused_variable_warning(n3);
|
||||
check(!biNodeConnected(g), "Graph is not bi-node-connected");
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
Digraph d;
|
||||
Digraph::NodeMap<int> order(d);
|
||||
Graph g(d);
|
||||
|
||||
Digraph::Node n1 = d.addNode();
|
||||
Digraph::Node n2 = d.addNode();
|
||||
Digraph::Node n3 = d.addNode();
|
||||
Digraph::Node n4 = d.addNode();
|
||||
Digraph::Node n5 = d.addNode();
|
||||
Digraph::Node n6 = d.addNode();
|
||||
|
||||
d.addArc(n1, n3);
|
||||
d.addArc(n3, n2);
|
||||
d.addArc(n2, n1);
|
||||
d.addArc(n4, n2);
|
||||
d.addArc(n4, n3);
|
||||
d.addArc(n5, n6);
|
||||
d.addArc(n6, n5);
|
||||
|
||||
check(!stronglyConnected(d), "This digraph is not strongly connected");
|
||||
check(countStronglyConnectedComponents(d) == 3,
|
||||
"This digraph has 3 strongly connected components");
|
||||
check(!connected(g), "This graph is not connected");
|
||||
check(countConnectedComponents(g) == 2,
|
||||
"This graph has 2 connected components");
|
||||
|
||||
check(!dag(d), "This digraph is not DAG.");
|
||||
check(!checkedTopologicalSort(d, order), "This digraph is not DAG.");
|
||||
check(loopFree(d), "This digraph is loop-free.");
|
||||
check(parallelFree(d), "This digraph is parallel-free.");
|
||||
check(simpleGraph(d), "This digraph is simple.");
|
||||
|
||||
check(!acyclic(g), "This graph is not acyclic.");
|
||||
check(!tree(g), "This graph is not tree.");
|
||||
check(!bipartite(g), "This graph is not bipartite.");
|
||||
check(loopFree(g), "This graph is loop-free.");
|
||||
check(!parallelFree(g), "This graph is not parallel-free.");
|
||||
check(!simpleGraph(g), "This graph is not simple.");
|
||||
|
||||
d.addArc(n3, n3);
|
||||
|
||||
check(!loopFree(d), "This digraph is not loop-free.");
|
||||
check(!loopFree(g), "This graph is not loop-free.");
|
||||
check(!simpleGraph(d), "This digraph is not simple.");
|
||||
|
||||
d.addArc(n3, n2);
|
||||
|
||||
check(!parallelFree(d), "This digraph is not parallel-free.");
|
||||
}
|
||||
|
||||
{
|
||||
Digraph d;
|
||||
Digraph::ArcMap<bool> cutarcs(d, false);
|
||||
Graph g(d);
|
||||
|
||||
Digraph::Node n1 = d.addNode();
|
||||
Digraph::Node n2 = d.addNode();
|
||||
Digraph::Node n3 = d.addNode();
|
||||
Digraph::Node n4 = d.addNode();
|
||||
Digraph::Node n5 = d.addNode();
|
||||
Digraph::Node n6 = d.addNode();
|
||||
Digraph::Node n7 = d.addNode();
|
||||
Digraph::Node n8 = d.addNode();
|
||||
|
||||
d.addArc(n1, n2);
|
||||
d.addArc(n5, n1);
|
||||
d.addArc(n2, n8);
|
||||
d.addArc(n8, n5);
|
||||
d.addArc(n6, n4);
|
||||
d.addArc(n4, n6);
|
||||
d.addArc(n2, n5);
|
||||
d.addArc(n1, n8);
|
||||
d.addArc(n6, n7);
|
||||
d.addArc(n7, n6);
|
||||
|
||||
check(!stronglyConnected(d), "This digraph is not strongly connected");
|
||||
check(countStronglyConnectedComponents(d) == 3,
|
||||
"This digraph has 3 strongly connected components");
|
||||
Digraph::NodeMap<int> scomp1(d);
|
||||
check(stronglyConnectedComponents(d, scomp1) == 3,
|
||||
"This digraph has 3 strongly connected components");
|
||||
check(scomp1[n1] != scomp1[n3] && scomp1[n1] != scomp1[n4] &&
|
||||
scomp1[n3] != scomp1[n4], "Wrong stronglyConnectedComponents()");
|
||||
check(scomp1[n1] == scomp1[n2] && scomp1[n1] == scomp1[n5] &&
|
||||
scomp1[n1] == scomp1[n8], "Wrong stronglyConnectedComponents()");
|
||||
check(scomp1[n4] == scomp1[n6] && scomp1[n4] == scomp1[n7],
|
||||
"Wrong stronglyConnectedComponents()");
|
||||
Digraph::ArcMap<bool> scut1(d, false);
|
||||
check(stronglyConnectedCutArcs(d, scut1) == 0,
|
||||
"This digraph has 0 strongly connected cut arc.");
|
||||
for (Digraph::ArcIt a(d); a != INVALID; ++a) {
|
||||
check(!scut1[a], "Wrong stronglyConnectedCutArcs()");
|
||||
}
|
||||
|
||||
check(!connected(g), "This graph is not connected");
|
||||
check(countConnectedComponents(g) == 3,
|
||||
"This graph has 3 connected components");
|
||||
Graph::NodeMap<int> comp(g);
|
||||
check(connectedComponents(g, comp) == 3,
|
||||
"This graph has 3 connected components");
|
||||
check(comp[n1] != comp[n3] && comp[n1] != comp[n4] &&
|
||||
comp[n3] != comp[n4], "Wrong connectedComponents()");
|
||||
check(comp[n1] == comp[n2] && comp[n1] == comp[n5] &&
|
||||
comp[n1] == comp[n8], "Wrong connectedComponents()");
|
||||
check(comp[n4] == comp[n6] && comp[n4] == comp[n7],
|
||||
"Wrong connectedComponents()");
|
||||
|
||||
cutarcs[d.addArc(n3, n1)] = true;
|
||||
cutarcs[d.addArc(n3, n5)] = true;
|
||||
cutarcs[d.addArc(n3, n8)] = true;
|
||||
cutarcs[d.addArc(n8, n6)] = true;
|
||||
cutarcs[d.addArc(n8, n7)] = true;
|
||||
|
||||
check(!stronglyConnected(d), "This digraph is not strongly connected");
|
||||
check(countStronglyConnectedComponents(d) == 3,
|
||||
"This digraph has 3 strongly connected components");
|
||||
Digraph::NodeMap<int> scomp2(d);
|
||||
check(stronglyConnectedComponents(d, scomp2) == 3,
|
||||
"This digraph has 3 strongly connected components");
|
||||
check(scomp2[n3] == 0, "Wrong stronglyConnectedComponents()");
|
||||
check(scomp2[n1] == 1 && scomp2[n2] == 1 && scomp2[n5] == 1 &&
|
||||
scomp2[n8] == 1, "Wrong stronglyConnectedComponents()");
|
||||
check(scomp2[n4] == 2 && scomp2[n6] == 2 && scomp2[n7] == 2,
|
||||
"Wrong stronglyConnectedComponents()");
|
||||
Digraph::ArcMap<bool> scut2(d, false);
|
||||
check(stronglyConnectedCutArcs(d, scut2) == 5,
|
||||
"This digraph has 5 strongly connected cut arcs.");
|
||||
for (Digraph::ArcIt a(d); a != INVALID; ++a) {
|
||||
check(scut2[a] == cutarcs[a], "Wrong stronglyConnectedCutArcs()");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// DAG example for topological sort from the book New Algorithms
|
||||
// (T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein)
|
||||
Digraph d;
|
||||
Digraph::NodeMap<int> order(d);
|
||||
|
||||
Digraph::Node belt = d.addNode();
|
||||
Digraph::Node trousers = d.addNode();
|
||||
Digraph::Node necktie = d.addNode();
|
||||
Digraph::Node coat = d.addNode();
|
||||
Digraph::Node socks = d.addNode();
|
||||
Digraph::Node shirt = d.addNode();
|
||||
Digraph::Node shoe = d.addNode();
|
||||
Digraph::Node watch = d.addNode();
|
||||
Digraph::Node pants = d.addNode();
|
||||
::lemon::ignore_unused_variable_warning(watch);
|
||||
|
||||
d.addArc(socks, shoe);
|
||||
d.addArc(pants, shoe);
|
||||
d.addArc(pants, trousers);
|
||||
d.addArc(trousers, shoe);
|
||||
d.addArc(trousers, belt);
|
||||
d.addArc(belt, coat);
|
||||
d.addArc(shirt, belt);
|
||||
d.addArc(shirt, necktie);
|
||||
d.addArc(necktie, coat);
|
||||
|
||||
check(dag(d), "This digraph is DAG.");
|
||||
topologicalSort(d, order);
|
||||
for (Digraph::ArcIt a(d); a != INVALID; ++a) {
|
||||
check(order[d.source(a)] < order[d.target(a)],
|
||||
"Wrong topologicalSort()");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
ListGraph g;
|
||||
ListGraph::NodeMap<bool> map(g);
|
||||
|
||||
ListGraph::Node n1 = g.addNode();
|
||||
ListGraph::Node n2 = g.addNode();
|
||||
ListGraph::Node n3 = g.addNode();
|
||||
ListGraph::Node n4 = g.addNode();
|
||||
ListGraph::Node n5 = g.addNode();
|
||||
ListGraph::Node n6 = g.addNode();
|
||||
ListGraph::Node n7 = g.addNode();
|
||||
|
||||
g.addEdge(n1, n3);
|
||||
g.addEdge(n1, n4);
|
||||
g.addEdge(n2, n5);
|
||||
g.addEdge(n3, n6);
|
||||
g.addEdge(n4, n6);
|
||||
g.addEdge(n4, n7);
|
||||
g.addEdge(n5, n7);
|
||||
|
||||
check(bipartite(g), "This graph is bipartite");
|
||||
check(bipartitePartitions(g, map), "This graph is bipartite");
|
||||
|
||||
check(map[n1] == map[n2] && map[n1] == map[n6] && map[n1] == map[n7],
|
||||
"Wrong bipartitePartitions()");
|
||||
check(map[n3] == map[n4] && map[n3] == map[n5],
|
||||
"Wrong bipartitePartitions()");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
118
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/counter_test.cc
vendored
Normal file
118
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/counter_test.cc
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/counter.h>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
#include "test/test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
template <typename T>
|
||||
void bubbleSort(std::vector<T>& v) {
|
||||
std::stringstream s1, s2, s3;
|
||||
{
|
||||
Counter op("Bubble Sort - Operations: ", s1);
|
||||
Counter::SubCounter as(op, "Assignments: ", s2);
|
||||
Counter::SubCounter co(op, "Comparisons: ", s3);
|
||||
for (int i = v.size()-1; i > 0; --i) {
|
||||
for (int j = 0; j < i; ++j) {
|
||||
if (v[j] > v[j+1]) {
|
||||
T tmp = v[j];
|
||||
v[j] = v[j+1];
|
||||
v[j+1] = tmp;
|
||||
as += 3;
|
||||
}
|
||||
++co;
|
||||
}
|
||||
}
|
||||
}
|
||||
check(s1.str() == "Bubble Sort - Operations: 102\n", "Wrong counter");
|
||||
check(s2.str() == "Assignments: 57\n", "Wrong subcounter");
|
||||
check(s3.str() == "Comparisons: 45\n", "Wrong subcounter");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void insertionSort(std::vector<T>& v) {
|
||||
std::stringstream s1, s2, s3;
|
||||
{
|
||||
Counter op("Insertion Sort - Operations: ", s1);
|
||||
Counter::SubCounter as(op, "Assignments: ", s2);
|
||||
Counter::SubCounter co(op, "Comparisons: ", s3);
|
||||
for (int i = 1; i < int(v.size()); ++i) {
|
||||
T value = v[i];
|
||||
++as;
|
||||
int j = i;
|
||||
while (j > 0 && v[j-1] > value) {
|
||||
v[j] = v[j-1];
|
||||
--j;
|
||||
++co; ++as;
|
||||
}
|
||||
v[j] = value;
|
||||
++as;
|
||||
}
|
||||
}
|
||||
check(s1.str() == "Insertion Sort - Operations: 56\n", "Wrong counter");
|
||||
check(s2.str() == "Assignments: 37\n", "Wrong subcounter");
|
||||
check(s3.str() == "Comparisons: 19\n", "Wrong subcounter");
|
||||
}
|
||||
|
||||
template <typename MyCounter>
|
||||
void counterTest(bool output) {
|
||||
std::stringstream s1, s2, s3;
|
||||
{
|
||||
MyCounter c("Main Counter: ", s1);
|
||||
c++;
|
||||
typename MyCounter::SubCounter d(c, "SubCounter: ", s2);
|
||||
d++;
|
||||
typename MyCounter::SubCounter::NoSubCounter e(d, "SubSubCounter: ", s3);
|
||||
e++;
|
||||
d+=3;
|
||||
c-=4;
|
||||
e-=2;
|
||||
c.reset(2);
|
||||
c.reset();
|
||||
}
|
||||
if (output) {
|
||||
check(s1.str() == "Main Counter: 3\n", "Wrong Counter");
|
||||
check(s2.str() == "SubCounter: 3\n", "Wrong SubCounter");
|
||||
check(s3.str() == "", "Wrong NoSubCounter");
|
||||
} else {
|
||||
check(s1.str() == "", "Wrong NoCounter");
|
||||
check(s2.str() == "", "Wrong SubCounter");
|
||||
check(s3.str() == "", "Wrong NoSubCounter");
|
||||
}
|
||||
}
|
||||
|
||||
void init(std::vector<int>& v) {
|
||||
v[0] = 10; v[1] = 60; v[2] = 20; v[3] = 90; v[4] = 100;
|
||||
v[5] = 80; v[6] = 40; v[7] = 30; v[8] = 50; v[9] = 70;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
counterTest<Counter>(true);
|
||||
counterTest<NoCounter>(false);
|
||||
|
||||
std::vector<int> x(10);
|
||||
init(x); bubbleSort(x);
|
||||
init(x); insertionSort(x);
|
||||
|
||||
return 0;
|
||||
}
|
||||
238
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/dfs_test.cc
vendored
Normal file
238
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/dfs_test.cc
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/concepts/digraph.h>
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/list_graph.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/dfs.h>
|
||||
#include <lemon/path.h>
|
||||
|
||||
#include "graph_test.h"
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
char test_lgf[] =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"6\n"
|
||||
"@arcs\n"
|
||||
" label\n"
|
||||
"0 1 0\n"
|
||||
"1 2 1\n"
|
||||
"2 3 2\n"
|
||||
"1 4 3\n"
|
||||
"4 2 4\n"
|
||||
"4 5 5\n"
|
||||
"5 0 6\n"
|
||||
"6 3 7\n"
|
||||
"@attributes\n"
|
||||
"source 0\n"
|
||||
"target 5\n"
|
||||
"source1 6\n"
|
||||
"target1 3\n";
|
||||
|
||||
|
||||
void checkDfsCompile()
|
||||
{
|
||||
typedef concepts::Digraph Digraph;
|
||||
typedef Dfs<Digraph> DType;
|
||||
typedef Digraph::Node Node;
|
||||
typedef Digraph::Arc Arc;
|
||||
|
||||
Digraph G;
|
||||
Node s, t;
|
||||
Arc e;
|
||||
int l, i;
|
||||
bool b;
|
||||
::lemon::ignore_unused_variable_warning(l,i,b);
|
||||
|
||||
DType::DistMap d(G);
|
||||
DType::PredMap p(G);
|
||||
Path<Digraph> pp;
|
||||
concepts::ReadMap<Arc,bool> am;
|
||||
|
||||
{
|
||||
DType dfs_test(G);
|
||||
const DType& const_dfs_test = dfs_test;
|
||||
|
||||
dfs_test.run(s);
|
||||
dfs_test.run(s,t);
|
||||
dfs_test.run();
|
||||
|
||||
dfs_test.init();
|
||||
dfs_test.addSource(s);
|
||||
e = dfs_test.processNextArc();
|
||||
e = const_dfs_test.nextArc();
|
||||
b = const_dfs_test.emptyQueue();
|
||||
i = const_dfs_test.queueSize();
|
||||
|
||||
dfs_test.start();
|
||||
dfs_test.start(t);
|
||||
dfs_test.start(am);
|
||||
|
||||
l = const_dfs_test.dist(t);
|
||||
e = const_dfs_test.predArc(t);
|
||||
s = const_dfs_test.predNode(t);
|
||||
b = const_dfs_test.reached(t);
|
||||
d = const_dfs_test.distMap();
|
||||
p = const_dfs_test.predMap();
|
||||
pp = const_dfs_test.path(t);
|
||||
}
|
||||
{
|
||||
DType
|
||||
::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
|
||||
::SetDistMap<concepts::ReadWriteMap<Node,int> >
|
||||
::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
|
||||
::SetStandardProcessedMap
|
||||
::SetProcessedMap<concepts::WriteMap<Node,bool> >
|
||||
::Create dfs_test(G);
|
||||
|
||||
concepts::ReadWriteMap<Node,Arc> pred_map;
|
||||
concepts::ReadWriteMap<Node,int> dist_map;
|
||||
concepts::ReadWriteMap<Node,bool> reached_map;
|
||||
concepts::WriteMap<Node,bool> processed_map;
|
||||
|
||||
dfs_test
|
||||
.predMap(pred_map)
|
||||
.distMap(dist_map)
|
||||
.reachedMap(reached_map)
|
||||
.processedMap(processed_map);
|
||||
|
||||
dfs_test.run(s);
|
||||
dfs_test.run(s,t);
|
||||
dfs_test.run();
|
||||
dfs_test.init();
|
||||
|
||||
dfs_test.addSource(s);
|
||||
e = dfs_test.processNextArc();
|
||||
e = dfs_test.nextArc();
|
||||
b = dfs_test.emptyQueue();
|
||||
i = dfs_test.queueSize();
|
||||
|
||||
dfs_test.start();
|
||||
dfs_test.start(t);
|
||||
dfs_test.start(am);
|
||||
|
||||
l = dfs_test.dist(t);
|
||||
e = dfs_test.predArc(t);
|
||||
s = dfs_test.predNode(t);
|
||||
b = dfs_test.reached(t);
|
||||
pp = dfs_test.path(t);
|
||||
}
|
||||
}
|
||||
|
||||
void checkDfsFunctionCompile()
|
||||
{
|
||||
typedef int VType;
|
||||
typedef concepts::Digraph Digraph;
|
||||
typedef Digraph::Arc Arc;
|
||||
typedef Digraph::Node Node;
|
||||
|
||||
Digraph g;
|
||||
bool b;
|
||||
::lemon::ignore_unused_variable_warning(b);
|
||||
|
||||
dfs(g).run(Node());
|
||||
b=dfs(g).run(Node(),Node());
|
||||
dfs(g).run();
|
||||
dfs(g)
|
||||
.predMap(concepts::ReadWriteMap<Node,Arc>())
|
||||
.distMap(concepts::ReadWriteMap<Node,VType>())
|
||||
.reachedMap(concepts::ReadWriteMap<Node,bool>())
|
||||
.processedMap(concepts::WriteMap<Node,bool>())
|
||||
.run(Node());
|
||||
b=dfs(g)
|
||||
.predMap(concepts::ReadWriteMap<Node,Arc>())
|
||||
.distMap(concepts::ReadWriteMap<Node,VType>())
|
||||
.reachedMap(concepts::ReadWriteMap<Node,bool>())
|
||||
.processedMap(concepts::WriteMap<Node,bool>())
|
||||
.path(concepts::Path<Digraph>())
|
||||
.dist(VType())
|
||||
.run(Node(),Node());
|
||||
dfs(g)
|
||||
.predMap(concepts::ReadWriteMap<Node,Arc>())
|
||||
.distMap(concepts::ReadWriteMap<Node,VType>())
|
||||
.reachedMap(concepts::ReadWriteMap<Node,bool>())
|
||||
.processedMap(concepts::WriteMap<Node,bool>())
|
||||
.run();
|
||||
}
|
||||
|
||||
template <class Digraph>
|
||||
void checkDfs() {
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
|
||||
Digraph G;
|
||||
Node s, t;
|
||||
Node s1, t1;
|
||||
|
||||
std::istringstream input(test_lgf);
|
||||
digraphReader(G, input).
|
||||
node("source", s).
|
||||
node("target", t).
|
||||
node("source1", s1).
|
||||
node("target1", t1).
|
||||
run();
|
||||
|
||||
Dfs<Digraph> dfs_test(G);
|
||||
dfs_test.run(s);
|
||||
|
||||
Path<Digraph> p = dfs_test.path(t);
|
||||
check(p.length() == dfs_test.dist(t),"path() found a wrong path.");
|
||||
check(checkPath(G, p),"path() found a wrong path.");
|
||||
check(pathSource(G, p) == s,"path() found a wrong path.");
|
||||
check(pathTarget(G, p) == t,"path() found a wrong path.");
|
||||
|
||||
for(NodeIt v(G); v!=INVALID; ++v) {
|
||||
if (dfs_test.reached(v)) {
|
||||
check(v==s || dfs_test.predArc(v)!=INVALID, "Wrong tree.");
|
||||
if (dfs_test.predArc(v)!=INVALID ) {
|
||||
Arc e=dfs_test.predArc(v);
|
||||
Node u=G.source(e);
|
||||
check(u==dfs_test.predNode(v),"Wrong tree.");
|
||||
check(dfs_test.dist(v) - dfs_test.dist(u) == 1,
|
||||
"Wrong distance. (" << dfs_test.dist(u) << "->"
|
||||
<< dfs_test.dist(v) << ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Dfs<Digraph> dfs(G);
|
||||
check(dfs.run(s1,t1) && dfs.reached(t1),"Node 3 is reachable from Node 6.");
|
||||
}
|
||||
|
||||
{
|
||||
NullMap<Node,Arc> myPredMap;
|
||||
dfs(G).predMap(myPredMap).run(s);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
checkDfs<ListDigraph>();
|
||||
checkDfs<SmartDigraph>();
|
||||
return 0;
|
||||
}
|
||||
569
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/digraph_test.cc
vendored
Normal file
569
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/digraph_test.cc
vendored
Normal file
@@ -0,0 +1,569 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/concepts/digraph.h>
|
||||
#include <lemon/list_graph.h>
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/static_graph.h>
|
||||
#include <lemon/full_graph.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
#include "graph_test.h"
|
||||
|
||||
using namespace lemon;
|
||||
using namespace lemon::concepts;
|
||||
|
||||
template <class Digraph>
|
||||
void checkDigraphBuild() {
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
Digraph G;
|
||||
|
||||
checkGraphNodeList(G, 0);
|
||||
checkGraphArcList(G, 0);
|
||||
|
||||
G.reserveNode(3);
|
||||
G.reserveArc(4);
|
||||
|
||||
Node
|
||||
n1 = G.addNode(),
|
||||
n2 = G.addNode(),
|
||||
n3 = G.addNode();
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphArcList(G, 0);
|
||||
|
||||
Arc a1 = G.addArc(n1, n2);
|
||||
check(G.source(a1) == n1 && G.target(a1) == n2, "Wrong arc");
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphArcList(G, 1);
|
||||
|
||||
checkGraphOutArcList(G, n1, 1);
|
||||
checkGraphOutArcList(G, n2, 0);
|
||||
checkGraphOutArcList(G, n3, 0);
|
||||
|
||||
checkGraphInArcList(G, n1, 0);
|
||||
checkGraphInArcList(G, n2, 1);
|
||||
checkGraphInArcList(G, n3, 0);
|
||||
|
||||
checkGraphConArcList(G, 1);
|
||||
|
||||
Arc a2 = G.addArc(n2, n1),
|
||||
a3 = G.addArc(n2, n3),
|
||||
a4 = G.addArc(n2, n3);
|
||||
::lemon::ignore_unused_variable_warning(a2,a3,a4);
|
||||
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphArcList(G, 4);
|
||||
|
||||
checkGraphOutArcList(G, n1, 1);
|
||||
checkGraphOutArcList(G, n2, 3);
|
||||
checkGraphOutArcList(G, n3, 0);
|
||||
|
||||
checkGraphInArcList(G, n1, 1);
|
||||
checkGraphInArcList(G, n2, 1);
|
||||
checkGraphInArcList(G, n3, 2);
|
||||
|
||||
checkGraphConArcList(G, 4);
|
||||
|
||||
checkNodeIds(G);
|
||||
checkArcIds(G);
|
||||
checkGraphNodeMap(G);
|
||||
checkGraphArcMap(G);
|
||||
}
|
||||
|
||||
template <class Digraph>
|
||||
void checkDigraphSplit() {
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
|
||||
Digraph G;
|
||||
Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
|
||||
Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
|
||||
a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
|
||||
::lemon::ignore_unused_variable_warning(a1,a2,a3,a4);
|
||||
|
||||
Node n4 = G.split(n2);
|
||||
|
||||
check(G.target(OutArcIt(G, n2)) == n4 &&
|
||||
G.source(InArcIt(G, n4)) == n2,
|
||||
"Wrong split.");
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphArcList(G, 5);
|
||||
|
||||
checkGraphOutArcList(G, n1, 1);
|
||||
checkGraphOutArcList(G, n2, 1);
|
||||
checkGraphOutArcList(G, n3, 0);
|
||||
checkGraphOutArcList(G, n4, 3);
|
||||
|
||||
checkGraphInArcList(G, n1, 1);
|
||||
checkGraphInArcList(G, n2, 1);
|
||||
checkGraphInArcList(G, n3, 2);
|
||||
checkGraphInArcList(G, n4, 1);
|
||||
|
||||
checkGraphConArcList(G, 5);
|
||||
}
|
||||
|
||||
template <class Digraph>
|
||||
void checkDigraphAlter() {
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
|
||||
Digraph G;
|
||||
Node n1 = G.addNode(), n2 = G.addNode(),
|
||||
n3 = G.addNode(), n4 = G.addNode();
|
||||
Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
|
||||
a3 = G.addArc(n4, n3), a4 = G.addArc(n4, n3),
|
||||
a5 = G.addArc(n2, n4);
|
||||
::lemon::ignore_unused_variable_warning(a1,a2,a3,a5);
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphArcList(G, 5);
|
||||
|
||||
// Check changeSource() and changeTarget()
|
||||
G.changeTarget(a4, n1);
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphArcList(G, 5);
|
||||
|
||||
checkGraphOutArcList(G, n1, 1);
|
||||
checkGraphOutArcList(G, n2, 1);
|
||||
checkGraphOutArcList(G, n3, 0);
|
||||
checkGraphOutArcList(G, n4, 3);
|
||||
|
||||
checkGraphInArcList(G, n1, 2);
|
||||
checkGraphInArcList(G, n2, 1);
|
||||
checkGraphInArcList(G, n3, 1);
|
||||
checkGraphInArcList(G, n4, 1);
|
||||
|
||||
checkGraphConArcList(G, 5);
|
||||
|
||||
G.changeSource(a4, n3);
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphArcList(G, 5);
|
||||
|
||||
checkGraphOutArcList(G, n1, 1);
|
||||
checkGraphOutArcList(G, n2, 1);
|
||||
checkGraphOutArcList(G, n3, 1);
|
||||
checkGraphOutArcList(G, n4, 2);
|
||||
|
||||
checkGraphInArcList(G, n1, 2);
|
||||
checkGraphInArcList(G, n2, 1);
|
||||
checkGraphInArcList(G, n3, 1);
|
||||
checkGraphInArcList(G, n4, 1);
|
||||
|
||||
checkGraphConArcList(G, 5);
|
||||
|
||||
// Check contract()
|
||||
G.contract(n2, n4, false);
|
||||
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphArcList(G, 5);
|
||||
|
||||
checkGraphOutArcList(G, n1, 1);
|
||||
checkGraphOutArcList(G, n2, 3);
|
||||
checkGraphOutArcList(G, n3, 1);
|
||||
|
||||
checkGraphInArcList(G, n1, 2);
|
||||
checkGraphInArcList(G, n2, 2);
|
||||
checkGraphInArcList(G, n3, 1);
|
||||
|
||||
checkGraphConArcList(G, 5);
|
||||
|
||||
G.contract(n2, n1);
|
||||
|
||||
checkGraphNodeList(G, 2);
|
||||
checkGraphArcList(G, 3);
|
||||
|
||||
checkGraphOutArcList(G, n2, 2);
|
||||
checkGraphOutArcList(G, n3, 1);
|
||||
|
||||
checkGraphInArcList(G, n2, 2);
|
||||
checkGraphInArcList(G, n3, 1);
|
||||
|
||||
checkGraphConArcList(G, 3);
|
||||
}
|
||||
|
||||
template <class Digraph>
|
||||
void checkDigraphErase() {
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
|
||||
Digraph G;
|
||||
Node n1 = G.addNode(), n2 = G.addNode(),
|
||||
n3 = G.addNode(), n4 = G.addNode();
|
||||
Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
|
||||
a3 = G.addArc(n4, n3), a4 = G.addArc(n3, n1),
|
||||
a5 = G.addArc(n2, n4);
|
||||
::lemon::ignore_unused_variable_warning(a2,a3,a4,a5);
|
||||
|
||||
// Check arc deletion
|
||||
G.erase(a1);
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphArcList(G, 4);
|
||||
|
||||
checkGraphOutArcList(G, n1, 0);
|
||||
checkGraphOutArcList(G, n2, 1);
|
||||
checkGraphOutArcList(G, n3, 1);
|
||||
checkGraphOutArcList(G, n4, 2);
|
||||
|
||||
checkGraphInArcList(G, n1, 2);
|
||||
checkGraphInArcList(G, n2, 0);
|
||||
checkGraphInArcList(G, n3, 1);
|
||||
checkGraphInArcList(G, n4, 1);
|
||||
|
||||
checkGraphConArcList(G, 4);
|
||||
|
||||
// Check node deletion
|
||||
G.erase(n4);
|
||||
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphArcList(G, 1);
|
||||
|
||||
checkGraphOutArcList(G, n1, 0);
|
||||
checkGraphOutArcList(G, n2, 0);
|
||||
checkGraphOutArcList(G, n3, 1);
|
||||
checkGraphOutArcList(G, n4, 0);
|
||||
|
||||
checkGraphInArcList(G, n1, 1);
|
||||
checkGraphInArcList(G, n2, 0);
|
||||
checkGraphInArcList(G, n3, 0);
|
||||
checkGraphInArcList(G, n4, 0);
|
||||
|
||||
checkGraphConArcList(G, 1);
|
||||
}
|
||||
|
||||
|
||||
template <class Digraph>
|
||||
void checkDigraphSnapshot() {
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
|
||||
Digraph G;
|
||||
Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
|
||||
Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
|
||||
a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
|
||||
::lemon::ignore_unused_variable_warning(a1,a2,a3,a4);
|
||||
|
||||
typename Digraph::Snapshot snapshot(G);
|
||||
|
||||
Node n = G.addNode();
|
||||
G.addArc(n3, n);
|
||||
G.addArc(n, n3);
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphArcList(G, 6);
|
||||
|
||||
snapshot.restore();
|
||||
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphArcList(G, 4);
|
||||
|
||||
checkGraphOutArcList(G, n1, 1);
|
||||
checkGraphOutArcList(G, n2, 3);
|
||||
checkGraphOutArcList(G, n3, 0);
|
||||
|
||||
checkGraphInArcList(G, n1, 1);
|
||||
checkGraphInArcList(G, n2, 1);
|
||||
checkGraphInArcList(G, n3, 2);
|
||||
|
||||
checkGraphConArcList(G, 4);
|
||||
|
||||
checkNodeIds(G);
|
||||
checkArcIds(G);
|
||||
checkGraphNodeMap(G);
|
||||
checkGraphArcMap(G);
|
||||
|
||||
G.addNode();
|
||||
snapshot.save(G);
|
||||
|
||||
G.addArc(G.addNode(), G.addNode());
|
||||
|
||||
snapshot.restore();
|
||||
snapshot.save(G);
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphArcList(G, 4);
|
||||
|
||||
G.addArc(G.addNode(), G.addNode());
|
||||
|
||||
snapshot.restore();
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphArcList(G, 4);
|
||||
}
|
||||
|
||||
void checkConcepts() {
|
||||
{ // Checking digraph components
|
||||
checkConcept<BaseDigraphComponent, BaseDigraphComponent >();
|
||||
|
||||
checkConcept<IDableDigraphComponent<>,
|
||||
IDableDigraphComponent<> >();
|
||||
|
||||
checkConcept<IterableDigraphComponent<>,
|
||||
IterableDigraphComponent<> >();
|
||||
|
||||
checkConcept<MappableDigraphComponent<>,
|
||||
MappableDigraphComponent<> >();
|
||||
}
|
||||
{ // Checking skeleton digraph
|
||||
checkConcept<Digraph, Digraph>();
|
||||
}
|
||||
{ // Checking ListDigraph
|
||||
checkConcept<Digraph, ListDigraph>();
|
||||
checkConcept<AlterableDigraphComponent<>, ListDigraph>();
|
||||
checkConcept<ExtendableDigraphComponent<>, ListDigraph>();
|
||||
checkConcept<ClearableDigraphComponent<>, ListDigraph>();
|
||||
checkConcept<ErasableDigraphComponent<>, ListDigraph>();
|
||||
}
|
||||
{ // Checking SmartDigraph
|
||||
checkConcept<Digraph, SmartDigraph>();
|
||||
checkConcept<AlterableDigraphComponent<>, SmartDigraph>();
|
||||
checkConcept<ExtendableDigraphComponent<>, SmartDigraph>();
|
||||
checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
|
||||
}
|
||||
{ // Checking StaticDigraph
|
||||
checkConcept<Digraph, StaticDigraph>();
|
||||
checkConcept<ClearableDigraphComponent<>, StaticDigraph>();
|
||||
}
|
||||
{ // Checking FullDigraph
|
||||
checkConcept<Digraph, FullDigraph>();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Digraph>
|
||||
void checkDigraphValidity() {
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
Digraph g;
|
||||
|
||||
Node
|
||||
n1 = g.addNode(),
|
||||
n2 = g.addNode(),
|
||||
n3 = g.addNode();
|
||||
|
||||
Arc
|
||||
e1 = g.addArc(n1, n2),
|
||||
e2 = g.addArc(n2, n3);
|
||||
::lemon::ignore_unused_variable_warning(e2);
|
||||
|
||||
check(g.valid(n1), "Wrong validity check");
|
||||
check(g.valid(e1), "Wrong validity check");
|
||||
|
||||
check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
|
||||
check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
|
||||
}
|
||||
|
||||
template <typename Digraph>
|
||||
void checkDigraphValidityErase() {
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
Digraph g;
|
||||
|
||||
Node
|
||||
n1 = g.addNode(),
|
||||
n2 = g.addNode(),
|
||||
n3 = g.addNode();
|
||||
|
||||
Arc
|
||||
e1 = g.addArc(n1, n2),
|
||||
e2 = g.addArc(n2, n3);
|
||||
|
||||
check(g.valid(n1), "Wrong validity check");
|
||||
check(g.valid(e1), "Wrong validity check");
|
||||
|
||||
g.erase(n1);
|
||||
|
||||
check(!g.valid(n1), "Wrong validity check");
|
||||
check(g.valid(n2), "Wrong validity check");
|
||||
check(g.valid(n3), "Wrong validity check");
|
||||
check(!g.valid(e1), "Wrong validity check");
|
||||
check(g.valid(e2), "Wrong validity check");
|
||||
|
||||
check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
|
||||
check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
|
||||
}
|
||||
|
||||
void checkStaticDigraph() {
|
||||
SmartDigraph g;
|
||||
SmartDigraph::NodeMap<StaticDigraph::Node> nref(g);
|
||||
SmartDigraph::ArcMap<StaticDigraph::Arc> aref(g);
|
||||
|
||||
StaticDigraph G;
|
||||
|
||||
checkGraphNodeList(G, 0);
|
||||
checkGraphArcList(G, 0);
|
||||
|
||||
G.build(g, nref, aref);
|
||||
|
||||
checkGraphNodeList(G, 0);
|
||||
checkGraphArcList(G, 0);
|
||||
|
||||
SmartDigraph::Node
|
||||
n1 = g.addNode(),
|
||||
n2 = g.addNode(),
|
||||
n3 = g.addNode();
|
||||
|
||||
G.build(g, nref, aref);
|
||||
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphArcList(G, 0);
|
||||
|
||||
SmartDigraph::Arc a1 = g.addArc(n1, n2);
|
||||
|
||||
G.build(g, nref, aref);
|
||||
|
||||
check(G.source(aref[a1]) == nref[n1] && G.target(aref[a1]) == nref[n2],
|
||||
"Wrong arc or wrong references");
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphArcList(G, 1);
|
||||
|
||||
checkGraphOutArcList(G, nref[n1], 1);
|
||||
checkGraphOutArcList(G, nref[n2], 0);
|
||||
checkGraphOutArcList(G, nref[n3], 0);
|
||||
|
||||
checkGraphInArcList(G, nref[n1], 0);
|
||||
checkGraphInArcList(G, nref[n2], 1);
|
||||
checkGraphInArcList(G, nref[n3], 0);
|
||||
|
||||
checkGraphConArcList(G, 1);
|
||||
|
||||
SmartDigraph::Arc
|
||||
a2 = g.addArc(n2, n1),
|
||||
a3 = g.addArc(n2, n3),
|
||||
a4 = g.addArc(n2, n3);
|
||||
::lemon::ignore_unused_variable_warning(a2,a3,a4);
|
||||
|
||||
digraphCopy(g, G).nodeRef(nref).run();
|
||||
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphArcList(G, 4);
|
||||
|
||||
checkGraphOutArcList(G, nref[n1], 1);
|
||||
checkGraphOutArcList(G, nref[n2], 3);
|
||||
checkGraphOutArcList(G, nref[n3], 0);
|
||||
|
||||
checkGraphInArcList(G, nref[n1], 1);
|
||||
checkGraphInArcList(G, nref[n2], 1);
|
||||
checkGraphInArcList(G, nref[n3], 2);
|
||||
|
||||
checkGraphConArcList(G, 4);
|
||||
|
||||
std::vector<std::pair<int,int> > arcs;
|
||||
arcs.push_back(std::make_pair(0,1));
|
||||
arcs.push_back(std::make_pair(0,2));
|
||||
arcs.push_back(std::make_pair(1,3));
|
||||
arcs.push_back(std::make_pair(1,2));
|
||||
arcs.push_back(std::make_pair(3,0));
|
||||
arcs.push_back(std::make_pair(3,3));
|
||||
arcs.push_back(std::make_pair(4,2));
|
||||
arcs.push_back(std::make_pair(4,3));
|
||||
arcs.push_back(std::make_pair(4,1));
|
||||
|
||||
G.build(6, arcs.begin(), arcs.end());
|
||||
|
||||
checkGraphNodeList(G, 6);
|
||||
checkGraphArcList(G, 9);
|
||||
|
||||
checkGraphOutArcList(G, G.node(0), 2);
|
||||
checkGraphOutArcList(G, G.node(1), 2);
|
||||
checkGraphOutArcList(G, G.node(2), 0);
|
||||
checkGraphOutArcList(G, G.node(3), 2);
|
||||
checkGraphOutArcList(G, G.node(4), 3);
|
||||
checkGraphOutArcList(G, G.node(5), 0);
|
||||
|
||||
checkGraphInArcList(G, G.node(0), 1);
|
||||
checkGraphInArcList(G, G.node(1), 2);
|
||||
checkGraphInArcList(G, G.node(2), 3);
|
||||
checkGraphInArcList(G, G.node(3), 3);
|
||||
checkGraphInArcList(G, G.node(4), 0);
|
||||
checkGraphInArcList(G, G.node(5), 0);
|
||||
|
||||
checkGraphConArcList(G, 9);
|
||||
|
||||
checkNodeIds(G);
|
||||
checkArcIds(G);
|
||||
checkGraphNodeMap(G);
|
||||
checkGraphArcMap(G);
|
||||
|
||||
int n = G.nodeNum();
|
||||
int m = G.arcNum();
|
||||
check(G.index(G.node(n-1)) == n-1, "Wrong index.");
|
||||
check(G.index(G.arc(m-1)) == m-1, "Wrong index.");
|
||||
}
|
||||
|
||||
void checkFullDigraph(int num) {
|
||||
typedef FullDigraph Digraph;
|
||||
DIGRAPH_TYPEDEFS(Digraph);
|
||||
|
||||
Digraph G(num);
|
||||
check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
|
||||
|
||||
G.resize(num);
|
||||
check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
|
||||
|
||||
checkGraphNodeList(G, num);
|
||||
checkGraphArcList(G, num * num);
|
||||
|
||||
for (NodeIt n(G); n != INVALID; ++n) {
|
||||
checkGraphOutArcList(G, n, num);
|
||||
checkGraphInArcList(G, n, num);
|
||||
}
|
||||
|
||||
checkGraphConArcList(G, num * num);
|
||||
|
||||
checkNodeIds(G);
|
||||
checkArcIds(G);
|
||||
checkGraphNodeMap(G);
|
||||
checkGraphArcMap(G);
|
||||
|
||||
for (int i = 0; i < G.nodeNum(); ++i) {
|
||||
check(G.index(G(i)) == i, "Wrong index");
|
||||
}
|
||||
|
||||
for (NodeIt s(G); s != INVALID; ++s) {
|
||||
for (NodeIt t(G); t != INVALID; ++t) {
|
||||
Arc a = G.arc(s, t);
|
||||
check(G.source(a) == s && G.target(a) == t, "Wrong arc lookup");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void checkDigraphs() {
|
||||
{ // Checking ListDigraph
|
||||
checkDigraphBuild<ListDigraph>();
|
||||
checkDigraphSplit<ListDigraph>();
|
||||
checkDigraphAlter<ListDigraph>();
|
||||
checkDigraphErase<ListDigraph>();
|
||||
checkDigraphSnapshot<ListDigraph>();
|
||||
checkDigraphValidityErase<ListDigraph>();
|
||||
}
|
||||
{ // Checking SmartDigraph
|
||||
checkDigraphBuild<SmartDigraph>();
|
||||
checkDigraphSplit<SmartDigraph>();
|
||||
checkDigraphSnapshot<SmartDigraph>();
|
||||
checkDigraphValidity<SmartDigraph>();
|
||||
}
|
||||
{ // Checking StaticDigraph
|
||||
checkStaticDigraph();
|
||||
}
|
||||
{ // Checking FullDigraph
|
||||
checkFullDigraph(8);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
checkDigraphs();
|
||||
checkConcepts();
|
||||
return 0;
|
||||
}
|
||||
246
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/dijkstra_test.cc
vendored
Normal file
246
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/dijkstra_test.cc
vendored
Normal file
@@ -0,0 +1,246 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/concepts/digraph.h>
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/list_graph.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/dijkstra.h>
|
||||
#include <lemon/path.h>
|
||||
#include <lemon/bin_heap.h>
|
||||
|
||||
#include "graph_test.h"
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
char test_lgf[] =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"@arcs\n"
|
||||
" label length\n"
|
||||
"0 1 0 1\n"
|
||||
"1 2 1 1\n"
|
||||
"2 3 2 1\n"
|
||||
"0 3 4 5\n"
|
||||
"0 3 5 10\n"
|
||||
"0 3 6 7\n"
|
||||
"4 2 7 1\n"
|
||||
"@attributes\n"
|
||||
"source 0\n"
|
||||
"target 3\n";
|
||||
|
||||
void checkDijkstraCompile()
|
||||
{
|
||||
typedef int VType;
|
||||
typedef concepts::Digraph Digraph;
|
||||
typedef concepts::ReadMap<Digraph::Arc,VType> LengthMap;
|
||||
typedef Dijkstra<Digraph, LengthMap> DType;
|
||||
typedef Digraph::Node Node;
|
||||
typedef Digraph::Arc Arc;
|
||||
|
||||
Digraph G;
|
||||
Node s, t, n;
|
||||
Arc e;
|
||||
VType l;
|
||||
int i;
|
||||
bool b;
|
||||
::lemon::ignore_unused_variable_warning(l,i,b);
|
||||
|
||||
DType::DistMap d(G);
|
||||
DType::PredMap p(G);
|
||||
LengthMap length;
|
||||
Path<Digraph> pp;
|
||||
concepts::ReadMap<Node,bool> nm;
|
||||
|
||||
{
|
||||
DType dijkstra_test(G,length);
|
||||
const DType& const_dijkstra_test = dijkstra_test;
|
||||
|
||||
dijkstra_test.run(s);
|
||||
dijkstra_test.run(s,t);
|
||||
|
||||
dijkstra_test.init();
|
||||
dijkstra_test.addSource(s);
|
||||
dijkstra_test.addSource(s, 1);
|
||||
n = dijkstra_test.processNextNode();
|
||||
n = const_dijkstra_test.nextNode();
|
||||
b = const_dijkstra_test.emptyQueue();
|
||||
i = const_dijkstra_test.queueSize();
|
||||
|
||||
dijkstra_test.start();
|
||||
dijkstra_test.start(t);
|
||||
dijkstra_test.start(nm);
|
||||
|
||||
l = const_dijkstra_test.dist(t);
|
||||
e = const_dijkstra_test.predArc(t);
|
||||
s = const_dijkstra_test.predNode(t);
|
||||
b = const_dijkstra_test.reached(t);
|
||||
b = const_dijkstra_test.processed(t);
|
||||
d = const_dijkstra_test.distMap();
|
||||
p = const_dijkstra_test.predMap();
|
||||
pp = const_dijkstra_test.path(t);
|
||||
l = const_dijkstra_test.currentDist(t);
|
||||
}
|
||||
{
|
||||
DType
|
||||
::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
|
||||
::SetDistMap<concepts::ReadWriteMap<Node,VType> >
|
||||
::SetStandardProcessedMap
|
||||
::SetProcessedMap<concepts::WriteMap<Node,bool> >
|
||||
::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
|
||||
::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
|
||||
::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
|
||||
::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >,
|
||||
concepts::ReadWriteMap<Node,int> >
|
||||
::Create dijkstra_test(G,length);
|
||||
|
||||
LengthMap length_map;
|
||||
concepts::ReadWriteMap<Node,Arc> pred_map;
|
||||
concepts::ReadWriteMap<Node,VType> dist_map;
|
||||
concepts::WriteMap<Node,bool> processed_map;
|
||||
concepts::ReadWriteMap<Node,int> heap_cross_ref;
|
||||
BinHeap<VType, concepts::ReadWriteMap<Node,int> > heap(heap_cross_ref);
|
||||
|
||||
dijkstra_test
|
||||
.lengthMap(length_map)
|
||||
.predMap(pred_map)
|
||||
.distMap(dist_map)
|
||||
.processedMap(processed_map)
|
||||
.heap(heap, heap_cross_ref);
|
||||
|
||||
dijkstra_test.run(s);
|
||||
dijkstra_test.run(s,t);
|
||||
|
||||
dijkstra_test.addSource(s);
|
||||
dijkstra_test.addSource(s, 1);
|
||||
n = dijkstra_test.processNextNode();
|
||||
n = dijkstra_test.nextNode();
|
||||
b = dijkstra_test.emptyQueue();
|
||||
i = dijkstra_test.queueSize();
|
||||
|
||||
dijkstra_test.start();
|
||||
dijkstra_test.start(t);
|
||||
dijkstra_test.start(nm);
|
||||
|
||||
l = dijkstra_test.dist(t);
|
||||
e = dijkstra_test.predArc(t);
|
||||
s = dijkstra_test.predNode(t);
|
||||
b = dijkstra_test.reached(t);
|
||||
b = dijkstra_test.processed(t);
|
||||
pp = dijkstra_test.path(t);
|
||||
l = dijkstra_test.currentDist(t);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void checkDijkstraFunctionCompile()
|
||||
{
|
||||
typedef int VType;
|
||||
typedef concepts::Digraph Digraph;
|
||||
typedef Digraph::Arc Arc;
|
||||
typedef Digraph::Node Node;
|
||||
typedef concepts::ReadMap<Digraph::Arc,VType> LengthMap;
|
||||
|
||||
Digraph g;
|
||||
bool b;
|
||||
::lemon::ignore_unused_variable_warning(b);
|
||||
|
||||
dijkstra(g,LengthMap()).run(Node());
|
||||
b=dijkstra(g,LengthMap()).run(Node(),Node());
|
||||
dijkstra(g,LengthMap())
|
||||
.predMap(concepts::ReadWriteMap<Node,Arc>())
|
||||
.distMap(concepts::ReadWriteMap<Node,VType>())
|
||||
.processedMap(concepts::WriteMap<Node,bool>())
|
||||
.run(Node());
|
||||
b=dijkstra(g,LengthMap())
|
||||
.predMap(concepts::ReadWriteMap<Node,Arc>())
|
||||
.distMap(concepts::ReadWriteMap<Node,VType>())
|
||||
.processedMap(concepts::WriteMap<Node,bool>())
|
||||
.path(concepts::Path<Digraph>())
|
||||
.dist(VType())
|
||||
.run(Node(),Node());
|
||||
}
|
||||
|
||||
template <class Digraph>
|
||||
void checkDijkstra() {
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
typedef typename Digraph::template ArcMap<int> LengthMap;
|
||||
|
||||
Digraph G;
|
||||
Node s, t;
|
||||
LengthMap length(G);
|
||||
|
||||
std::istringstream input(test_lgf);
|
||||
digraphReader(G, input).
|
||||
arcMap("length", length).
|
||||
node("source", s).
|
||||
node("target", t).
|
||||
run();
|
||||
|
||||
Dijkstra<Digraph, LengthMap>
|
||||
dijkstra_test(G, length);
|
||||
dijkstra_test.run(s);
|
||||
|
||||
check(dijkstra_test.dist(t)==3,"Dijkstra found a wrong path.");
|
||||
|
||||
Path<Digraph> p = dijkstra_test.path(t);
|
||||
check(p.length()==3,"path() found a wrong path.");
|
||||
check(checkPath(G, p),"path() found a wrong path.");
|
||||
check(pathSource(G, p) == s,"path() found a wrong path.");
|
||||
check(pathTarget(G, p) == t,"path() found a wrong path.");
|
||||
|
||||
for(ArcIt e(G); e!=INVALID; ++e) {
|
||||
Node u=G.source(e);
|
||||
Node v=G.target(e);
|
||||
check( !dijkstra_test.reached(u) ||
|
||||
(dijkstra_test.dist(v) - dijkstra_test.dist(u) <= length[e]),
|
||||
"Wrong output. dist(target)-dist(source)-arc_length=" <<
|
||||
dijkstra_test.dist(v) - dijkstra_test.dist(u) - length[e]);
|
||||
}
|
||||
|
||||
for(NodeIt v(G); v!=INVALID; ++v) {
|
||||
if (dijkstra_test.reached(v)) {
|
||||
check(v==s || dijkstra_test.predArc(v)!=INVALID, "Wrong tree.");
|
||||
if (dijkstra_test.predArc(v)!=INVALID ) {
|
||||
Arc e=dijkstra_test.predArc(v);
|
||||
Node u=G.source(e);
|
||||
check(u==dijkstra_test.predNode(v),"Wrong tree.");
|
||||
check(dijkstra_test.dist(v) - dijkstra_test.dist(u) == length[e],
|
||||
"Wrong distance! Difference: " <<
|
||||
std::abs(dijkstra_test.dist(v)-dijkstra_test.dist(u)-length[e]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
NullMap<Node,Arc> myPredMap;
|
||||
dijkstra(G,length).predMap(myPredMap).run(s);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
checkDijkstra<ListDigraph>();
|
||||
checkDijkstra<SmartDigraph>();
|
||||
return 0;
|
||||
}
|
||||
87
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/dim_test.cc
vendored
Normal file
87
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/dim_test.cc
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/dim2.h>
|
||||
#include <iostream>
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace lemon;
|
||||
|
||||
int main()
|
||||
{
|
||||
typedef dim2::Point<int> Point;
|
||||
|
||||
Point p;
|
||||
check(p.size()==2, "Wrong dim2::Point initialization.");
|
||||
|
||||
Point a(1,2);
|
||||
Point b(3,4);
|
||||
check(a[0]==1 && a[1]==2, "Wrong dim2::Point initialization.");
|
||||
|
||||
p = a+b;
|
||||
check(p.x==4 && p.y==6, "Wrong dim2::Point addition.");
|
||||
|
||||
p = a-b;
|
||||
check(p.x==-2 && p.y==-2, "Wrong dim2::Point subtraction.");
|
||||
|
||||
check(a.normSquare()==5,"Wrong dim2::Point norm calculation.");
|
||||
check(a*b==11, "Wrong dim2::Point scalar product.");
|
||||
|
||||
int l=2;
|
||||
p = a*l;
|
||||
check(p.x==2 && p.y==4, "Wrong dim2::Point multiplication by a scalar.");
|
||||
|
||||
p = b/l;
|
||||
check(p.x==1 && p.y==2, "Wrong dim2::Point division by a scalar.");
|
||||
|
||||
typedef dim2::Box<int> Box;
|
||||
Box box1;
|
||||
check(box1.empty(), "Wrong empty() in dim2::Box.");
|
||||
|
||||
box1.add(a);
|
||||
check(!box1.empty(), "Wrong empty() in dim2::Box.");
|
||||
box1.add(b);
|
||||
|
||||
check(box1.left()==1 && box1.bottom()==2 &&
|
||||
box1.right()==3 && box1.top()==4,
|
||||
"Wrong addition of points to dim2::Box.");
|
||||
|
||||
check(box1.inside(Point(2,3)), "Wrong inside() in dim2::Box.");
|
||||
check(box1.inside(Point(1,3)), "Wrong inside() in dim2::Box.");
|
||||
check(!box1.inside(Point(0,3)), "Wrong inside() in dim2::Box.");
|
||||
|
||||
Box box2(Point(2,2));
|
||||
check(!box2.empty(), "Wrong empty() in dim2::Box.");
|
||||
|
||||
box2.bottomLeft(Point(2,0));
|
||||
box2.topRight(Point(5,3));
|
||||
Box box3 = box1 & box2;
|
||||
check(!box3.empty() &&
|
||||
box3.left()==2 && box3.bottom()==2 &&
|
||||
box3.right()==3 && box3.top()==3,
|
||||
"Wrong intersection of two dim2::Box objects.");
|
||||
|
||||
box1.add(box2);
|
||||
check(!box1.empty() &&
|
||||
box1.left()==1 && box1.bottom()==0 &&
|
||||
box1.right()==5 && box1.top()==4,
|
||||
"Wrong addition of two dim2::Box objects.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
396
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/edge_set_test.cc
vendored
Normal file
396
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/edge_set_test.cc
vendored
Normal file
@@ -0,0 +1,396 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include <lemon/concepts/digraph.h>
|
||||
#include <lemon/concepts/graph.h>
|
||||
#include <lemon/concept_check.h>
|
||||
|
||||
#include <lemon/list_graph.h>
|
||||
|
||||
#include <lemon/edge_set.h>
|
||||
|
||||
#include "graph_test.h"
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
void checkSmartArcSet() {
|
||||
checkConcept<concepts::Digraph, SmartArcSet<ListDigraph> >();
|
||||
|
||||
typedef ListDigraph Digraph;
|
||||
typedef SmartArcSet<Digraph> ArcSet;
|
||||
|
||||
Digraph digraph;
|
||||
Digraph::Node
|
||||
n1 = digraph.addNode(),
|
||||
n2 = digraph.addNode();
|
||||
|
||||
Digraph::Arc ga1 = digraph.addArc(n1, n2);
|
||||
::lemon::ignore_unused_variable_warning(ga1);
|
||||
|
||||
ArcSet arc_set(digraph);
|
||||
|
||||
Digraph::Arc ga2 = digraph.addArc(n2, n1);
|
||||
::lemon::ignore_unused_variable_warning(ga2);
|
||||
|
||||
checkGraphNodeList(arc_set, 2);
|
||||
checkGraphArcList(arc_set, 0);
|
||||
|
||||
Digraph::Node
|
||||
n3 = digraph.addNode();
|
||||
checkGraphNodeList(arc_set, 3);
|
||||
checkGraphArcList(arc_set, 0);
|
||||
|
||||
ArcSet::Arc a1 = arc_set.addArc(n1, n2);
|
||||
check(arc_set.source(a1) == n1 && arc_set.target(a1) == n2, "Wrong arc");
|
||||
checkGraphNodeList(arc_set, 3);
|
||||
checkGraphArcList(arc_set, 1);
|
||||
|
||||
checkGraphOutArcList(arc_set, n1, 1);
|
||||
checkGraphOutArcList(arc_set, n2, 0);
|
||||
checkGraphOutArcList(arc_set, n3, 0);
|
||||
|
||||
checkGraphInArcList(arc_set, n1, 0);
|
||||
checkGraphInArcList(arc_set, n2, 1);
|
||||
checkGraphInArcList(arc_set, n3, 0);
|
||||
|
||||
checkGraphConArcList(arc_set, 1);
|
||||
|
||||
ArcSet::Arc a2 = arc_set.addArc(n2, n1),
|
||||
a3 = arc_set.addArc(n2, n3),
|
||||
a4 = arc_set.addArc(n2, n3);
|
||||
::lemon::ignore_unused_variable_warning(a2,a3,a4);
|
||||
|
||||
checkGraphNodeList(arc_set, 3);
|
||||
checkGraphArcList(arc_set, 4);
|
||||
|
||||
checkGraphOutArcList(arc_set, n1, 1);
|
||||
checkGraphOutArcList(arc_set, n2, 3);
|
||||
checkGraphOutArcList(arc_set, n3, 0);
|
||||
|
||||
checkGraphInArcList(arc_set, n1, 1);
|
||||
checkGraphInArcList(arc_set, n2, 1);
|
||||
checkGraphInArcList(arc_set, n3, 2);
|
||||
|
||||
checkGraphConArcList(arc_set, 4);
|
||||
|
||||
checkNodeIds(arc_set);
|
||||
checkArcIds(arc_set);
|
||||
checkGraphNodeMap(arc_set);
|
||||
checkGraphArcMap(arc_set);
|
||||
|
||||
check(arc_set.valid(), "Wrong validity");
|
||||
digraph.erase(n1);
|
||||
check(!arc_set.valid(), "Wrong validity");
|
||||
}
|
||||
|
||||
void checkListArcSet() {
|
||||
checkConcept<concepts::Digraph, SmartArcSet<ListDigraph> >();
|
||||
|
||||
typedef ListDigraph Digraph;
|
||||
typedef ListArcSet<Digraph> ArcSet;
|
||||
|
||||
Digraph digraph;
|
||||
Digraph::Node
|
||||
n1 = digraph.addNode(),
|
||||
n2 = digraph.addNode();
|
||||
|
||||
Digraph::Arc ga1 = digraph.addArc(n1, n2);
|
||||
::lemon::ignore_unused_variable_warning(ga1);
|
||||
|
||||
ArcSet arc_set(digraph);
|
||||
|
||||
Digraph::Arc ga2 = digraph.addArc(n2, n1);
|
||||
::lemon::ignore_unused_variable_warning(ga2);
|
||||
|
||||
checkGraphNodeList(arc_set, 2);
|
||||
checkGraphArcList(arc_set, 0);
|
||||
|
||||
Digraph::Node
|
||||
n3 = digraph.addNode();
|
||||
checkGraphNodeList(arc_set, 3);
|
||||
checkGraphArcList(arc_set, 0);
|
||||
|
||||
ArcSet::Arc a1 = arc_set.addArc(n1, n2);
|
||||
check(arc_set.source(a1) == n1 && arc_set.target(a1) == n2, "Wrong arc");
|
||||
checkGraphNodeList(arc_set, 3);
|
||||
checkGraphArcList(arc_set, 1);
|
||||
|
||||
checkGraphOutArcList(arc_set, n1, 1);
|
||||
checkGraphOutArcList(arc_set, n2, 0);
|
||||
checkGraphOutArcList(arc_set, n3, 0);
|
||||
|
||||
checkGraphInArcList(arc_set, n1, 0);
|
||||
checkGraphInArcList(arc_set, n2, 1);
|
||||
checkGraphInArcList(arc_set, n3, 0);
|
||||
|
||||
checkGraphConArcList(arc_set, 1);
|
||||
|
||||
ArcSet::Arc a2 = arc_set.addArc(n2, n1),
|
||||
a3 = arc_set.addArc(n2, n3),
|
||||
a4 = arc_set.addArc(n2, n3);
|
||||
::lemon::ignore_unused_variable_warning(a2,a3,a4);
|
||||
|
||||
checkGraphNodeList(arc_set, 3);
|
||||
checkGraphArcList(arc_set, 4);
|
||||
|
||||
checkGraphOutArcList(arc_set, n1, 1);
|
||||
checkGraphOutArcList(arc_set, n2, 3);
|
||||
checkGraphOutArcList(arc_set, n3, 0);
|
||||
|
||||
checkGraphInArcList(arc_set, n1, 1);
|
||||
checkGraphInArcList(arc_set, n2, 1);
|
||||
checkGraphInArcList(arc_set, n3, 2);
|
||||
|
||||
checkGraphConArcList(arc_set, 4);
|
||||
|
||||
checkNodeIds(arc_set);
|
||||
checkArcIds(arc_set);
|
||||
checkGraphNodeMap(arc_set);
|
||||
checkGraphArcMap(arc_set);
|
||||
|
||||
digraph.erase(n1);
|
||||
|
||||
checkGraphNodeList(arc_set, 2);
|
||||
checkGraphArcList(arc_set, 2);
|
||||
|
||||
checkGraphOutArcList(arc_set, n2, 2);
|
||||
checkGraphOutArcList(arc_set, n3, 0);
|
||||
|
||||
checkGraphInArcList(arc_set, n2, 0);
|
||||
checkGraphInArcList(arc_set, n3, 2);
|
||||
|
||||
checkNodeIds(arc_set);
|
||||
checkArcIds(arc_set);
|
||||
checkGraphNodeMap(arc_set);
|
||||
checkGraphArcMap(arc_set);
|
||||
|
||||
checkGraphConArcList(arc_set, 2);
|
||||
}
|
||||
|
||||
void checkSmartEdgeSet() {
|
||||
checkConcept<concepts::Digraph, SmartEdgeSet<ListDigraph> >();
|
||||
|
||||
typedef ListDigraph Digraph;
|
||||
typedef SmartEdgeSet<Digraph> EdgeSet;
|
||||
|
||||
Digraph digraph;
|
||||
Digraph::Node
|
||||
n1 = digraph.addNode(),
|
||||
n2 = digraph.addNode();
|
||||
|
||||
Digraph::Arc ga1 = digraph.addArc(n1, n2);
|
||||
::lemon::ignore_unused_variable_warning(ga1);
|
||||
|
||||
EdgeSet edge_set(digraph);
|
||||
|
||||
Digraph::Arc ga2 = digraph.addArc(n2, n1);
|
||||
::lemon::ignore_unused_variable_warning(ga2);
|
||||
|
||||
checkGraphNodeList(edge_set, 2);
|
||||
checkGraphArcList(edge_set, 0);
|
||||
checkGraphEdgeList(edge_set, 0);
|
||||
|
||||
Digraph::Node
|
||||
n3 = digraph.addNode();
|
||||
checkGraphNodeList(edge_set, 3);
|
||||
checkGraphArcList(edge_set, 0);
|
||||
checkGraphEdgeList(edge_set, 0);
|
||||
|
||||
EdgeSet::Edge e1 = edge_set.addEdge(n1, n2);
|
||||
check((edge_set.u(e1) == n1 && edge_set.v(e1) == n2) ||
|
||||
(edge_set.v(e1) == n1 && edge_set.u(e1) == n2), "Wrong edge");
|
||||
checkGraphNodeList(edge_set, 3);
|
||||
checkGraphArcList(edge_set, 2);
|
||||
checkGraphEdgeList(edge_set, 1);
|
||||
|
||||
checkGraphOutArcList(edge_set, n1, 1);
|
||||
checkGraphOutArcList(edge_set, n2, 1);
|
||||
checkGraphOutArcList(edge_set, n3, 0);
|
||||
|
||||
checkGraphInArcList(edge_set, n1, 1);
|
||||
checkGraphInArcList(edge_set, n2, 1);
|
||||
checkGraphInArcList(edge_set, n3, 0);
|
||||
|
||||
checkGraphIncEdgeList(edge_set, n1, 1);
|
||||
checkGraphIncEdgeList(edge_set, n2, 1);
|
||||
checkGraphIncEdgeList(edge_set, n3, 0);
|
||||
|
||||
checkGraphConEdgeList(edge_set, 1);
|
||||
checkGraphConArcList(edge_set, 2);
|
||||
|
||||
EdgeSet::Edge e2 = edge_set.addEdge(n2, n1),
|
||||
e3 = edge_set.addEdge(n2, n3),
|
||||
e4 = edge_set.addEdge(n2, n3);
|
||||
::lemon::ignore_unused_variable_warning(e2,e3,e4);
|
||||
|
||||
checkGraphNodeList(edge_set, 3);
|
||||
checkGraphEdgeList(edge_set, 4);
|
||||
|
||||
checkGraphOutArcList(edge_set, n1, 2);
|
||||
checkGraphOutArcList(edge_set, n2, 4);
|
||||
checkGraphOutArcList(edge_set, n3, 2);
|
||||
|
||||
checkGraphInArcList(edge_set, n1, 2);
|
||||
checkGraphInArcList(edge_set, n2, 4);
|
||||
checkGraphInArcList(edge_set, n3, 2);
|
||||
|
||||
checkGraphIncEdgeList(edge_set, n1, 2);
|
||||
checkGraphIncEdgeList(edge_set, n2, 4);
|
||||
checkGraphIncEdgeList(edge_set, n3, 2);
|
||||
|
||||
checkGraphConEdgeList(edge_set, 4);
|
||||
checkGraphConArcList(edge_set, 8);
|
||||
|
||||
checkArcDirections(edge_set);
|
||||
|
||||
checkNodeIds(edge_set);
|
||||
checkArcIds(edge_set);
|
||||
checkEdgeIds(edge_set);
|
||||
checkGraphNodeMap(edge_set);
|
||||
checkGraphArcMap(edge_set);
|
||||
checkGraphEdgeMap(edge_set);
|
||||
|
||||
check(edge_set.valid(), "Wrong validity");
|
||||
digraph.erase(n1);
|
||||
check(!edge_set.valid(), "Wrong validity");
|
||||
}
|
||||
|
||||
void checkListEdgeSet() {
|
||||
checkConcept<concepts::Digraph, ListEdgeSet<ListDigraph> >();
|
||||
|
||||
typedef ListDigraph Digraph;
|
||||
typedef ListEdgeSet<Digraph> EdgeSet;
|
||||
|
||||
Digraph digraph;
|
||||
Digraph::Node
|
||||
n1 = digraph.addNode(),
|
||||
n2 = digraph.addNode();
|
||||
|
||||
Digraph::Arc ga1 = digraph.addArc(n1, n2);
|
||||
::lemon::ignore_unused_variable_warning(ga1);
|
||||
|
||||
EdgeSet edge_set(digraph);
|
||||
|
||||
Digraph::Arc ga2 = digraph.addArc(n2, n1);
|
||||
::lemon::ignore_unused_variable_warning(ga2);
|
||||
|
||||
checkGraphNodeList(edge_set, 2);
|
||||
checkGraphArcList(edge_set, 0);
|
||||
checkGraphEdgeList(edge_set, 0);
|
||||
|
||||
Digraph::Node
|
||||
n3 = digraph.addNode();
|
||||
checkGraphNodeList(edge_set, 3);
|
||||
checkGraphArcList(edge_set, 0);
|
||||
checkGraphEdgeList(edge_set, 0);
|
||||
|
||||
EdgeSet::Edge e1 = edge_set.addEdge(n1, n2);
|
||||
check((edge_set.u(e1) == n1 && edge_set.v(e1) == n2) ||
|
||||
(edge_set.v(e1) == n1 && edge_set.u(e1) == n2), "Wrong edge");
|
||||
checkGraphNodeList(edge_set, 3);
|
||||
checkGraphArcList(edge_set, 2);
|
||||
checkGraphEdgeList(edge_set, 1);
|
||||
|
||||
checkGraphOutArcList(edge_set, n1, 1);
|
||||
checkGraphOutArcList(edge_set, n2, 1);
|
||||
checkGraphOutArcList(edge_set, n3, 0);
|
||||
|
||||
checkGraphInArcList(edge_set, n1, 1);
|
||||
checkGraphInArcList(edge_set, n2, 1);
|
||||
checkGraphInArcList(edge_set, n3, 0);
|
||||
|
||||
checkGraphIncEdgeList(edge_set, n1, 1);
|
||||
checkGraphIncEdgeList(edge_set, n2, 1);
|
||||
checkGraphIncEdgeList(edge_set, n3, 0);
|
||||
|
||||
checkGraphConEdgeList(edge_set, 1);
|
||||
checkGraphConArcList(edge_set, 2);
|
||||
|
||||
EdgeSet::Edge e2 = edge_set.addEdge(n2, n1),
|
||||
e3 = edge_set.addEdge(n2, n3),
|
||||
e4 = edge_set.addEdge(n2, n3);
|
||||
::lemon::ignore_unused_variable_warning(e2,e3,e4);
|
||||
|
||||
checkGraphNodeList(edge_set, 3);
|
||||
checkGraphEdgeList(edge_set, 4);
|
||||
|
||||
checkGraphOutArcList(edge_set, n1, 2);
|
||||
checkGraphOutArcList(edge_set, n2, 4);
|
||||
checkGraphOutArcList(edge_set, n3, 2);
|
||||
|
||||
checkGraphInArcList(edge_set, n1, 2);
|
||||
checkGraphInArcList(edge_set, n2, 4);
|
||||
checkGraphInArcList(edge_set, n3, 2);
|
||||
|
||||
checkGraphIncEdgeList(edge_set, n1, 2);
|
||||
checkGraphIncEdgeList(edge_set, n2, 4);
|
||||
checkGraphIncEdgeList(edge_set, n3, 2);
|
||||
|
||||
checkGraphConEdgeList(edge_set, 4);
|
||||
checkGraphConArcList(edge_set, 8);
|
||||
|
||||
checkArcDirections(edge_set);
|
||||
|
||||
checkNodeIds(edge_set);
|
||||
checkArcIds(edge_set);
|
||||
checkEdgeIds(edge_set);
|
||||
checkGraphNodeMap(edge_set);
|
||||
checkGraphArcMap(edge_set);
|
||||
checkGraphEdgeMap(edge_set);
|
||||
|
||||
digraph.erase(n1);
|
||||
|
||||
checkGraphNodeList(edge_set, 2);
|
||||
checkGraphArcList(edge_set, 4);
|
||||
checkGraphEdgeList(edge_set, 2);
|
||||
|
||||
checkGraphOutArcList(edge_set, n2, 2);
|
||||
checkGraphOutArcList(edge_set, n3, 2);
|
||||
|
||||
checkGraphInArcList(edge_set, n2, 2);
|
||||
checkGraphInArcList(edge_set, n3, 2);
|
||||
|
||||
checkGraphIncEdgeList(edge_set, n2, 2);
|
||||
checkGraphIncEdgeList(edge_set, n3, 2);
|
||||
|
||||
checkNodeIds(edge_set);
|
||||
checkArcIds(edge_set);
|
||||
checkEdgeIds(edge_set);
|
||||
checkGraphNodeMap(edge_set);
|
||||
checkGraphArcMap(edge_set);
|
||||
checkGraphEdgeMap(edge_set);
|
||||
|
||||
checkGraphConEdgeList(edge_set, 2);
|
||||
checkGraphConArcList(edge_set, 4);
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
checkSmartArcSet();
|
||||
checkListArcSet();
|
||||
checkSmartEdgeSet();
|
||||
checkListEdgeSet();
|
||||
|
||||
return 0;
|
||||
}
|
||||
90
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/error_test.cc
vendored
Normal file
90
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/error_test.cc
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <lemon/error.h>
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
#ifdef LEMON_ENABLE_ASSERTS
|
||||
#undef LEMON_ENABLE_ASSERTS
|
||||
#endif
|
||||
|
||||
#ifdef LEMON_DISABLE_ASSERTS
|
||||
#undef LEMON_DISABLE_ASSERTS
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
|
||||
//checking disabled asserts
|
||||
#define LEMON_DISABLE_ASSERTS
|
||||
#include <lemon/assert.h>
|
||||
|
||||
void no_assertion_text_disable() {
|
||||
LEMON_ASSERT(true, "This is a fault message");
|
||||
}
|
||||
|
||||
void assertion_text_disable() {
|
||||
LEMON_ASSERT(false, "This is a fault message");
|
||||
}
|
||||
|
||||
void check_assertion_disable() {
|
||||
no_assertion_text_disable();
|
||||
assertion_text_disable();
|
||||
}
|
||||
#undef LEMON_DISABLE_ASSERTS
|
||||
|
||||
//checking custom assert handler
|
||||
#define LEMON_ASSERT_CUSTOM
|
||||
|
||||
static int cnt = 0;
|
||||
void my_assert_handler(const char*, int, const char*,
|
||||
const char*, const char*) {
|
||||
++cnt;
|
||||
}
|
||||
|
||||
#define LEMON_CUSTOM_ASSERT_HANDLER my_assert_handler
|
||||
#include <lemon/assert.h>
|
||||
|
||||
void no_assertion_text_custom() {
|
||||
LEMON_ASSERT(true, "This is a fault message");
|
||||
}
|
||||
|
||||
void assertion_text_custom() {
|
||||
LEMON_ASSERT(false, "This is a fault message");
|
||||
}
|
||||
|
||||
void check_assertion_custom() {
|
||||
no_assertion_text_custom();
|
||||
assertion_text_custom();
|
||||
check(cnt == 1, "The custom assert handler does not work");
|
||||
}
|
||||
|
||||
#undef LEMON_ASSERT_CUSTOM
|
||||
|
||||
|
||||
int main() {
|
||||
check_assertion_disable();
|
||||
check_assertion_custom();
|
||||
|
||||
return 0;
|
||||
}
|
||||
225
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/euler_test.cc
vendored
Normal file
225
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/euler_test.cc
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/euler.h>
|
||||
#include <lemon/list_graph.h>
|
||||
#include <lemon/adaptors.h>
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
template <typename Digraph>
|
||||
void checkDiEulerIt(const Digraph& g,
|
||||
const typename Digraph::Node& start = INVALID)
|
||||
{
|
||||
typename Digraph::template ArcMap<int> visitationNumber(g, 0);
|
||||
|
||||
DiEulerIt<Digraph> e(g, start);
|
||||
if (e == INVALID) return;
|
||||
typename Digraph::Node firstNode = g.source(e);
|
||||
typename Digraph::Node lastNode = g.target(e);
|
||||
if (start != INVALID) {
|
||||
check(firstNode == start, "checkDiEulerIt: Wrong first node");
|
||||
}
|
||||
|
||||
for (; e != INVALID; ++e) {
|
||||
if (e != INVALID) lastNode = g.target(e);
|
||||
++visitationNumber[e];
|
||||
}
|
||||
|
||||
check(firstNode == lastNode,
|
||||
"checkDiEulerIt: First and last nodes are not the same");
|
||||
|
||||
for (typename Digraph::ArcIt a(g); a != INVALID; ++a)
|
||||
{
|
||||
check(visitationNumber[a] == 1,
|
||||
"checkDiEulerIt: Not visited or multiple times visited arc found");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void checkEulerIt(const Graph& g,
|
||||
const typename Graph::Node& start = INVALID)
|
||||
{
|
||||
typename Graph::template EdgeMap<int> visitationNumber(g, 0);
|
||||
|
||||
EulerIt<Graph> e(g, start);
|
||||
if (e == INVALID) return;
|
||||
typename Graph::Node firstNode = g.source(typename Graph::Arc(e));
|
||||
typename Graph::Node lastNode = g.target(typename Graph::Arc(e));
|
||||
if (start != INVALID) {
|
||||
check(firstNode == start, "checkEulerIt: Wrong first node");
|
||||
}
|
||||
|
||||
for (; e != INVALID; ++e) {
|
||||
if (e != INVALID) lastNode = g.target(typename Graph::Arc(e));
|
||||
++visitationNumber[e];
|
||||
}
|
||||
|
||||
check(firstNode == lastNode,
|
||||
"checkEulerIt: First and last nodes are not the same");
|
||||
|
||||
for (typename Graph::EdgeIt e(g); e != INVALID; ++e)
|
||||
{
|
||||
check(visitationNumber[e] == 1,
|
||||
"checkEulerIt: Not visited or multiple times visited edge found");
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
typedef ListDigraph Digraph;
|
||||
typedef Undirector<Digraph> Graph;
|
||||
|
||||
{
|
||||
Digraph d;
|
||||
Graph g(d);
|
||||
|
||||
checkDiEulerIt(d);
|
||||
checkDiEulerIt(g);
|
||||
checkEulerIt(g);
|
||||
|
||||
check(eulerian(d), "This graph is Eulerian");
|
||||
check(eulerian(g), "This graph is Eulerian");
|
||||
}
|
||||
{
|
||||
Digraph d;
|
||||
Graph g(d);
|
||||
Digraph::Node n = d.addNode();
|
||||
::lemon::ignore_unused_variable_warning(n);
|
||||
|
||||
checkDiEulerIt(d);
|
||||
checkDiEulerIt(g);
|
||||
checkEulerIt(g);
|
||||
|
||||
check(eulerian(d), "This graph is Eulerian");
|
||||
check(eulerian(g), "This graph is Eulerian");
|
||||
}
|
||||
{
|
||||
Digraph d;
|
||||
Graph g(d);
|
||||
Digraph::Node n = d.addNode();
|
||||
d.addArc(n, n);
|
||||
|
||||
checkDiEulerIt(d);
|
||||
checkDiEulerIt(g);
|
||||
checkEulerIt(g);
|
||||
|
||||
check(eulerian(d), "This graph is Eulerian");
|
||||
check(eulerian(g), "This graph is Eulerian");
|
||||
}
|
||||
{
|
||||
Digraph d;
|
||||
Graph g(d);
|
||||
Digraph::Node n1 = d.addNode();
|
||||
Digraph::Node n2 = d.addNode();
|
||||
Digraph::Node n3 = d.addNode();
|
||||
|
||||
d.addArc(n1, n2);
|
||||
d.addArc(n2, n1);
|
||||
d.addArc(n2, n3);
|
||||
d.addArc(n3, n2);
|
||||
|
||||
checkDiEulerIt(d);
|
||||
checkDiEulerIt(d, n2);
|
||||
checkDiEulerIt(g);
|
||||
checkDiEulerIt(g, n2);
|
||||
checkEulerIt(g);
|
||||
checkEulerIt(g, n2);
|
||||
|
||||
check(eulerian(d), "This graph is Eulerian");
|
||||
check(eulerian(g), "This graph is Eulerian");
|
||||
}
|
||||
{
|
||||
Digraph d;
|
||||
Graph g(d);
|
||||
Digraph::Node n1 = d.addNode();
|
||||
Digraph::Node n2 = d.addNode();
|
||||
Digraph::Node n3 = d.addNode();
|
||||
Digraph::Node n4 = d.addNode();
|
||||
Digraph::Node n5 = d.addNode();
|
||||
Digraph::Node n6 = d.addNode();
|
||||
|
||||
d.addArc(n1, n2);
|
||||
d.addArc(n2, n4);
|
||||
d.addArc(n1, n3);
|
||||
d.addArc(n3, n4);
|
||||
d.addArc(n4, n1);
|
||||
d.addArc(n3, n5);
|
||||
d.addArc(n5, n2);
|
||||
d.addArc(n4, n6);
|
||||
d.addArc(n2, n6);
|
||||
d.addArc(n6, n1);
|
||||
d.addArc(n6, n3);
|
||||
|
||||
checkDiEulerIt(d);
|
||||
checkDiEulerIt(d, n1);
|
||||
checkDiEulerIt(d, n5);
|
||||
|
||||
checkDiEulerIt(g);
|
||||
checkDiEulerIt(g, n1);
|
||||
checkDiEulerIt(g, n5);
|
||||
checkEulerIt(g);
|
||||
checkEulerIt(g, n1);
|
||||
checkEulerIt(g, n5);
|
||||
|
||||
check(eulerian(d), "This graph is Eulerian");
|
||||
check(eulerian(g), "This graph is Eulerian");
|
||||
}
|
||||
{
|
||||
Digraph d;
|
||||
Graph g(d);
|
||||
Digraph::Node n0 = d.addNode();
|
||||
Digraph::Node n1 = d.addNode();
|
||||
Digraph::Node n2 = d.addNode();
|
||||
Digraph::Node n3 = d.addNode();
|
||||
Digraph::Node n4 = d.addNode();
|
||||
Digraph::Node n5 = d.addNode();
|
||||
::lemon::ignore_unused_variable_warning(n0,n4,n5);
|
||||
|
||||
d.addArc(n1, n2);
|
||||
d.addArc(n2, n3);
|
||||
d.addArc(n3, n1);
|
||||
|
||||
checkDiEulerIt(d);
|
||||
checkDiEulerIt(d, n2);
|
||||
|
||||
checkDiEulerIt(g);
|
||||
checkDiEulerIt(g, n2);
|
||||
checkEulerIt(g);
|
||||
checkEulerIt(g, n2);
|
||||
|
||||
check(!eulerian(d), "This graph is not Eulerian");
|
||||
check(!eulerian(g), "This graph is not Eulerian");
|
||||
}
|
||||
{
|
||||
Digraph d;
|
||||
Graph g(d);
|
||||
Digraph::Node n1 = d.addNode();
|
||||
Digraph::Node n2 = d.addNode();
|
||||
Digraph::Node n3 = d.addNode();
|
||||
|
||||
d.addArc(n1, n2);
|
||||
d.addArc(n2, n3);
|
||||
|
||||
check(!eulerian(d), "This graph is not Eulerian");
|
||||
check(!eulerian(g), "This graph is not Eulerian");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
527
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/fractional_matching_test.cc
vendored
Normal file
527
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/fractional_matching_test.cc
vendored
Normal file
@@ -0,0 +1,527 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <lemon/fractional_matching.h>
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/concepts/graph.h>
|
||||
#include <lemon/concepts/maps.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/math.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace lemon;
|
||||
|
||||
GRAPH_TYPEDEFS(SmartGraph);
|
||||
|
||||
|
||||
const int lgfn = 4;
|
||||
const std::string lgf[lgfn] = {
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"6\n"
|
||||
"7\n"
|
||||
"@edges\n"
|
||||
" label weight\n"
|
||||
"7 4 0 984\n"
|
||||
"0 7 1 73\n"
|
||||
"7 1 2 204\n"
|
||||
"2 3 3 583\n"
|
||||
"2 7 4 565\n"
|
||||
"2 1 5 582\n"
|
||||
"0 4 6 551\n"
|
||||
"2 5 7 385\n"
|
||||
"1 5 8 561\n"
|
||||
"5 3 9 484\n"
|
||||
"7 5 10 904\n"
|
||||
"3 6 11 47\n"
|
||||
"7 6 12 888\n"
|
||||
"3 0 13 747\n"
|
||||
"6 1 14 310\n",
|
||||
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"6\n"
|
||||
"7\n"
|
||||
"@edges\n"
|
||||
" label weight\n"
|
||||
"2 5 0 710\n"
|
||||
"0 5 1 241\n"
|
||||
"2 4 2 856\n"
|
||||
"2 6 3 762\n"
|
||||
"4 1 4 747\n"
|
||||
"6 1 5 962\n"
|
||||
"4 7 6 723\n"
|
||||
"1 7 7 661\n"
|
||||
"2 3 8 376\n"
|
||||
"1 0 9 416\n"
|
||||
"6 7 10 391\n",
|
||||
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"6\n"
|
||||
"7\n"
|
||||
"@edges\n"
|
||||
" label weight\n"
|
||||
"6 2 0 553\n"
|
||||
"0 7 1 653\n"
|
||||
"6 3 2 22\n"
|
||||
"4 7 3 846\n"
|
||||
"7 2 4 981\n"
|
||||
"7 6 5 250\n"
|
||||
"5 2 6 539\n",
|
||||
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"@edges\n"
|
||||
" label weight\n"
|
||||
"0 0 0 100\n"
|
||||
};
|
||||
|
||||
void checkMaxFractionalMatchingCompile()
|
||||
{
|
||||
typedef concepts::Graph Graph;
|
||||
typedef Graph::Node Node;
|
||||
typedef Graph::Edge Edge;
|
||||
|
||||
Graph g;
|
||||
Node n;
|
||||
Edge e;
|
||||
|
||||
MaxFractionalMatching<Graph> mat_test(g);
|
||||
const MaxFractionalMatching<Graph>&
|
||||
const_mat_test = mat_test;
|
||||
|
||||
mat_test.init();
|
||||
mat_test.start();
|
||||
mat_test.start(true);
|
||||
mat_test.startPerfect();
|
||||
mat_test.startPerfect(true);
|
||||
mat_test.run();
|
||||
mat_test.run(true);
|
||||
mat_test.runPerfect();
|
||||
mat_test.runPerfect(true);
|
||||
|
||||
const_mat_test.matchingSize();
|
||||
const_mat_test.matching(e);
|
||||
const_mat_test.matching(n);
|
||||
const MaxFractionalMatching<Graph>::MatchingMap& mmap =
|
||||
const_mat_test.matchingMap();
|
||||
e = mmap[n];
|
||||
|
||||
const_mat_test.barrier(n);
|
||||
}
|
||||
|
||||
void checkMaxWeightedFractionalMatchingCompile()
|
||||
{
|
||||
typedef concepts::Graph Graph;
|
||||
typedef Graph::Node Node;
|
||||
typedef Graph::Edge Edge;
|
||||
typedef Graph::EdgeMap<int> WeightMap;
|
||||
|
||||
Graph g;
|
||||
Node n;
|
||||
Edge e;
|
||||
WeightMap w(g);
|
||||
|
||||
MaxWeightedFractionalMatching<Graph> mat_test(g, w);
|
||||
const MaxWeightedFractionalMatching<Graph>&
|
||||
const_mat_test = mat_test;
|
||||
|
||||
mat_test.init();
|
||||
mat_test.start();
|
||||
mat_test.run();
|
||||
|
||||
const_mat_test.matchingWeight();
|
||||
const_mat_test.matchingSize();
|
||||
const_mat_test.matching(e);
|
||||
const_mat_test.matching(n);
|
||||
const MaxWeightedFractionalMatching<Graph>::MatchingMap& mmap =
|
||||
const_mat_test.matchingMap();
|
||||
e = mmap[n];
|
||||
|
||||
const_mat_test.dualValue();
|
||||
const_mat_test.nodeValue(n);
|
||||
}
|
||||
|
||||
void checkMaxWeightedPerfectFractionalMatchingCompile()
|
||||
{
|
||||
typedef concepts::Graph Graph;
|
||||
typedef Graph::Node Node;
|
||||
typedef Graph::Edge Edge;
|
||||
typedef Graph::EdgeMap<int> WeightMap;
|
||||
|
||||
Graph g;
|
||||
Node n;
|
||||
Edge e;
|
||||
WeightMap w(g);
|
||||
|
||||
MaxWeightedPerfectFractionalMatching<Graph> mat_test(g, w);
|
||||
const MaxWeightedPerfectFractionalMatching<Graph>&
|
||||
const_mat_test = mat_test;
|
||||
|
||||
mat_test.init();
|
||||
mat_test.start();
|
||||
mat_test.run();
|
||||
|
||||
const_mat_test.matchingWeight();
|
||||
const_mat_test.matching(e);
|
||||
const_mat_test.matching(n);
|
||||
const MaxWeightedPerfectFractionalMatching<Graph>::MatchingMap& mmap =
|
||||
const_mat_test.matchingMap();
|
||||
e = mmap[n];
|
||||
|
||||
const_mat_test.dualValue();
|
||||
const_mat_test.nodeValue(n);
|
||||
}
|
||||
|
||||
void checkFractionalMatching(const SmartGraph& graph,
|
||||
const MaxFractionalMatching<SmartGraph>& mfm,
|
||||
bool allow_loops = true) {
|
||||
int pv = 0;
|
||||
for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
|
||||
int indeg = 0;
|
||||
for (InArcIt a(graph, n); a != INVALID; ++a) {
|
||||
if (mfm.matching(graph.source(a)) == a) {
|
||||
++indeg;
|
||||
}
|
||||
}
|
||||
if (mfm.matching(n) != INVALID) {
|
||||
check(indeg == 1, "Invalid matching");
|
||||
++pv;
|
||||
} else {
|
||||
check(indeg == 0, "Invalid matching");
|
||||
}
|
||||
}
|
||||
check(pv == mfm.matchingSize(), "Wrong matching size");
|
||||
|
||||
for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
|
||||
check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
|
||||
(e == mfm.matching(graph.v(e)) ? 1 : 0) ==
|
||||
mfm.matching(e), "Invalid matching");
|
||||
}
|
||||
|
||||
SmartGraph::NodeMap<bool> processed(graph, false);
|
||||
for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
|
||||
if (processed[n]) continue;
|
||||
processed[n] = true;
|
||||
if (mfm.matching(n) == INVALID) continue;
|
||||
int num = 1;
|
||||
Node v = graph.target(mfm.matching(n));
|
||||
while (v != n) {
|
||||
processed[v] = true;
|
||||
++num;
|
||||
v = graph.target(mfm.matching(v));
|
||||
}
|
||||
check(num == 2 || num % 2 == 1, "Wrong cycle size");
|
||||
check(allow_loops || num != 1, "Wrong cycle size");
|
||||
}
|
||||
|
||||
int anum = 0, bnum = 0;
|
||||
SmartGraph::NodeMap<bool> neighbours(graph, false);
|
||||
for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
|
||||
if (!mfm.barrier(n)) continue;
|
||||
++anum;
|
||||
for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) {
|
||||
Node u = graph.source(a);
|
||||
if (!allow_loops && u == n) continue;
|
||||
if (!neighbours[u]) {
|
||||
neighbours[u] = true;
|
||||
++bnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
check(anum - bnum + mfm.matchingSize() == countNodes(graph),
|
||||
"Wrong barrier");
|
||||
}
|
||||
|
||||
void checkPerfectFractionalMatching(const SmartGraph& graph,
|
||||
const MaxFractionalMatching<SmartGraph>& mfm,
|
||||
bool perfect, bool allow_loops = true) {
|
||||
if (perfect) {
|
||||
for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
|
||||
int indeg = 0;
|
||||
for (InArcIt a(graph, n); a != INVALID; ++a) {
|
||||
if (mfm.matching(graph.source(a)) == a) {
|
||||
++indeg;
|
||||
}
|
||||
}
|
||||
check(mfm.matching(n) != INVALID, "Invalid matching");
|
||||
check(indeg == 1, "Invalid matching");
|
||||
}
|
||||
for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
|
||||
check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
|
||||
(e == mfm.matching(graph.v(e)) ? 1 : 0) ==
|
||||
mfm.matching(e), "Invalid matching");
|
||||
}
|
||||
} else {
|
||||
int anum = 0, bnum = 0;
|
||||
SmartGraph::NodeMap<bool> neighbours(graph, false);
|
||||
for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
|
||||
if (!mfm.barrier(n)) continue;
|
||||
++anum;
|
||||
for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) {
|
||||
Node u = graph.source(a);
|
||||
if (!allow_loops && u == n) continue;
|
||||
if (!neighbours[u]) {
|
||||
neighbours[u] = true;
|
||||
++bnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
check(anum - bnum > 0, "Wrong barrier");
|
||||
}
|
||||
}
|
||||
|
||||
void checkWeightedFractionalMatching(const SmartGraph& graph,
|
||||
const SmartGraph::EdgeMap<int>& weight,
|
||||
const MaxWeightedFractionalMatching<SmartGraph>& mwfm,
|
||||
bool allow_loops = true) {
|
||||
for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
|
||||
if (graph.u(e) == graph.v(e) && !allow_loops) continue;
|
||||
int rw = mwfm.nodeValue(graph.u(e)) + mwfm.nodeValue(graph.v(e))
|
||||
- weight[e] * mwfm.dualScale;
|
||||
|
||||
check(rw >= 0, "Negative reduced weight");
|
||||
check(rw == 0 || !mwfm.matching(e),
|
||||
"Non-zero reduced weight on matching edge");
|
||||
}
|
||||
|
||||
int pv = 0;
|
||||
for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
|
||||
int indeg = 0;
|
||||
for (InArcIt a(graph, n); a != INVALID; ++a) {
|
||||
if (mwfm.matching(graph.source(a)) == a) {
|
||||
++indeg;
|
||||
}
|
||||
}
|
||||
check(indeg <= 1, "Invalid matching");
|
||||
if (mwfm.matching(n) != INVALID) {
|
||||
check(mwfm.nodeValue(n) >= 0, "Invalid node value");
|
||||
check(indeg == 1, "Invalid matching");
|
||||
pv += weight[mwfm.matching(n)];
|
||||
SmartGraph::Node o = graph.target(mwfm.matching(n));
|
||||
::lemon::ignore_unused_variable_warning(o);
|
||||
} else {
|
||||
check(mwfm.nodeValue(n) == 0, "Invalid matching");
|
||||
check(indeg == 0, "Invalid matching");
|
||||
}
|
||||
}
|
||||
|
||||
for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
|
||||
check((e == mwfm.matching(graph.u(e)) ? 1 : 0) +
|
||||
(e == mwfm.matching(graph.v(e)) ? 1 : 0) ==
|
||||
mwfm.matching(e), "Invalid matching");
|
||||
}
|
||||
|
||||
int dv = 0;
|
||||
for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
|
||||
dv += mwfm.nodeValue(n);
|
||||
}
|
||||
|
||||
check(pv * mwfm.dualScale == dv * 2, "Wrong duality");
|
||||
|
||||
SmartGraph::NodeMap<bool> processed(graph, false);
|
||||
for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
|
||||
if (processed[n]) continue;
|
||||
processed[n] = true;
|
||||
if (mwfm.matching(n) == INVALID) continue;
|
||||
int num = 1;
|
||||
Node v = graph.target(mwfm.matching(n));
|
||||
while (v != n) {
|
||||
processed[v] = true;
|
||||
++num;
|
||||
v = graph.target(mwfm.matching(v));
|
||||
}
|
||||
check(num == 2 || num % 2 == 1, "Wrong cycle size");
|
||||
check(allow_loops || num != 1, "Wrong cycle size");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void checkWeightedPerfectFractionalMatching(const SmartGraph& graph,
|
||||
const SmartGraph::EdgeMap<int>& weight,
|
||||
const MaxWeightedPerfectFractionalMatching<SmartGraph>& mwpfm,
|
||||
bool allow_loops = true) {
|
||||
for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
|
||||
if (graph.u(e) == graph.v(e) && !allow_loops) continue;
|
||||
int rw = mwpfm.nodeValue(graph.u(e)) + mwpfm.nodeValue(graph.v(e))
|
||||
- weight[e] * mwpfm.dualScale;
|
||||
|
||||
check(rw >= 0, "Negative reduced weight");
|
||||
check(rw == 0 || !mwpfm.matching(e),
|
||||
"Non-zero reduced weight on matching edge");
|
||||
}
|
||||
|
||||
int pv = 0;
|
||||
for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
|
||||
int indeg = 0;
|
||||
for (InArcIt a(graph, n); a != INVALID; ++a) {
|
||||
if (mwpfm.matching(graph.source(a)) == a) {
|
||||
++indeg;
|
||||
}
|
||||
}
|
||||
check(mwpfm.matching(n) != INVALID, "Invalid perfect matching");
|
||||
check(indeg == 1, "Invalid perfect matching");
|
||||
pv += weight[mwpfm.matching(n)];
|
||||
SmartGraph::Node o = graph.target(mwpfm.matching(n));
|
||||
::lemon::ignore_unused_variable_warning(o);
|
||||
}
|
||||
|
||||
for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
|
||||
check((e == mwpfm.matching(graph.u(e)) ? 1 : 0) +
|
||||
(e == mwpfm.matching(graph.v(e)) ? 1 : 0) ==
|
||||
mwpfm.matching(e), "Invalid matching");
|
||||
}
|
||||
|
||||
int dv = 0;
|
||||
for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
|
||||
dv += mwpfm.nodeValue(n);
|
||||
}
|
||||
|
||||
check(pv * mwpfm.dualScale == dv * 2, "Wrong duality");
|
||||
|
||||
SmartGraph::NodeMap<bool> processed(graph, false);
|
||||
for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
|
||||
if (processed[n]) continue;
|
||||
processed[n] = true;
|
||||
if (mwpfm.matching(n) == INVALID) continue;
|
||||
int num = 1;
|
||||
Node v = graph.target(mwpfm.matching(n));
|
||||
while (v != n) {
|
||||
processed[v] = true;
|
||||
++num;
|
||||
v = graph.target(mwpfm.matching(v));
|
||||
}
|
||||
check(num == 2 || num % 2 == 1, "Wrong cycle size");
|
||||
check(allow_loops || num != 1, "Wrong cycle size");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
for (int i = 0; i < lgfn; ++i) {
|
||||
SmartGraph graph;
|
||||
SmartGraph::EdgeMap<int> weight(graph);
|
||||
|
||||
istringstream lgfs(lgf[i]);
|
||||
graphReader(graph, lgfs).
|
||||
edgeMap("weight", weight).run();
|
||||
|
||||
bool perfect_with_loops;
|
||||
{
|
||||
MaxFractionalMatching<SmartGraph> mfm(graph, true);
|
||||
mfm.run();
|
||||
checkFractionalMatching(graph, mfm, true);
|
||||
perfect_with_loops = mfm.matchingSize() == countNodes(graph);
|
||||
}
|
||||
|
||||
bool perfect_without_loops;
|
||||
{
|
||||
MaxFractionalMatching<SmartGraph> mfm(graph, false);
|
||||
mfm.run();
|
||||
checkFractionalMatching(graph, mfm, false);
|
||||
perfect_without_loops = mfm.matchingSize() == countNodes(graph);
|
||||
}
|
||||
|
||||
{
|
||||
MaxFractionalMatching<SmartGraph> mfm(graph, true);
|
||||
bool result = mfm.runPerfect();
|
||||
checkPerfectFractionalMatching(graph, mfm, result, true);
|
||||
check(result == perfect_with_loops, "Wrong perfect matching");
|
||||
}
|
||||
|
||||
{
|
||||
MaxFractionalMatching<SmartGraph> mfm(graph, false);
|
||||
bool result = mfm.runPerfect();
|
||||
checkPerfectFractionalMatching(graph, mfm, result, false);
|
||||
check(result == perfect_without_loops, "Wrong perfect matching");
|
||||
}
|
||||
|
||||
{
|
||||
MaxWeightedFractionalMatching<SmartGraph> mwfm(graph, weight, true);
|
||||
mwfm.run();
|
||||
checkWeightedFractionalMatching(graph, weight, mwfm, true);
|
||||
}
|
||||
|
||||
{
|
||||
MaxWeightedFractionalMatching<SmartGraph> mwfm(graph, weight, false);
|
||||
mwfm.run();
|
||||
checkWeightedFractionalMatching(graph, weight, mwfm, false);
|
||||
}
|
||||
|
||||
{
|
||||
MaxWeightedPerfectFractionalMatching<SmartGraph> mwpfm(graph, weight,
|
||||
true);
|
||||
bool perfect = mwpfm.run();
|
||||
check(perfect == (mwpfm.matchingSize() == countNodes(graph)),
|
||||
"Perfect matching found");
|
||||
check(perfect == perfect_with_loops, "Wrong perfect matching");
|
||||
|
||||
if (perfect) {
|
||||
checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, true);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
MaxWeightedPerfectFractionalMatching<SmartGraph> mwpfm(graph, weight,
|
||||
false);
|
||||
bool perfect = mwpfm.run();
|
||||
check(perfect == (mwpfm.matchingSize() == countNodes(graph)),
|
||||
"Perfect matching found");
|
||||
check(perfect == perfect_without_loops, "Wrong perfect matching");
|
||||
|
||||
if (perfect) {
|
||||
checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
142
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/gomory_hu_test.cc
vendored
Normal file
142
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/gomory_hu_test.cc
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "test_tools.h"
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/concepts/graph.h>
|
||||
#include <lemon/concepts/maps.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/gomory_hu.h>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
using namespace lemon;
|
||||
|
||||
typedef SmartGraph Graph;
|
||||
|
||||
char test_lgf[] =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"@arcs\n"
|
||||
" label capacity\n"
|
||||
"0 1 0 1\n"
|
||||
"1 2 1 1\n"
|
||||
"2 3 2 1\n"
|
||||
"0 3 4 5\n"
|
||||
"0 3 5 10\n"
|
||||
"0 3 6 7\n"
|
||||
"4 2 7 1\n"
|
||||
"@attributes\n"
|
||||
"source 0\n"
|
||||
"target 3\n";
|
||||
|
||||
void checkGomoryHuCompile()
|
||||
{
|
||||
typedef int Value;
|
||||
typedef concepts::Graph Graph;
|
||||
|
||||
typedef Graph::Node Node;
|
||||
typedef Graph::Edge Edge;
|
||||
typedef concepts::ReadMap<Edge, Value> CapMap;
|
||||
typedef concepts::ReadWriteMap<Node, bool> CutMap;
|
||||
|
||||
Graph g;
|
||||
Node n;
|
||||
CapMap cap;
|
||||
CutMap cut;
|
||||
Value v;
|
||||
int d;
|
||||
::lemon::ignore_unused_variable_warning(v,d);
|
||||
|
||||
GomoryHu<Graph, CapMap> gh_test(g, cap);
|
||||
const GomoryHu<Graph, CapMap>&
|
||||
const_gh_test = gh_test;
|
||||
|
||||
gh_test.run();
|
||||
|
||||
n = const_gh_test.predNode(n);
|
||||
v = const_gh_test.predValue(n);
|
||||
d = const_gh_test.rootDist(n);
|
||||
v = const_gh_test.minCutValue(n, n);
|
||||
v = const_gh_test.minCutMap(n, n, cut);
|
||||
}
|
||||
|
||||
GRAPH_TYPEDEFS(Graph);
|
||||
typedef Graph::EdgeMap<int> IntEdgeMap;
|
||||
typedef Graph::NodeMap<bool> BoolNodeMap;
|
||||
|
||||
int cutValue(const Graph& graph, const BoolNodeMap& cut,
|
||||
const IntEdgeMap& capacity) {
|
||||
|
||||
int sum = 0;
|
||||
for (EdgeIt e(graph); e != INVALID; ++e) {
|
||||
Node s = graph.u(e);
|
||||
Node t = graph.v(e);
|
||||
|
||||
if (cut[s] != cut[t]) {
|
||||
sum += capacity[e];
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
Graph graph;
|
||||
IntEdgeMap capacity(graph);
|
||||
|
||||
std::istringstream input(test_lgf);
|
||||
GraphReader<Graph>(graph, input).
|
||||
edgeMap("capacity", capacity).run();
|
||||
|
||||
GomoryHu<Graph> ght(graph, capacity);
|
||||
ght.run();
|
||||
|
||||
for (NodeIt u(graph); u != INVALID; ++u) {
|
||||
for (NodeIt v(graph); v != u; ++v) {
|
||||
Preflow<Graph, IntEdgeMap> pf(graph, capacity, u, v);
|
||||
pf.runMinCut();
|
||||
BoolNodeMap cm(graph);
|
||||
ght.minCutMap(u, v, cm);
|
||||
check(pf.flowValue() == ght.minCutValue(u, v), "Wrong cut 1");
|
||||
check(cm[u] != cm[v], "Wrong cut 2");
|
||||
check(pf.flowValue() == cutValue(graph, cm, capacity), "Wrong cut 3");
|
||||
|
||||
int sum=0;
|
||||
for(GomoryHu<Graph>::MinCutEdgeIt a(ght, u, v);a!=INVALID;++a)
|
||||
sum+=capacity[a];
|
||||
check(sum == ght.minCutValue(u, v), "Problem with MinCutEdgeIt");
|
||||
|
||||
sum=0;
|
||||
for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,true);n!=INVALID;++n)
|
||||
sum++;
|
||||
for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,false);n!=INVALID;++n)
|
||||
sum++;
|
||||
check(sum == countNodes(graph), "Problem with MinCutNodeIt");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
388
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/graph_copy_test.cc
vendored
Normal file
388
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/graph_copy_test.cc
vendored
Normal file
@@ -0,0 +1,388 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/list_graph.h>
|
||||
#include <lemon/static_graph.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/error.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace lemon;
|
||||
|
||||
template <typename GR>
|
||||
void digraph_copy_test() {
|
||||
const int nn = 10;
|
||||
|
||||
// Build a digraph
|
||||
SmartDigraph from;
|
||||
SmartDigraph::NodeMap<int> fnm(from);
|
||||
SmartDigraph::ArcMap<int> fam(from);
|
||||
SmartDigraph::Node fn = INVALID;
|
||||
SmartDigraph::Arc fa = INVALID;
|
||||
|
||||
std::vector<SmartDigraph::Node> fnv;
|
||||
for (int i = 0; i < nn; ++i) {
|
||||
SmartDigraph::Node node = from.addNode();
|
||||
fnv.push_back(node);
|
||||
fnm[node] = i * i;
|
||||
if (i == 0) fn = node;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nn; ++i) {
|
||||
for (int j = 0; j < nn; ++j) {
|
||||
SmartDigraph::Arc arc = from.addArc(fnv[i], fnv[j]);
|
||||
fam[arc] = i + j * j;
|
||||
if (i == 0 && j == 0) fa = arc;
|
||||
}
|
||||
}
|
||||
|
||||
// Test digraph copy
|
||||
GR to;
|
||||
typename GR::template NodeMap<int> tnm(to);
|
||||
typename GR::template ArcMap<int> tam(to);
|
||||
typename GR::Node tn;
|
||||
typename GR::Arc ta;
|
||||
|
||||
SmartDigraph::NodeMap<typename GR::Node> nr(from);
|
||||
SmartDigraph::ArcMap<typename GR::Arc> er(from);
|
||||
|
||||
typename GR::template NodeMap<SmartDigraph::Node> ncr(to);
|
||||
typename GR::template ArcMap<SmartDigraph::Arc> ecr(to);
|
||||
|
||||
digraphCopy(from, to).
|
||||
nodeMap(fnm, tnm).arcMap(fam, tam).
|
||||
nodeRef(nr).arcRef(er).
|
||||
nodeCrossRef(ncr).arcCrossRef(ecr).
|
||||
node(fn, tn).arc(fa, ta).run();
|
||||
|
||||
check(countNodes(from) == countNodes(to), "Wrong copy.");
|
||||
check(countArcs(from) == countArcs(to), "Wrong copy.");
|
||||
|
||||
for (SmartDigraph::NodeIt it(from); it != INVALID; ++it) {
|
||||
check(ncr[nr[it]] == it, "Wrong copy.");
|
||||
check(fnm[it] == tnm[nr[it]], "Wrong copy.");
|
||||
}
|
||||
|
||||
for (SmartDigraph::ArcIt it(from); it != INVALID; ++it) {
|
||||
check(ecr[er[it]] == it, "Wrong copy.");
|
||||
check(fam[it] == tam[er[it]], "Wrong copy.");
|
||||
check(nr[from.source(it)] == to.source(er[it]), "Wrong copy.");
|
||||
check(nr[from.target(it)] == to.target(er[it]), "Wrong copy.");
|
||||
}
|
||||
|
||||
for (typename GR::NodeIt it(to); it != INVALID; ++it) {
|
||||
check(nr[ncr[it]] == it, "Wrong copy.");
|
||||
}
|
||||
|
||||
for (typename GR::ArcIt it(to); it != INVALID; ++it) {
|
||||
check(er[ecr[it]] == it, "Wrong copy.");
|
||||
}
|
||||
check(tn == nr[fn], "Wrong copy.");
|
||||
check(ta == er[fa], "Wrong copy.");
|
||||
|
||||
// Test repeated copy
|
||||
digraphCopy(from, to).run();
|
||||
|
||||
check(countNodes(from) == countNodes(to), "Wrong copy.");
|
||||
check(countArcs(from) == countArcs(to), "Wrong copy.");
|
||||
}
|
||||
|
||||
template <typename GR>
|
||||
void graph_copy_test() {
|
||||
const int nn = 10;
|
||||
|
||||
// Build a graph
|
||||
SmartGraph from;
|
||||
SmartGraph::NodeMap<int> fnm(from);
|
||||
SmartGraph::ArcMap<int> fam(from);
|
||||
SmartGraph::EdgeMap<int> fem(from);
|
||||
SmartGraph::Node fn = INVALID;
|
||||
SmartGraph::Arc fa = INVALID;
|
||||
SmartGraph::Edge fe = INVALID;
|
||||
|
||||
std::vector<SmartGraph::Node> fnv;
|
||||
for (int i = 0; i < nn; ++i) {
|
||||
SmartGraph::Node node = from.addNode();
|
||||
fnv.push_back(node);
|
||||
fnm[node] = i * i;
|
||||
if (i == 0) fn = node;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nn; ++i) {
|
||||
for (int j = 0; j < nn; ++j) {
|
||||
SmartGraph::Edge edge = from.addEdge(fnv[i], fnv[j]);
|
||||
fem[edge] = i * i + j * j;
|
||||
fam[from.direct(edge, true)] = i + j * j;
|
||||
fam[from.direct(edge, false)] = i * i + j;
|
||||
if (i == 0 && j == 0) fa = from.direct(edge, true);
|
||||
if (i == 0 && j == 0) fe = edge;
|
||||
}
|
||||
}
|
||||
|
||||
// Test graph copy
|
||||
GR to;
|
||||
typename GR::template NodeMap<int> tnm(to);
|
||||
typename GR::template ArcMap<int> tam(to);
|
||||
typename GR::template EdgeMap<int> tem(to);
|
||||
typename GR::Node tn;
|
||||
typename GR::Arc ta;
|
||||
typename GR::Edge te;
|
||||
|
||||
SmartGraph::NodeMap<typename GR::Node> nr(from);
|
||||
SmartGraph::ArcMap<typename GR::Arc> ar(from);
|
||||
SmartGraph::EdgeMap<typename GR::Edge> er(from);
|
||||
|
||||
typename GR::template NodeMap<SmartGraph::Node> ncr(to);
|
||||
typename GR::template ArcMap<SmartGraph::Arc> acr(to);
|
||||
typename GR::template EdgeMap<SmartGraph::Edge> ecr(to);
|
||||
|
||||
graphCopy(from, to).
|
||||
nodeMap(fnm, tnm).arcMap(fam, tam).edgeMap(fem, tem).
|
||||
nodeRef(nr).arcRef(ar).edgeRef(er).
|
||||
nodeCrossRef(ncr).arcCrossRef(acr).edgeCrossRef(ecr).
|
||||
node(fn, tn).arc(fa, ta).edge(fe, te).run();
|
||||
|
||||
check(countNodes(from) == countNodes(to), "Wrong copy.");
|
||||
check(countEdges(from) == countEdges(to), "Wrong copy.");
|
||||
check(countArcs(from) == countArcs(to), "Wrong copy.");
|
||||
|
||||
for (SmartGraph::NodeIt it(from); it != INVALID; ++it) {
|
||||
check(ncr[nr[it]] == it, "Wrong copy.");
|
||||
check(fnm[it] == tnm[nr[it]], "Wrong copy.");
|
||||
}
|
||||
|
||||
for (SmartGraph::ArcIt it(from); it != INVALID; ++it) {
|
||||
check(acr[ar[it]] == it, "Wrong copy.");
|
||||
check(fam[it] == tam[ar[it]], "Wrong copy.");
|
||||
check(nr[from.source(it)] == to.source(ar[it]), "Wrong copy.");
|
||||
check(nr[from.target(it)] == to.target(ar[it]), "Wrong copy.");
|
||||
}
|
||||
|
||||
for (SmartGraph::EdgeIt it(from); it != INVALID; ++it) {
|
||||
check(ecr[er[it]] == it, "Wrong copy.");
|
||||
check(fem[it] == tem[er[it]], "Wrong copy.");
|
||||
check(nr[from.u(it)] == to.u(er[it]) || nr[from.u(it)] == to.v(er[it]),
|
||||
"Wrong copy.");
|
||||
check(nr[from.v(it)] == to.u(er[it]) || nr[from.v(it)] == to.v(er[it]),
|
||||
"Wrong copy.");
|
||||
check((from.u(it) != from.v(it)) == (to.u(er[it]) != to.v(er[it])),
|
||||
"Wrong copy.");
|
||||
}
|
||||
|
||||
for (typename GR::NodeIt it(to); it != INVALID; ++it) {
|
||||
check(nr[ncr[it]] == it, "Wrong copy.");
|
||||
}
|
||||
|
||||
for (typename GR::ArcIt it(to); it != INVALID; ++it) {
|
||||
check(ar[acr[it]] == it, "Wrong copy.");
|
||||
}
|
||||
for (typename GR::EdgeIt it(to); it != INVALID; ++it) {
|
||||
check(er[ecr[it]] == it, "Wrong copy.");
|
||||
}
|
||||
check(tn == nr[fn], "Wrong copy.");
|
||||
check(ta == ar[fa], "Wrong copy.");
|
||||
check(te == er[fe], "Wrong copy.");
|
||||
|
||||
// Test repeated copy
|
||||
graphCopy(from, to).run();
|
||||
|
||||
check(countNodes(from) == countNodes(to), "Wrong copy.");
|
||||
check(countEdges(from) == countEdges(to), "Wrong copy.");
|
||||
check(countArcs(from) == countArcs(to), "Wrong copy.");
|
||||
}
|
||||
|
||||
template <typename GR>
|
||||
void bpgraph_copy_test() {
|
||||
const int nn = 10;
|
||||
|
||||
// Build a graph
|
||||
SmartBpGraph from;
|
||||
SmartBpGraph::NodeMap<int> fnm(from);
|
||||
SmartBpGraph::RedNodeMap<int> frnm(from);
|
||||
SmartBpGraph::BlueNodeMap<int> fbnm(from);
|
||||
SmartBpGraph::ArcMap<int> fam(from);
|
||||
SmartBpGraph::EdgeMap<int> fem(from);
|
||||
SmartBpGraph::Node fn = INVALID;
|
||||
SmartBpGraph::RedNode frn = INVALID;
|
||||
SmartBpGraph::BlueNode fbn = INVALID;
|
||||
SmartBpGraph::Arc fa = INVALID;
|
||||
SmartBpGraph::Edge fe = INVALID;
|
||||
|
||||
std::vector<SmartBpGraph::RedNode> frnv;
|
||||
for (int i = 0; i < nn; ++i) {
|
||||
SmartBpGraph::RedNode node = from.addRedNode();
|
||||
frnv.push_back(node);
|
||||
fnm[node] = i * i;
|
||||
frnm[node] = i + i;
|
||||
if (i == 0) {
|
||||
fn = node;
|
||||
frn = node;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<SmartBpGraph::BlueNode> fbnv;
|
||||
for (int i = 0; i < nn; ++i) {
|
||||
SmartBpGraph::BlueNode node = from.addBlueNode();
|
||||
fbnv.push_back(node);
|
||||
fnm[node] = i * i;
|
||||
fbnm[node] = i + i;
|
||||
if (i == 0) fbn = node;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nn; ++i) {
|
||||
for (int j = 0; j < nn; ++j) {
|
||||
SmartBpGraph::Edge edge = from.addEdge(frnv[i], fbnv[j]);
|
||||
fem[edge] = i * i + j * j;
|
||||
fam[from.direct(edge, true)] = i + j * j;
|
||||
fam[from.direct(edge, false)] = i * i + j;
|
||||
if (i == 0 && j == 0) fa = from.direct(edge, true);
|
||||
if (i == 0 && j == 0) fe = edge;
|
||||
}
|
||||
}
|
||||
|
||||
// Test graph copy
|
||||
GR to;
|
||||
typename GR::template NodeMap<int> tnm(to);
|
||||
typename GR::template RedNodeMap<int> trnm(to);
|
||||
typename GR::template BlueNodeMap<int> tbnm(to);
|
||||
typename GR::template ArcMap<int> tam(to);
|
||||
typename GR::template EdgeMap<int> tem(to);
|
||||
typename GR::Node tn;
|
||||
typename GR::RedNode trn;
|
||||
typename GR::BlueNode tbn;
|
||||
typename GR::Arc ta;
|
||||
typename GR::Edge te;
|
||||
|
||||
SmartBpGraph::NodeMap<typename GR::Node> nr(from);
|
||||
SmartBpGraph::RedNodeMap<typename GR::RedNode> rnr(from);
|
||||
SmartBpGraph::BlueNodeMap<typename GR::BlueNode> bnr(from);
|
||||
SmartBpGraph::ArcMap<typename GR::Arc> ar(from);
|
||||
SmartBpGraph::EdgeMap<typename GR::Edge> er(from);
|
||||
|
||||
typename GR::template NodeMap<SmartBpGraph::Node> ncr(to);
|
||||
typename GR::template RedNodeMap<SmartBpGraph::RedNode> rncr(to);
|
||||
typename GR::template BlueNodeMap<SmartBpGraph::BlueNode> bncr(to);
|
||||
typename GR::template ArcMap<SmartBpGraph::Arc> acr(to);
|
||||
typename GR::template EdgeMap<SmartBpGraph::Edge> ecr(to);
|
||||
|
||||
bpGraphCopy(from, to).
|
||||
nodeMap(fnm, tnm).
|
||||
redNodeMap(frnm, trnm).blueNodeMap(fbnm, tbnm).
|
||||
arcMap(fam, tam).edgeMap(fem, tem).
|
||||
nodeRef(nr).redRef(rnr).blueRef(bnr).
|
||||
arcRef(ar).edgeRef(er).
|
||||
nodeCrossRef(ncr).redCrossRef(rncr).blueCrossRef(bncr).
|
||||
arcCrossRef(acr).edgeCrossRef(ecr).
|
||||
node(fn, tn).redNode(frn, trn).blueNode(fbn, tbn).
|
||||
arc(fa, ta).edge(fe, te).run();
|
||||
|
||||
check(countNodes(from) == countNodes(to), "Wrong copy.");
|
||||
check(countRedNodes(from) == countRedNodes(to), "Wrong copy.");
|
||||
check(countBlueNodes(from) == countBlueNodes(to), "Wrong copy.");
|
||||
check(countEdges(from) == countEdges(to), "Wrong copy.");
|
||||
check(countArcs(from) == countArcs(to), "Wrong copy.");
|
||||
|
||||
for (SmartBpGraph::NodeIt it(from); it != INVALID; ++it) {
|
||||
check(ncr[nr[it]] == it, "Wrong copy.");
|
||||
check(fnm[it] == tnm[nr[it]], "Wrong copy.");
|
||||
}
|
||||
|
||||
for (SmartBpGraph::RedNodeIt it(from); it != INVALID; ++it) {
|
||||
check(ncr[nr[it]] == it, "Wrong copy.");
|
||||
check(fnm[it] == tnm[nr[it]], "Wrong copy.");
|
||||
check(rnr[it] == nr[it], "Wrong copy.");
|
||||
check(rncr[rnr[it]] == it, "Wrong copy.");
|
||||
check(frnm[it] == trnm[rnr[it]], "Wrong copy.");
|
||||
check(to.red(rnr[it]), "Wrong copy.");
|
||||
}
|
||||
|
||||
for (SmartBpGraph::BlueNodeIt it(from); it != INVALID; ++it) {
|
||||
check(ncr[nr[it]] == it, "Wrong copy.");
|
||||
check(fnm[it] == tnm[nr[it]], "Wrong copy.");
|
||||
check(bnr[it] == nr[it], "Wrong copy.");
|
||||
check(bncr[bnr[it]] == it, "Wrong copy.");
|
||||
check(fbnm[it] == tbnm[bnr[it]], "Wrong copy.");
|
||||
check(to.blue(bnr[it]), "Wrong copy.");
|
||||
}
|
||||
|
||||
for (SmartBpGraph::ArcIt it(from); it != INVALID; ++it) {
|
||||
check(acr[ar[it]] == it, "Wrong copy.");
|
||||
check(fam[it] == tam[ar[it]], "Wrong copy.");
|
||||
check(nr[from.source(it)] == to.source(ar[it]), "Wrong copy.");
|
||||
check(nr[from.target(it)] == to.target(ar[it]), "Wrong copy.");
|
||||
}
|
||||
|
||||
for (SmartBpGraph::EdgeIt it(from); it != INVALID; ++it) {
|
||||
check(ecr[er[it]] == it, "Wrong copy.");
|
||||
check(fem[it] == tem[er[it]], "Wrong copy.");
|
||||
check(nr[from.u(it)] == to.u(er[it]) || nr[from.u(it)] == to.v(er[it]),
|
||||
"Wrong copy.");
|
||||
check(nr[from.v(it)] == to.u(er[it]) || nr[from.v(it)] == to.v(er[it]),
|
||||
"Wrong copy.");
|
||||
check((from.u(it) != from.v(it)) == (to.u(er[it]) != to.v(er[it])),
|
||||
"Wrong copy.");
|
||||
}
|
||||
|
||||
for (typename GR::NodeIt it(to); it != INVALID; ++it) {
|
||||
check(nr[ncr[it]] == it, "Wrong copy.");
|
||||
}
|
||||
for (typename GR::RedNodeIt it(to); it != INVALID; ++it) {
|
||||
check(rncr[it] == ncr[it], "Wrong copy.");
|
||||
check(rnr[rncr[it]] == it, "Wrong copy.");
|
||||
}
|
||||
for (typename GR::BlueNodeIt it(to); it != INVALID; ++it) {
|
||||
check(bncr[it] == ncr[it], "Wrong copy.");
|
||||
check(bnr[bncr[it]] == it, "Wrong copy.");
|
||||
}
|
||||
for (typename GR::ArcIt it(to); it != INVALID; ++it) {
|
||||
check(ar[acr[it]] == it, "Wrong copy.");
|
||||
}
|
||||
for (typename GR::EdgeIt it(to); it != INVALID; ++it) {
|
||||
check(er[ecr[it]] == it, "Wrong copy.");
|
||||
}
|
||||
check(tn == nr[fn], "Wrong copy.");
|
||||
check(trn == rnr[frn], "Wrong copy.");
|
||||
check(tbn == bnr[fbn], "Wrong copy.");
|
||||
check(ta == ar[fa], "Wrong copy.");
|
||||
check(te == er[fe], "Wrong copy.");
|
||||
|
||||
// Test repeated copy
|
||||
bpGraphCopy(from, to).run();
|
||||
|
||||
check(countNodes(from) == countNodes(to), "Wrong copy.");
|
||||
check(countRedNodes(from) == countRedNodes(to), "Wrong copy.");
|
||||
check(countBlueNodes(from) == countBlueNodes(to), "Wrong copy.");
|
||||
check(countEdges(from) == countEdges(to), "Wrong copy.");
|
||||
check(countArcs(from) == countArcs(to), "Wrong copy.");
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
digraph_copy_test<SmartDigraph>();
|
||||
digraph_copy_test<ListDigraph>();
|
||||
digraph_copy_test<StaticDigraph>();
|
||||
graph_copy_test<SmartGraph>();
|
||||
graph_copy_test<ListGraph>();
|
||||
bpgraph_copy_test<SmartBpGraph>();
|
||||
bpgraph_copy_test<ListBpGraph>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
603
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/graph_test.cc
vendored
Normal file
603
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/graph_test.cc
vendored
Normal file
@@ -0,0 +1,603 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/concepts/graph.h>
|
||||
#include <lemon/list_graph.h>
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/full_graph.h>
|
||||
#include <lemon/grid_graph.h>
|
||||
#include <lemon/hypercube_graph.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
#include "graph_test.h"
|
||||
|
||||
using namespace lemon;
|
||||
using namespace lemon::concepts;
|
||||
|
||||
template <class Graph>
|
||||
void checkGraphBuild() {
|
||||
TEMPLATE_GRAPH_TYPEDEFS(Graph);
|
||||
|
||||
Graph G;
|
||||
checkGraphNodeList(G, 0);
|
||||
checkGraphEdgeList(G, 0);
|
||||
checkGraphArcList(G, 0);
|
||||
|
||||
G.reserveNode(3);
|
||||
G.reserveEdge(3);
|
||||
|
||||
Node
|
||||
n1 = G.addNode(),
|
||||
n2 = G.addNode(),
|
||||
n3 = G.addNode();
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphEdgeList(G, 0);
|
||||
checkGraphArcList(G, 0);
|
||||
|
||||
Edge e1 = G.addEdge(n1, n2);
|
||||
check((G.u(e1) == n1 && G.v(e1) == n2) || (G.u(e1) == n2 && G.v(e1) == n1),
|
||||
"Wrong edge");
|
||||
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphEdgeList(G, 1);
|
||||
checkGraphArcList(G, 2);
|
||||
|
||||
checkGraphIncEdgeArcLists(G, n1, 1);
|
||||
checkGraphIncEdgeArcLists(G, n2, 1);
|
||||
checkGraphIncEdgeArcLists(G, n3, 0);
|
||||
|
||||
checkGraphConEdgeList(G, 1);
|
||||
checkGraphConArcList(G, 2);
|
||||
|
||||
Edge e2 = G.addEdge(n2, n1),
|
||||
e3 = G.addEdge(n2, n3);
|
||||
::lemon::ignore_unused_variable_warning(e2,e3);
|
||||
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphEdgeList(G, 3);
|
||||
checkGraphArcList(G, 6);
|
||||
|
||||
checkGraphIncEdgeArcLists(G, n1, 2);
|
||||
checkGraphIncEdgeArcLists(G, n2, 3);
|
||||
checkGraphIncEdgeArcLists(G, n3, 1);
|
||||
|
||||
checkGraphConEdgeList(G, 3);
|
||||
checkGraphConArcList(G, 6);
|
||||
|
||||
checkArcDirections(G);
|
||||
|
||||
checkNodeIds(G);
|
||||
checkArcIds(G);
|
||||
checkEdgeIds(G);
|
||||
checkGraphNodeMap(G);
|
||||
checkGraphArcMap(G);
|
||||
checkGraphEdgeMap(G);
|
||||
}
|
||||
|
||||
template <class Graph>
|
||||
void checkGraphAlter() {
|
||||
TEMPLATE_GRAPH_TYPEDEFS(Graph);
|
||||
|
||||
Graph G;
|
||||
Node n1 = G.addNode(), n2 = G.addNode(),
|
||||
n3 = G.addNode(), n4 = G.addNode();
|
||||
Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
|
||||
e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
|
||||
e5 = G.addEdge(n4, n3);
|
||||
::lemon::ignore_unused_variable_warning(e1,e3,e4,e5);
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphEdgeList(G, 5);
|
||||
checkGraphArcList(G, 10);
|
||||
|
||||
// Check changeU() and changeV()
|
||||
if (G.u(e2) == n2) {
|
||||
G.changeU(e2, n3);
|
||||
} else {
|
||||
G.changeV(e2, n3);
|
||||
}
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphEdgeList(G, 5);
|
||||
checkGraphArcList(G, 10);
|
||||
|
||||
checkGraphIncEdgeArcLists(G, n1, 3);
|
||||
checkGraphIncEdgeArcLists(G, n2, 2);
|
||||
checkGraphIncEdgeArcLists(G, n3, 3);
|
||||
checkGraphIncEdgeArcLists(G, n4, 2);
|
||||
|
||||
checkGraphConEdgeList(G, 5);
|
||||
checkGraphConArcList(G, 10);
|
||||
|
||||
if (G.u(e2) == n1) {
|
||||
G.changeU(e2, n2);
|
||||
} else {
|
||||
G.changeV(e2, n2);
|
||||
}
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphEdgeList(G, 5);
|
||||
checkGraphArcList(G, 10);
|
||||
|
||||
checkGraphIncEdgeArcLists(G, n1, 2);
|
||||
checkGraphIncEdgeArcLists(G, n2, 3);
|
||||
checkGraphIncEdgeArcLists(G, n3, 3);
|
||||
checkGraphIncEdgeArcLists(G, n4, 2);
|
||||
|
||||
checkGraphConEdgeList(G, 5);
|
||||
checkGraphConArcList(G, 10);
|
||||
|
||||
// Check contract()
|
||||
G.contract(n1, n4, false);
|
||||
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphEdgeList(G, 5);
|
||||
checkGraphArcList(G, 10);
|
||||
|
||||
checkGraphIncEdgeArcLists(G, n1, 4);
|
||||
checkGraphIncEdgeArcLists(G, n2, 3);
|
||||
checkGraphIncEdgeArcLists(G, n3, 3);
|
||||
|
||||
checkGraphConEdgeList(G, 5);
|
||||
checkGraphConArcList(G, 10);
|
||||
|
||||
G.contract(n2, n3);
|
||||
|
||||
checkGraphNodeList(G, 2);
|
||||
checkGraphEdgeList(G, 3);
|
||||
checkGraphArcList(G, 6);
|
||||
|
||||
checkGraphIncEdgeArcLists(G, n1, 4);
|
||||
checkGraphIncEdgeArcLists(G, n2, 2);
|
||||
|
||||
checkGraphConEdgeList(G, 3);
|
||||
checkGraphConArcList(G, 6);
|
||||
}
|
||||
|
||||
template <class Graph>
|
||||
void checkGraphErase() {
|
||||
TEMPLATE_GRAPH_TYPEDEFS(Graph);
|
||||
|
||||
Graph G;
|
||||
Node n1 = G.addNode(), n2 = G.addNode(),
|
||||
n3 = G.addNode(), n4 = G.addNode();
|
||||
Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
|
||||
e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
|
||||
e5 = G.addEdge(n4, n3);
|
||||
::lemon::ignore_unused_variable_warning(e1,e3,e4,e5);
|
||||
|
||||
// Check edge deletion
|
||||
G.erase(e2);
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphEdgeList(G, 4);
|
||||
checkGraphArcList(G, 8);
|
||||
|
||||
checkGraphIncEdgeArcLists(G, n1, 2);
|
||||
checkGraphIncEdgeArcLists(G, n2, 2);
|
||||
checkGraphIncEdgeArcLists(G, n3, 2);
|
||||
checkGraphIncEdgeArcLists(G, n4, 2);
|
||||
|
||||
checkGraphConEdgeList(G, 4);
|
||||
checkGraphConArcList(G, 8);
|
||||
|
||||
// Check node deletion
|
||||
G.erase(n3);
|
||||
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphEdgeList(G, 2);
|
||||
checkGraphArcList(G, 4);
|
||||
|
||||
checkGraphIncEdgeArcLists(G, n1, 2);
|
||||
checkGraphIncEdgeArcLists(G, n2, 1);
|
||||
checkGraphIncEdgeArcLists(G, n4, 1);
|
||||
|
||||
checkGraphConEdgeList(G, 2);
|
||||
checkGraphConArcList(G, 4);
|
||||
}
|
||||
|
||||
|
||||
template <class Graph>
|
||||
void checkGraphSnapshot() {
|
||||
TEMPLATE_GRAPH_TYPEDEFS(Graph);
|
||||
|
||||
Graph G;
|
||||
Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
|
||||
Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
|
||||
e3 = G.addEdge(n2, n3);
|
||||
::lemon::ignore_unused_variable_warning(e1,e2,e3);
|
||||
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphEdgeList(G, 3);
|
||||
checkGraphArcList(G, 6);
|
||||
|
||||
typename Graph::Snapshot snapshot(G);
|
||||
|
||||
Node n = G.addNode();
|
||||
G.addEdge(n3, n);
|
||||
G.addEdge(n, n3);
|
||||
G.addEdge(n3, n2);
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphEdgeList(G, 6);
|
||||
checkGraphArcList(G, 12);
|
||||
|
||||
snapshot.restore();
|
||||
|
||||
checkGraphNodeList(G, 3);
|
||||
checkGraphEdgeList(G, 3);
|
||||
checkGraphArcList(G, 6);
|
||||
|
||||
checkGraphIncEdgeArcLists(G, n1, 2);
|
||||
checkGraphIncEdgeArcLists(G, n2, 3);
|
||||
checkGraphIncEdgeArcLists(G, n3, 1);
|
||||
|
||||
checkGraphConEdgeList(G, 3);
|
||||
checkGraphConArcList(G, 6);
|
||||
|
||||
checkNodeIds(G);
|
||||
checkEdgeIds(G);
|
||||
checkArcIds(G);
|
||||
checkGraphNodeMap(G);
|
||||
checkGraphEdgeMap(G);
|
||||
checkGraphArcMap(G);
|
||||
|
||||
G.addNode();
|
||||
snapshot.save(G);
|
||||
|
||||
G.addEdge(G.addNode(), G.addNode());
|
||||
|
||||
snapshot.restore();
|
||||
snapshot.save(G);
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphEdgeList(G, 3);
|
||||
checkGraphArcList(G, 6);
|
||||
|
||||
G.addEdge(G.addNode(), G.addNode());
|
||||
|
||||
snapshot.restore();
|
||||
|
||||
checkGraphNodeList(G, 4);
|
||||
checkGraphEdgeList(G, 3);
|
||||
checkGraphArcList(G, 6);
|
||||
}
|
||||
|
||||
void checkFullGraph(int num) {
|
||||
typedef FullGraph Graph;
|
||||
GRAPH_TYPEDEFS(Graph);
|
||||
|
||||
Graph G(num);
|
||||
check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
|
||||
"Wrong size");
|
||||
|
||||
G.resize(num);
|
||||
check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
|
||||
"Wrong size");
|
||||
|
||||
checkGraphNodeList(G, num);
|
||||
checkGraphEdgeList(G, num * (num - 1) / 2);
|
||||
|
||||
for (NodeIt n(G); n != INVALID; ++n) {
|
||||
checkGraphOutArcList(G, n, num - 1);
|
||||
checkGraphInArcList(G, n, num - 1);
|
||||
checkGraphIncEdgeList(G, n, num - 1);
|
||||
}
|
||||
|
||||
checkGraphConArcList(G, num * (num - 1));
|
||||
checkGraphConEdgeList(G, num * (num - 1) / 2);
|
||||
|
||||
checkArcDirections(G);
|
||||
|
||||
checkNodeIds(G);
|
||||
checkArcIds(G);
|
||||
checkEdgeIds(G);
|
||||
checkGraphNodeMap(G);
|
||||
checkGraphArcMap(G);
|
||||
checkGraphEdgeMap(G);
|
||||
|
||||
|
||||
for (int i = 0; i < G.nodeNum(); ++i) {
|
||||
check(G.index(G(i)) == i, "Wrong index");
|
||||
}
|
||||
|
||||
for (NodeIt u(G); u != INVALID; ++u) {
|
||||
for (NodeIt v(G); v != INVALID; ++v) {
|
||||
Edge e = G.edge(u, v);
|
||||
Arc a = G.arc(u, v);
|
||||
if (u == v) {
|
||||
check(e == INVALID, "Wrong edge lookup");
|
||||
check(a == INVALID, "Wrong arc lookup");
|
||||
} else {
|
||||
check((G.u(e) == u && G.v(e) == v) ||
|
||||
(G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
|
||||
check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void checkConcepts() {
|
||||
{ // Checking graph components
|
||||
checkConcept<BaseGraphComponent, BaseGraphComponent >();
|
||||
|
||||
checkConcept<IDableGraphComponent<>,
|
||||
IDableGraphComponent<> >();
|
||||
|
||||
checkConcept<IterableGraphComponent<>,
|
||||
IterableGraphComponent<> >();
|
||||
|
||||
checkConcept<MappableGraphComponent<>,
|
||||
MappableGraphComponent<> >();
|
||||
}
|
||||
{ // Checking skeleton graph
|
||||
checkConcept<Graph, Graph>();
|
||||
}
|
||||
{ // Checking ListGraph
|
||||
checkConcept<Graph, ListGraph>();
|
||||
checkConcept<AlterableGraphComponent<>, ListGraph>();
|
||||
checkConcept<ExtendableGraphComponent<>, ListGraph>();
|
||||
checkConcept<ClearableGraphComponent<>, ListGraph>();
|
||||
checkConcept<ErasableGraphComponent<>, ListGraph>();
|
||||
}
|
||||
{ // Checking SmartGraph
|
||||
checkConcept<Graph, SmartGraph>();
|
||||
checkConcept<AlterableGraphComponent<>, SmartGraph>();
|
||||
checkConcept<ExtendableGraphComponent<>, SmartGraph>();
|
||||
checkConcept<ClearableGraphComponent<>, SmartGraph>();
|
||||
}
|
||||
{ // Checking FullGraph
|
||||
checkConcept<Graph, FullGraph>();
|
||||
}
|
||||
{ // Checking GridGraph
|
||||
checkConcept<Graph, GridGraph>();
|
||||
}
|
||||
{ // Checking HypercubeGraph
|
||||
checkConcept<Graph, HypercubeGraph>();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void checkGraphValidity() {
|
||||
TEMPLATE_GRAPH_TYPEDEFS(Graph);
|
||||
Graph g;
|
||||
|
||||
Node
|
||||
n1 = g.addNode(),
|
||||
n2 = g.addNode(),
|
||||
n3 = g.addNode();
|
||||
|
||||
Edge
|
||||
e1 = g.addEdge(n1, n2),
|
||||
e2 = g.addEdge(n2, n3);
|
||||
::lemon::ignore_unused_variable_warning(e2);
|
||||
|
||||
check(g.valid(n1), "Wrong validity check");
|
||||
check(g.valid(e1), "Wrong validity check");
|
||||
check(g.valid(g.direct(e1, true)), "Wrong validity check");
|
||||
|
||||
check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
|
||||
check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
|
||||
check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void checkGraphValidityErase() {
|
||||
TEMPLATE_GRAPH_TYPEDEFS(Graph);
|
||||
Graph g;
|
||||
|
||||
Node
|
||||
n1 = g.addNode(),
|
||||
n2 = g.addNode(),
|
||||
n3 = g.addNode();
|
||||
|
||||
Edge
|
||||
e1 = g.addEdge(n1, n2),
|
||||
e2 = g.addEdge(n2, n3);
|
||||
|
||||
check(g.valid(n1), "Wrong validity check");
|
||||
check(g.valid(e1), "Wrong validity check");
|
||||
check(g.valid(g.direct(e1, true)), "Wrong validity check");
|
||||
|
||||
g.erase(n1);
|
||||
|
||||
check(!g.valid(n1), "Wrong validity check");
|
||||
check(g.valid(n2), "Wrong validity check");
|
||||
check(g.valid(n3), "Wrong validity check");
|
||||
check(!g.valid(e1), "Wrong validity check");
|
||||
check(g.valid(e2), "Wrong validity check");
|
||||
|
||||
check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
|
||||
check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
|
||||
check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
|
||||
}
|
||||
|
||||
void checkGridGraph(int width, int height) {
|
||||
typedef GridGraph Graph;
|
||||
GRAPH_TYPEDEFS(Graph);
|
||||
Graph G(width, height);
|
||||
|
||||
check(G.width() == width, "Wrong column number");
|
||||
check(G.height() == height, "Wrong row number");
|
||||
|
||||
G.resize(width, height);
|
||||
check(G.width() == width, "Wrong column number");
|
||||
check(G.height() == height, "Wrong row number");
|
||||
|
||||
for (int i = 0; i < width; ++i) {
|
||||
for (int j = 0; j < height; ++j) {
|
||||
check(G.col(G(i, j)) == i, "Wrong column");
|
||||
check(G.row(G(i, j)) == j, "Wrong row");
|
||||
check(G.pos(G(i, j)).x == i, "Wrong column");
|
||||
check(G.pos(G(i, j)).y == j, "Wrong row");
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < height; ++j) {
|
||||
for (int i = 0; i < width - 1; ++i) {
|
||||
check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right");
|
||||
check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right");
|
||||
}
|
||||
check(G.right(G(width - 1, j)) == INVALID, "Wrong right");
|
||||
}
|
||||
|
||||
for (int j = 0; j < height; ++j) {
|
||||
for (int i = 1; i < width; ++i) {
|
||||
check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left");
|
||||
check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left");
|
||||
}
|
||||
check(G.left(G(0, j)) == INVALID, "Wrong left");
|
||||
}
|
||||
|
||||
for (int i = 0; i < width; ++i) {
|
||||
for (int j = 0; j < height - 1; ++j) {
|
||||
check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up");
|
||||
check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up");
|
||||
}
|
||||
check(G.up(G(i, height - 1)) == INVALID, "Wrong up");
|
||||
}
|
||||
|
||||
for (int i = 0; i < width; ++i) {
|
||||
for (int j = 1; j < height; ++j) {
|
||||
check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down");
|
||||
check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down");
|
||||
}
|
||||
check(G.down(G(i, 0)) == INVALID, "Wrong down");
|
||||
}
|
||||
|
||||
checkGraphNodeList(G, width * height);
|
||||
checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height);
|
||||
checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
|
||||
|
||||
for (NodeIt n(G); n != INVALID; ++n) {
|
||||
int nb = 4;
|
||||
if (G.col(n) == 0) --nb;
|
||||
if (G.col(n) == width - 1) --nb;
|
||||
if (G.row(n) == 0) --nb;
|
||||
if (G.row(n) == height - 1) --nb;
|
||||
|
||||
checkGraphOutArcList(G, n, nb);
|
||||
checkGraphInArcList(G, n, nb);
|
||||
checkGraphIncEdgeList(G, n, nb);
|
||||
}
|
||||
|
||||
checkArcDirections(G);
|
||||
|
||||
checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
|
||||
checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height);
|
||||
|
||||
checkNodeIds(G);
|
||||
checkArcIds(G);
|
||||
checkEdgeIds(G);
|
||||
checkGraphNodeMap(G);
|
||||
checkGraphArcMap(G);
|
||||
checkGraphEdgeMap(G);
|
||||
|
||||
}
|
||||
|
||||
void checkHypercubeGraph(int dim) {
|
||||
GRAPH_TYPEDEFS(HypercubeGraph);
|
||||
|
||||
HypercubeGraph G(dim);
|
||||
check(G.dimension() == dim, "Wrong dimension");
|
||||
|
||||
G.resize(dim);
|
||||
check(G.dimension() == dim, "Wrong dimension");
|
||||
|
||||
checkGraphNodeList(G, 1 << dim);
|
||||
checkGraphEdgeList(G, dim * (1 << (dim-1)));
|
||||
checkGraphArcList(G, dim * (1 << dim));
|
||||
|
||||
Node n = G.nodeFromId(dim);
|
||||
::lemon::ignore_unused_variable_warning(n);
|
||||
|
||||
for (NodeIt n(G); n != INVALID; ++n) {
|
||||
checkGraphIncEdgeList(G, n, dim);
|
||||
for (IncEdgeIt e(G, n); e != INVALID; ++e) {
|
||||
check( (G.u(e) == n &&
|
||||
G.id(G.v(e)) == (G.id(n) ^ (1 << G.dimension(e)))) ||
|
||||
(G.v(e) == n &&
|
||||
G.id(G.u(e)) == (G.id(n) ^ (1 << G.dimension(e)))),
|
||||
"Wrong edge or wrong dimension");
|
||||
}
|
||||
|
||||
checkGraphOutArcList(G, n, dim);
|
||||
for (OutArcIt a(G, n); a != INVALID; ++a) {
|
||||
check(G.source(a) == n &&
|
||||
G.id(G.target(a)) == (G.id(n) ^ (1 << G.dimension(a))),
|
||||
"Wrong arc or wrong dimension");
|
||||
}
|
||||
|
||||
checkGraphInArcList(G, n, dim);
|
||||
for (InArcIt a(G, n); a != INVALID; ++a) {
|
||||
check(G.target(a) == n &&
|
||||
G.id(G.source(a)) == (G.id(n) ^ (1 << G.dimension(a))),
|
||||
"Wrong arc or wrong dimension");
|
||||
}
|
||||
}
|
||||
|
||||
checkGraphConArcList(G, (1 << dim) * dim);
|
||||
checkGraphConEdgeList(G, dim * (1 << (dim-1)));
|
||||
|
||||
checkArcDirections(G);
|
||||
|
||||
checkNodeIds(G);
|
||||
checkArcIds(G);
|
||||
checkEdgeIds(G);
|
||||
checkGraphNodeMap(G);
|
||||
checkGraphArcMap(G);
|
||||
checkGraphEdgeMap(G);
|
||||
}
|
||||
|
||||
void checkGraphs() {
|
||||
{ // Checking ListGraph
|
||||
checkGraphBuild<ListGraph>();
|
||||
checkGraphAlter<ListGraph>();
|
||||
checkGraphErase<ListGraph>();
|
||||
checkGraphSnapshot<ListGraph>();
|
||||
checkGraphValidityErase<ListGraph>();
|
||||
}
|
||||
{ // Checking SmartGraph
|
||||
checkGraphBuild<SmartGraph>();
|
||||
checkGraphSnapshot<SmartGraph>();
|
||||
checkGraphValidity<SmartGraph>();
|
||||
}
|
||||
{ // Checking FullGraph
|
||||
checkFullGraph(7);
|
||||
checkFullGraph(8);
|
||||
}
|
||||
{ // Checking GridGraph
|
||||
checkGridGraph(5, 8);
|
||||
checkGridGraph(8, 5);
|
||||
checkGridGraph(5, 5);
|
||||
checkGridGraph(0, 0);
|
||||
checkGridGraph(1, 1);
|
||||
}
|
||||
{ // Checking HypercubeGraph
|
||||
checkHypercubeGraph(1);
|
||||
checkHypercubeGraph(2);
|
||||
checkHypercubeGraph(3);
|
||||
checkHypercubeGraph(4);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
checkConcepts();
|
||||
checkGraphs();
|
||||
return 0;
|
||||
}
|
||||
421
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/graph_test.h
vendored
Normal file
421
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/graph_test.h
vendored
Normal file
@@ -0,0 +1,421 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_TEST_GRAPH_TEST_H
|
||||
#define LEMON_TEST_GRAPH_TEST_H
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <lemon/core.h>
|
||||
#include <lemon/maps.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
namespace lemon {
|
||||
|
||||
template<class Graph>
|
||||
void checkGraphNodeList(const Graph &G, int cnt)
|
||||
{
|
||||
typename Graph::NodeIt n(G);
|
||||
for(int i=0;i<cnt;i++) {
|
||||
check(n!=INVALID,"Wrong Node list linking.");
|
||||
++n;
|
||||
}
|
||||
check(n==INVALID,"Wrong Node list linking.");
|
||||
check(countNodes(G)==cnt,"Wrong Node number.");
|
||||
}
|
||||
|
||||
template<class Graph>
|
||||
void checkGraphRedNodeList(const Graph &G, int cnt)
|
||||
{
|
||||
typename Graph::RedNodeIt n(G);
|
||||
for(int i=0;i<cnt;i++) {
|
||||
check(n!=INVALID,"Wrong red Node list linking.");
|
||||
check(G.red(n),"Wrong node set check.");
|
||||
check(!G.blue(n),"Wrong node set check.");
|
||||
typename Graph::Node nn = n;
|
||||
check(G.asRedNodeUnsafe(nn) == n,"Wrong node conversion.");
|
||||
check(G.asRedNode(nn) == n,"Wrong node conversion.");
|
||||
check(G.asBlueNode(nn) == INVALID,"Wrong node conversion.");
|
||||
++n;
|
||||
}
|
||||
check(n==INVALID,"Wrong red Node list linking.");
|
||||
check(countRedNodes(G)==cnt,"Wrong red Node number.");
|
||||
}
|
||||
|
||||
template<class Graph>
|
||||
void checkGraphBlueNodeList(const Graph &G, int cnt)
|
||||
{
|
||||
typename Graph::BlueNodeIt n(G);
|
||||
for(int i=0;i<cnt;i++) {
|
||||
check(n!=INVALID,"Wrong blue Node list linking.");
|
||||
check(G.blue(n),"Wrong node set check.");
|
||||
check(!G.red(n),"Wrong node set check.");
|
||||
typename Graph::Node nn = n;
|
||||
check(G.asBlueNodeUnsafe(nn) == n,"Wrong node conversion.");
|
||||
check(G.asBlueNode(nn) == n,"Wrong node conversion.");
|
||||
check(G.asRedNode(nn) == INVALID,"Wrong node conversion.");
|
||||
++n;
|
||||
}
|
||||
check(n==INVALID,"Wrong blue Node list linking.");
|
||||
check(countBlueNodes(G)==cnt,"Wrong blue Node number.");
|
||||
}
|
||||
|
||||
template<class Graph>
|
||||
void checkGraphArcList(const Graph &G, int cnt)
|
||||
{
|
||||
typename Graph::ArcIt e(G);
|
||||
for(int i=0;i<cnt;i++) {
|
||||
check(e!=INVALID,"Wrong Arc list linking.");
|
||||
check(G.oppositeNode(G.source(e), e) == G.target(e),
|
||||
"Wrong opposite node");
|
||||
check(G.oppositeNode(G.target(e), e) == G.source(e),
|
||||
"Wrong opposite node");
|
||||
++e;
|
||||
}
|
||||
check(e==INVALID,"Wrong Arc list linking.");
|
||||
check(countArcs(G)==cnt,"Wrong Arc number.");
|
||||
}
|
||||
|
||||
template<class Graph>
|
||||
void checkGraphOutArcList(const Graph &G, typename Graph::Node n, int cnt)
|
||||
{
|
||||
typename Graph::OutArcIt e(G,n);
|
||||
for(int i=0;i<cnt;i++) {
|
||||
check(e!=INVALID,"Wrong OutArc list linking.");
|
||||
check(n==G.source(e),"Wrong OutArc list linking.");
|
||||
check(n==G.baseNode(e),"Wrong OutArc list linking.");
|
||||
check(G.target(e)==G.runningNode(e),"Wrong OutArc list linking.");
|
||||
++e;
|
||||
}
|
||||
check(e==INVALID,"Wrong OutArc list linking.");
|
||||
check(countOutArcs(G,n)==cnt,"Wrong OutArc number.");
|
||||
}
|
||||
|
||||
template<class Graph>
|
||||
void checkGraphInArcList(const Graph &G, typename Graph::Node n, int cnt)
|
||||
{
|
||||
typename Graph::InArcIt e(G,n);
|
||||
for(int i=0;i<cnt;i++) {
|
||||
check(e!=INVALID,"Wrong InArc list linking.");
|
||||
check(n==G.target(e),"Wrong InArc list linking.");
|
||||
check(n==G.baseNode(e),"Wrong OutArc list linking.");
|
||||
check(G.source(e)==G.runningNode(e),"Wrong OutArc list linking.");
|
||||
++e;
|
||||
}
|
||||
check(e==INVALID,"Wrong InArc list linking.");
|
||||
check(countInArcs(G,n)==cnt,"Wrong InArc number.");
|
||||
}
|
||||
|
||||
template<class Graph>
|
||||
void checkGraphEdgeList(const Graph &G, int cnt)
|
||||
{
|
||||
typename Graph::EdgeIt e(G);
|
||||
for(int i=0;i<cnt;i++) {
|
||||
check(e!=INVALID,"Wrong Edge list linking.");
|
||||
check(G.oppositeNode(G.u(e), e) == G.v(e), "Wrong opposite node");
|
||||
check(G.oppositeNode(G.v(e), e) == G.u(e), "Wrong opposite node");
|
||||
++e;
|
||||
}
|
||||
check(e==INVALID,"Wrong Edge list linking.");
|
||||
check(countEdges(G)==cnt,"Wrong Edge number.");
|
||||
}
|
||||
|
||||
template<class Graph>
|
||||
void checkGraphIncEdgeList(const Graph &G, typename Graph::Node n, int cnt)
|
||||
{
|
||||
typename Graph::IncEdgeIt e(G,n);
|
||||
for(int i=0;i<cnt;i++) {
|
||||
check(e!=INVALID,"Wrong IncEdge list linking.");
|
||||
check(n==G.u(e) || n==G.v(e),"Wrong IncEdge list linking.");
|
||||
check(n==G.baseNode(e),"Wrong OutArc list linking.");
|
||||
check(G.u(e)==G.runningNode(e) || G.v(e)==G.runningNode(e),
|
||||
"Wrong OutArc list linking.");
|
||||
++e;
|
||||
}
|
||||
check(e==INVALID,"Wrong IncEdge list linking.");
|
||||
check(countIncEdges(G,n)==cnt,"Wrong IncEdge number.");
|
||||
}
|
||||
|
||||
template <class Graph>
|
||||
void checkGraphIncEdgeArcLists(const Graph &G, typename Graph::Node n,
|
||||
int cnt)
|
||||
{
|
||||
checkGraphIncEdgeList(G, n, cnt);
|
||||
checkGraphOutArcList(G, n, cnt);
|
||||
checkGraphInArcList(G, n, cnt);
|
||||
}
|
||||
|
||||
template <class Graph>
|
||||
void checkGraphConArcList(const Graph &G, int cnt) {
|
||||
int i = 0;
|
||||
for (typename Graph::NodeIt u(G); u != INVALID; ++u) {
|
||||
for (typename Graph::NodeIt v(G); v != INVALID; ++v) {
|
||||
for (ConArcIt<Graph> a(G, u, v); a != INVALID; ++a) {
|
||||
check(G.source(a) == u, "Wrong iterator.");
|
||||
check(G.target(a) == v, "Wrong iterator.");
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
check(cnt == i, "Wrong iterator.");
|
||||
}
|
||||
|
||||
template <class Graph>
|
||||
void checkGraphConEdgeList(const Graph &G, int cnt) {
|
||||
int i = 0;
|
||||
for (typename Graph::NodeIt u(G); u != INVALID; ++u) {
|
||||
for (typename Graph::NodeIt v(G); v != INVALID; ++v) {
|
||||
for (ConEdgeIt<Graph> e(G, u, v); e != INVALID; ++e) {
|
||||
check((G.u(e) == u && G.v(e) == v) ||
|
||||
(G.u(e) == v && G.v(e) == u), "Wrong iterator.");
|
||||
i += u == v ? 2 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
check(2 * cnt == i, "Wrong iterator.");
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void checkArcDirections(const Graph& G) {
|
||||
for (typename Graph::ArcIt a(G); a != INVALID; ++a) {
|
||||
check(G.source(a) == G.target(G.oppositeArc(a)), "Wrong direction");
|
||||
check(G.target(a) == G.source(G.oppositeArc(a)), "Wrong direction");
|
||||
check(G.direct(a, G.direction(a)) == a, "Wrong direction");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void checkNodeIds(const Graph& G) {
|
||||
typedef typename Graph::Node Node;
|
||||
std::set<int> values;
|
||||
for (typename Graph::NodeIt n(G); n != INVALID; ++n) {
|
||||
check(G.nodeFromId(G.id(n)) == n, "Wrong id");
|
||||
check(values.find(G.id(n)) == values.end(), "Wrong id");
|
||||
check(G.id(n) <= G.maxNodeId(), "Wrong maximum id");
|
||||
values.insert(G.id(n));
|
||||
}
|
||||
check(G.maxId(Node()) <= G.maxNodeId(), "Wrong maximum id");
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void checkRedNodeIds(const Graph& G) {
|
||||
typedef typename Graph::RedNode RedNode;
|
||||
std::set<int> values;
|
||||
for (typename Graph::RedNodeIt n(G); n != INVALID; ++n) {
|
||||
check(G.red(n), "Wrong partition");
|
||||
check(values.find(G.id(n)) == values.end(), "Wrong id");
|
||||
check(G.id(n) <= G.maxRedId(), "Wrong maximum id");
|
||||
values.insert(G.id(n));
|
||||
}
|
||||
check(G.maxId(RedNode()) == G.maxRedId(), "Wrong maximum id");
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void checkBlueNodeIds(const Graph& G) {
|
||||
typedef typename Graph::BlueNode BlueNode;
|
||||
std::set<int> values;
|
||||
for (typename Graph::BlueNodeIt n(G); n != INVALID; ++n) {
|
||||
check(G.blue(n), "Wrong partition");
|
||||
check(values.find(G.id(n)) == values.end(), "Wrong id");
|
||||
check(G.id(n) <= G.maxBlueId(), "Wrong maximum id");
|
||||
values.insert(G.id(n));
|
||||
}
|
||||
check(G.maxId(BlueNode()) == G.maxBlueId(), "Wrong maximum id");
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void checkArcIds(const Graph& G) {
|
||||
typedef typename Graph::Arc Arc;
|
||||
std::set<int> values;
|
||||
for (typename Graph::ArcIt a(G); a != INVALID; ++a) {
|
||||
check(G.arcFromId(G.id(a)) == a, "Wrong id");
|
||||
check(values.find(G.id(a)) == values.end(), "Wrong id");
|
||||
check(G.id(a) <= G.maxArcId(), "Wrong maximum id");
|
||||
values.insert(G.id(a));
|
||||
}
|
||||
check(G.maxId(Arc()) <= G.maxArcId(), "Wrong maximum id");
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void checkEdgeIds(const Graph& G) {
|
||||
typedef typename Graph::Edge Edge;
|
||||
std::set<int> values;
|
||||
for (typename Graph::EdgeIt e(G); e != INVALID; ++e) {
|
||||
check(G.edgeFromId(G.id(e)) == e, "Wrong id");
|
||||
check(values.find(G.id(e)) == values.end(), "Wrong id");
|
||||
check(G.id(e) <= G.maxEdgeId(), "Wrong maximum id");
|
||||
values.insert(G.id(e));
|
||||
}
|
||||
check(G.maxId(Edge()) <= G.maxEdgeId(), "Wrong maximum id");
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void checkGraphNodeMap(const Graph& G) {
|
||||
typedef typename Graph::Node Node;
|
||||
typedef typename Graph::NodeIt NodeIt;
|
||||
|
||||
typedef typename Graph::template NodeMap<int> IntNodeMap;
|
||||
IntNodeMap map(G, 42);
|
||||
for (NodeIt it(G); it != INVALID; ++it) {
|
||||
check(map[it] == 42, "Wrong map constructor.");
|
||||
}
|
||||
int s = 0;
|
||||
for (NodeIt it(G); it != INVALID; ++it) {
|
||||
map[it] = 0;
|
||||
check(map[it] == 0, "Wrong operator[].");
|
||||
map.set(it, s);
|
||||
check(map[it] == s, "Wrong set.");
|
||||
++s;
|
||||
}
|
||||
s = s * (s - 1) / 2;
|
||||
for (NodeIt it(G); it != INVALID; ++it) {
|
||||
s -= map[it];
|
||||
}
|
||||
check(s == 0, "Wrong sum.");
|
||||
|
||||
// map = constMap<Node>(12);
|
||||
// for (NodeIt it(G); it != INVALID; ++it) {
|
||||
// check(map[it] == 12, "Wrong operator[].");
|
||||
// }
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void checkGraphRedNodeMap(const Graph& G) {
|
||||
typedef typename Graph::Node Node;
|
||||
typedef typename Graph::RedNodeIt RedNodeIt;
|
||||
|
||||
typedef typename Graph::template RedNodeMap<int> IntRedNodeMap;
|
||||
IntRedNodeMap map(G, 42);
|
||||
for (RedNodeIt it(G); it != INVALID; ++it) {
|
||||
check(map[it] == 42, "Wrong map constructor.");
|
||||
}
|
||||
int s = 0;
|
||||
for (RedNodeIt it(G); it != INVALID; ++it) {
|
||||
map[it] = 0;
|
||||
check(map[it] == 0, "Wrong operator[].");
|
||||
map.set(it, s);
|
||||
check(map[it] == s, "Wrong set.");
|
||||
++s;
|
||||
}
|
||||
s = s * (s - 1) / 2;
|
||||
for (RedNodeIt it(G); it != INVALID; ++it) {
|
||||
s -= map[it];
|
||||
}
|
||||
check(s == 0, "Wrong sum.");
|
||||
|
||||
// map = constMap<Node>(12);
|
||||
// for (NodeIt it(G); it != INVALID; ++it) {
|
||||
// check(map[it] == 12, "Wrong operator[].");
|
||||
// }
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void checkGraphBlueNodeMap(const Graph& G) {
|
||||
typedef typename Graph::Node Node;
|
||||
typedef typename Graph::BlueNodeIt BlueNodeIt;
|
||||
|
||||
typedef typename Graph::template BlueNodeMap<int> IntBlueNodeMap;
|
||||
IntBlueNodeMap map(G, 42);
|
||||
for (BlueNodeIt it(G); it != INVALID; ++it) {
|
||||
check(map[it] == 42, "Wrong map constructor.");
|
||||
}
|
||||
int s = 0;
|
||||
for (BlueNodeIt it(G); it != INVALID; ++it) {
|
||||
map[it] = 0;
|
||||
check(map[it] == 0, "Wrong operator[].");
|
||||
map.set(it, s);
|
||||
check(map[it] == s, "Wrong set.");
|
||||
++s;
|
||||
}
|
||||
s = s * (s - 1) / 2;
|
||||
for (BlueNodeIt it(G); it != INVALID; ++it) {
|
||||
s -= map[it];
|
||||
}
|
||||
check(s == 0, "Wrong sum.");
|
||||
|
||||
// map = constMap<Node>(12);
|
||||
// for (NodeIt it(G); it != INVALID; ++it) {
|
||||
// check(map[it] == 12, "Wrong operator[].");
|
||||
// }
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void checkGraphArcMap(const Graph& G) {
|
||||
typedef typename Graph::Arc Arc;
|
||||
typedef typename Graph::ArcIt ArcIt;
|
||||
|
||||
typedef typename Graph::template ArcMap<int> IntArcMap;
|
||||
IntArcMap map(G, 42);
|
||||
for (ArcIt it(G); it != INVALID; ++it) {
|
||||
check(map[it] == 42, "Wrong map constructor.");
|
||||
}
|
||||
int s = 0;
|
||||
for (ArcIt it(G); it != INVALID; ++it) {
|
||||
map[it] = 0;
|
||||
check(map[it] == 0, "Wrong operator[].");
|
||||
map.set(it, s);
|
||||
check(map[it] == s, "Wrong set.");
|
||||
++s;
|
||||
}
|
||||
s = s * (s - 1) / 2;
|
||||
for (ArcIt it(G); it != INVALID; ++it) {
|
||||
s -= map[it];
|
||||
}
|
||||
check(s == 0, "Wrong sum.");
|
||||
|
||||
// map = constMap<Arc>(12);
|
||||
// for (ArcIt it(G); it != INVALID; ++it) {
|
||||
// check(map[it] == 12, "Wrong operator[].");
|
||||
// }
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void checkGraphEdgeMap(const Graph& G) {
|
||||
typedef typename Graph::Edge Edge;
|
||||
typedef typename Graph::EdgeIt EdgeIt;
|
||||
|
||||
typedef typename Graph::template EdgeMap<int> IntEdgeMap;
|
||||
IntEdgeMap map(G, 42);
|
||||
for (EdgeIt it(G); it != INVALID; ++it) {
|
||||
check(map[it] == 42, "Wrong map constructor.");
|
||||
}
|
||||
int s = 0;
|
||||
for (EdgeIt it(G); it != INVALID; ++it) {
|
||||
map[it] = 0;
|
||||
check(map[it] == 0, "Wrong operator[].");
|
||||
map.set(it, s);
|
||||
check(map[it] == s, "Wrong set.");
|
||||
++s;
|
||||
}
|
||||
s = s * (s - 1) / 2;
|
||||
for (EdgeIt it(G); it != INVALID; ++it) {
|
||||
s -= map[it];
|
||||
}
|
||||
check(s == 0, "Wrong sum.");
|
||||
|
||||
// map = constMap<Edge>(12);
|
||||
// for (EdgeIt it(G); it != INVALID; ++it) {
|
||||
// check(map[it] == 12, "Wrong operator[].");
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
} //namespace lemon
|
||||
|
||||
#endif
|
||||
217
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/graph_utils_test.cc
vendored
Normal file
217
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/graph_utils_test.cc
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
|
||||
#include <lemon/random.h>
|
||||
#include <lemon/list_graph.h>
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/maps.h>
|
||||
|
||||
#include "graph_test.h"
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
template <typename Digraph>
|
||||
void checkFindArcs() {
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
|
||||
{
|
||||
Digraph digraph;
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
digraph.addNode();
|
||||
}
|
||||
RangeIdMap<Digraph, Node> nodes(digraph);
|
||||
typename RangeIdMap<Digraph, Node>::InverseMap invNodes(nodes);
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
int src = rnd[invNodes.size()];
|
||||
int trg = rnd[invNodes.size()];
|
||||
digraph.addArc(invNodes[src], invNodes[trg]);
|
||||
}
|
||||
typename Digraph::template ArcMap<bool> found(digraph, false);
|
||||
RangeIdMap<Digraph, Arc> arcs(digraph);
|
||||
for (NodeIt src(digraph); src != INVALID; ++src) {
|
||||
for (NodeIt trg(digraph); trg != INVALID; ++trg) {
|
||||
for (ConArcIt<Digraph> con(digraph, src, trg); con != INVALID; ++con) {
|
||||
check(digraph.source(con) == src, "Wrong source.");
|
||||
check(digraph.target(con) == trg, "Wrong target.");
|
||||
check(found[con] == false, "The arc found already.");
|
||||
found[con] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (ArcIt it(digraph); it != INVALID; ++it) {
|
||||
check(found[it] == true, "The arc is not found.");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int num = 5;
|
||||
Digraph fg;
|
||||
std::vector<Node> nodes;
|
||||
for (int i = 0; i < num; ++i) {
|
||||
nodes.push_back(fg.addNode());
|
||||
}
|
||||
for (int i = 0; i < num * num; ++i) {
|
||||
fg.addArc(nodes[i / num], nodes[i % num]);
|
||||
}
|
||||
check(countNodes(fg) == num, "Wrong node number.");
|
||||
check(countArcs(fg) == num*num, "Wrong arc number.");
|
||||
for (NodeIt src(fg); src != INVALID; ++src) {
|
||||
for (NodeIt trg(fg); trg != INVALID; ++trg) {
|
||||
ConArcIt<Digraph> con(fg, src, trg);
|
||||
check(con != INVALID, "There is no connecting arc.");
|
||||
check(fg.source(con) == src, "Wrong source.");
|
||||
check(fg.target(con) == trg, "Wrong target.");
|
||||
check(++con == INVALID, "There is more connecting arc.");
|
||||
}
|
||||
}
|
||||
ArcLookUp<Digraph> al1(fg);
|
||||
DynArcLookUp<Digraph> al2(fg);
|
||||
AllArcLookUp<Digraph> al3(fg);
|
||||
for (NodeIt src(fg); src != INVALID; ++src) {
|
||||
for (NodeIt trg(fg); trg != INVALID; ++trg) {
|
||||
Arc con1 = al1(src, trg);
|
||||
Arc con2 = al2(src, trg);
|
||||
Arc con3 = al3(src, trg);
|
||||
Arc con4 = findArc(fg, src, trg);
|
||||
check(con1 == con2 && con2 == con3 && con3 == con4,
|
||||
"Different results.")
|
||||
check(con1 != INVALID, "There is no connecting arc.");
|
||||
check(fg.source(con1) == src, "Wrong source.");
|
||||
check(fg.target(con1) == trg, "Wrong target.");
|
||||
check(al3(src, trg, con3) == INVALID,
|
||||
"There is more connecting arc.");
|
||||
check(findArc(fg, src, trg, con4) == INVALID,
|
||||
"There is more connecting arc.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void checkFindEdges() {
|
||||
TEMPLATE_GRAPH_TYPEDEFS(Graph);
|
||||
Graph graph;
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
graph.addNode();
|
||||
}
|
||||
RangeIdMap<Graph, Node> nodes(graph);
|
||||
typename RangeIdMap<Graph, Node>::InverseMap invNodes(nodes);
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
int src = rnd[invNodes.size()];
|
||||
int trg = rnd[invNodes.size()];
|
||||
graph.addEdge(invNodes[src], invNodes[trg]);
|
||||
}
|
||||
typename Graph::template EdgeMap<int> found(graph, 0);
|
||||
RangeIdMap<Graph, Edge> edges(graph);
|
||||
for (NodeIt src(graph); src != INVALID; ++src) {
|
||||
for (NodeIt trg(graph); trg != INVALID; ++trg) {
|
||||
for (ConEdgeIt<Graph> con(graph, src, trg); con != INVALID; ++con) {
|
||||
check( (graph.u(con) == src && graph.v(con) == trg) ||
|
||||
(graph.v(con) == src && graph.u(con) == trg),
|
||||
"Wrong end nodes.");
|
||||
++found[con];
|
||||
check(found[con] <= 2, "The edge found more than twice.");
|
||||
}
|
||||
}
|
||||
}
|
||||
for (EdgeIt it(graph); it != INVALID; ++it) {
|
||||
check( (graph.u(it) != graph.v(it) && found[it] == 2) ||
|
||||
(graph.u(it) == graph.v(it) && found[it] == 1),
|
||||
"The edge is not found correctly.");
|
||||
}
|
||||
}
|
||||
|
||||
template <class Digraph>
|
||||
void checkDeg()
|
||||
{
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
|
||||
const int nodeNum = 10;
|
||||
const int arcNum = 100;
|
||||
Digraph digraph;
|
||||
InDegMap<Digraph> inDeg(digraph);
|
||||
OutDegMap<Digraph> outDeg(digraph);
|
||||
std::vector<Node> nodes(nodeNum);
|
||||
for (int i = 0; i < nodeNum; ++i) {
|
||||
nodes[i] = digraph.addNode();
|
||||
}
|
||||
std::vector<Arc> arcs(arcNum);
|
||||
for (int i = 0; i < arcNum; ++i) {
|
||||
arcs[i] = digraph.addArc(nodes[rnd[nodeNum]], nodes[rnd[nodeNum]]);
|
||||
}
|
||||
for (int i = 0; i < nodeNum; ++i) {
|
||||
check(inDeg[nodes[i]] == countInArcs(digraph, nodes[i]),
|
||||
"Wrong in degree map");
|
||||
}
|
||||
for (int i = 0; i < nodeNum; ++i) {
|
||||
check(outDeg[nodes[i]] == countOutArcs(digraph, nodes[i]),
|
||||
"Wrong out degree map");
|
||||
}
|
||||
}
|
||||
|
||||
template <class Digraph>
|
||||
void checkSnapDeg()
|
||||
{
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
|
||||
Digraph g;
|
||||
Node n1=g.addNode();
|
||||
Node n2=g.addNode();
|
||||
|
||||
InDegMap<Digraph> ind(g);
|
||||
|
||||
g.addArc(n1,n2);
|
||||
|
||||
typename Digraph::Snapshot snap(g);
|
||||
|
||||
OutDegMap<Digraph> outd(g);
|
||||
|
||||
check(ind[n1]==0 && ind[n2]==1, "Wrong InDegMap value.");
|
||||
check(outd[n1]==1 && outd[n2]==0, "Wrong OutDegMap value.");
|
||||
|
||||
g.addArc(n1,n2);
|
||||
g.addArc(n2,n1);
|
||||
|
||||
check(ind[n1]==1 && ind[n2]==2, "Wrong InDegMap value.");
|
||||
check(outd[n1]==2 && outd[n2]==1, "Wrong OutDegMap value.");
|
||||
|
||||
snap.restore();
|
||||
|
||||
check(ind[n1]==0 && ind[n2]==1, "Wrong InDegMap value.");
|
||||
check(outd[n1]==1 && outd[n2]==0, "Wrong OutDegMap value.");
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Checking ConArcIt, ConEdgeIt, ArcLookUp, AllArcLookUp, and DynArcLookUp
|
||||
checkFindArcs<ListDigraph>();
|
||||
checkFindArcs<SmartDigraph>();
|
||||
checkFindEdges<ListGraph>();
|
||||
checkFindEdges<SmartGraph>();
|
||||
|
||||
// Checking In/OutDegMap (and Snapshot feature)
|
||||
checkDeg<ListDigraph>();
|
||||
checkDeg<SmartDigraph>();
|
||||
checkSnapDeg<ListDigraph>();
|
||||
checkSnapDeg<SmartDigraph>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
164
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/hao_orlin_test.cc
vendored
Normal file
164
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/hao_orlin_test.cc
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/adaptors.h>
|
||||
#include <lemon/concepts/digraph.h>
|
||||
#include <lemon/concepts/maps.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/hao_orlin.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
using namespace std;
|
||||
|
||||
const std::string lgf =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"@edges\n"
|
||||
" cap1 cap2 cap3\n"
|
||||
"0 1 1 1 1 \n"
|
||||
"0 2 2 2 4 \n"
|
||||
"1 2 4 4 4 \n"
|
||||
"3 4 1 1 1 \n"
|
||||
"3 5 2 2 4 \n"
|
||||
"4 5 4 4 4 \n"
|
||||
"5 4 4 4 4 \n"
|
||||
"2 3 1 6 6 \n"
|
||||
"4 0 1 6 6 \n";
|
||||
|
||||
void checkHaoOrlinCompile()
|
||||
{
|
||||
typedef int Value;
|
||||
typedef concepts::Digraph Digraph;
|
||||
|
||||
typedef Digraph::Node Node;
|
||||
typedef Digraph::Arc Arc;
|
||||
typedef concepts::ReadMap<Arc, Value> CapMap;
|
||||
typedef concepts::WriteMap<Node, bool> CutMap;
|
||||
|
||||
Digraph g;
|
||||
Node n;
|
||||
CapMap cap;
|
||||
CutMap cut;
|
||||
Value v;
|
||||
::lemon::ignore_unused_variable_warning(v);
|
||||
|
||||
HaoOrlin<Digraph, CapMap> ho_test(g, cap);
|
||||
const HaoOrlin<Digraph, CapMap>&
|
||||
const_ho_test = ho_test;
|
||||
|
||||
ho_test.init();
|
||||
ho_test.init(n);
|
||||
ho_test.calculateOut();
|
||||
ho_test.calculateIn();
|
||||
ho_test.run();
|
||||
ho_test.run(n);
|
||||
|
||||
v = const_ho_test.minCutValue();
|
||||
v = const_ho_test.minCutMap(cut);
|
||||
}
|
||||
|
||||
template <typename Graph, typename CapMap, typename CutMap>
|
||||
typename CapMap::Value
|
||||
cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut)
|
||||
{
|
||||
typename CapMap::Value sum = 0;
|
||||
for (typename Graph::ArcIt a(graph); a != INVALID; ++a) {
|
||||
if (cut[graph.source(a)] && !cut[graph.target(a)])
|
||||
sum += cap[a];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
int main() {
|
||||
SmartDigraph graph;
|
||||
SmartDigraph::ArcMap<int> cap1(graph), cap2(graph), cap3(graph);
|
||||
SmartDigraph::NodeMap<bool> cut(graph);
|
||||
|
||||
istringstream input(lgf);
|
||||
digraphReader(graph, input)
|
||||
.arcMap("cap1", cap1)
|
||||
.arcMap("cap2", cap2)
|
||||
.arcMap("cap3", cap3)
|
||||
.run();
|
||||
|
||||
{
|
||||
HaoOrlin<SmartDigraph> ho(graph, cap1);
|
||||
ho.run();
|
||||
ho.minCutMap(cut);
|
||||
|
||||
check(ho.minCutValue() == 1, "Wrong cut value");
|
||||
check(ho.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value");
|
||||
}
|
||||
{
|
||||
HaoOrlin<SmartDigraph> ho(graph, cap2);
|
||||
ho.run();
|
||||
ho.minCutMap(cut);
|
||||
|
||||
check(ho.minCutValue() == 1, "Wrong cut value");
|
||||
check(ho.minCutValue() == cutValue(graph, cap2, cut), "Wrong cut value");
|
||||
}
|
||||
{
|
||||
HaoOrlin<SmartDigraph> ho(graph, cap3);
|
||||
ho.run();
|
||||
ho.minCutMap(cut);
|
||||
|
||||
check(ho.minCutValue() == 1, "Wrong cut value");
|
||||
check(ho.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value");
|
||||
}
|
||||
|
||||
typedef Undirector<SmartDigraph> UGraph;
|
||||
UGraph ugraph(graph);
|
||||
|
||||
{
|
||||
HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap1);
|
||||
ho.run();
|
||||
ho.minCutMap(cut);
|
||||
|
||||
check(ho.minCutValue() == 2, "Wrong cut value");
|
||||
check(ho.minCutValue() == cutValue(ugraph, cap1, cut), "Wrong cut value");
|
||||
}
|
||||
{
|
||||
HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap2);
|
||||
ho.run();
|
||||
ho.minCutMap(cut);
|
||||
|
||||
check(ho.minCutValue() == 5, "Wrong cut value");
|
||||
check(ho.minCutValue() == cutValue(ugraph, cap2, cut), "Wrong cut value");
|
||||
}
|
||||
{
|
||||
HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap3);
|
||||
ho.run();
|
||||
ho.minCutMap(cut);
|
||||
|
||||
check(ho.minCutValue() == 5, "Wrong cut value");
|
||||
check(ho.minCutValue() == cutValue(ugraph, cap3, cut), "Wrong cut value");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
310
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/heap_test.cc
vendored
Normal file
310
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/heap_test.cc
vendored
Normal file
@@ -0,0 +1,310 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <lemon/concept_check.h>
|
||||
#include <lemon/concepts/heap.h>
|
||||
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/dijkstra.h>
|
||||
#include <lemon/maps.h>
|
||||
|
||||
#include <lemon/bin_heap.h>
|
||||
#include <lemon/quad_heap.h>
|
||||
#include <lemon/dheap.h>
|
||||
#include <lemon/fib_heap.h>
|
||||
#include <lemon/pairing_heap.h>
|
||||
#include <lemon/radix_heap.h>
|
||||
#include <lemon/binomial_heap.h>
|
||||
#include <lemon/bucket_heap.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
using namespace lemon::concepts;
|
||||
|
||||
typedef ListDigraph Digraph;
|
||||
DIGRAPH_TYPEDEFS(Digraph);
|
||||
|
||||
char test_lgf[] =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"6\n"
|
||||
"7\n"
|
||||
"8\n"
|
||||
"9\n"
|
||||
"@arcs\n"
|
||||
" label capacity\n"
|
||||
"0 5 0 94\n"
|
||||
"3 9 1 11\n"
|
||||
"8 7 2 83\n"
|
||||
"1 2 3 94\n"
|
||||
"5 7 4 35\n"
|
||||
"7 4 5 84\n"
|
||||
"9 5 6 38\n"
|
||||
"0 4 7 96\n"
|
||||
"6 7 8 6\n"
|
||||
"3 1 9 27\n"
|
||||
"5 2 10 77\n"
|
||||
"5 6 11 69\n"
|
||||
"6 5 12 41\n"
|
||||
"4 6 13 70\n"
|
||||
"3 2 14 45\n"
|
||||
"7 9 15 93\n"
|
||||
"5 9 16 50\n"
|
||||
"9 0 17 94\n"
|
||||
"9 6 18 67\n"
|
||||
"0 9 19 86\n"
|
||||
"@attributes\n"
|
||||
"source 3\n";
|
||||
|
||||
int test_seq[] = { 2, 28, 19, 27, 33, 25, 13, 41, 10, 26, 1, 9, 4, 34};
|
||||
int test_inc[] = {20, 28, 34, 16, 0, 46, 44, 0, 42, 32, 14, 8, 6, 37};
|
||||
|
||||
int test_len = sizeof(test_seq) / sizeof(test_seq[0]);
|
||||
|
||||
template <typename Heap>
|
||||
void heapSortTest() {
|
||||
RangeMap<int> map(test_len, -1);
|
||||
Heap heap(map);
|
||||
|
||||
std::vector<int> v(test_len);
|
||||
for (int i = 0; i < test_len; ++i) {
|
||||
v[i] = test_seq[i];
|
||||
heap.push(i, v[i]);
|
||||
}
|
||||
std::sort(v.begin(), v.end());
|
||||
for (int i = 0; i < test_len; ++i) {
|
||||
check(v[i] == heap.prio(), "Wrong order in heap sort.");
|
||||
heap.pop();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Heap>
|
||||
void heapIncreaseTest() {
|
||||
RangeMap<int> map(test_len, -1);
|
||||
|
||||
Heap heap(map);
|
||||
|
||||
std::vector<int> v(test_len);
|
||||
for (int i = 0; i < test_len; ++i) {
|
||||
v[i] = test_seq[i];
|
||||
heap.push(i, v[i]);
|
||||
}
|
||||
for (int i = 0; i < test_len; ++i) {
|
||||
v[i] += test_inc[i];
|
||||
heap.increase(i, v[i]);
|
||||
}
|
||||
std::sort(v.begin(), v.end());
|
||||
for (int i = 0; i < test_len; ++i) {
|
||||
check(v[i] == heap.prio(), "Wrong order in heap increase test.");
|
||||
heap.pop();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Heap>
|
||||
void dijkstraHeapTest(const Digraph& digraph, const IntArcMap& length,
|
||||
Node source) {
|
||||
|
||||
typename Dijkstra<Digraph, IntArcMap>::template SetStandardHeap<Heap>::
|
||||
Create dijkstra(digraph, length);
|
||||
|
||||
dijkstra.run(source);
|
||||
|
||||
for(ArcIt a(digraph); a != INVALID; ++a) {
|
||||
Node s = digraph.source(a);
|
||||
Node t = digraph.target(a);
|
||||
if (dijkstra.reached(s)) {
|
||||
check( dijkstra.dist(t) - dijkstra.dist(s) <= length[a],
|
||||
"Error in shortest path tree.");
|
||||
}
|
||||
}
|
||||
|
||||
for(NodeIt n(digraph); n != INVALID; ++n) {
|
||||
if ( dijkstra.reached(n) && dijkstra.predArc(n) != INVALID ) {
|
||||
Arc a = dijkstra.predArc(n);
|
||||
Node s = digraph.source(a);
|
||||
check( dijkstra.dist(n) - dijkstra.dist(s) == length[a],
|
||||
"Error in shortest path tree.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
typedef int Item;
|
||||
typedef int Prio;
|
||||
typedef RangeMap<int> ItemIntMap;
|
||||
|
||||
Digraph digraph;
|
||||
IntArcMap length(digraph);
|
||||
Node source;
|
||||
|
||||
std::istringstream input(test_lgf);
|
||||
digraphReader(digraph, input).
|
||||
arcMap("capacity", length).
|
||||
node("source", source).
|
||||
run();
|
||||
|
||||
// BinHeap
|
||||
{
|
||||
typedef BinHeap<Prio, ItemIntMap> IntHeap;
|
||||
checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
|
||||
heapSortTest<IntHeap>();
|
||||
heapIncreaseTest<IntHeap>();
|
||||
|
||||
typedef BinHeap<Prio, IntNodeMap > NodeHeap;
|
||||
checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
|
||||
dijkstraHeapTest<NodeHeap>(digraph, length, source);
|
||||
}
|
||||
|
||||
// QuadHeap
|
||||
{
|
||||
typedef QuadHeap<Prio, ItemIntMap> IntHeap;
|
||||
checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
|
||||
heapSortTest<IntHeap>();
|
||||
heapIncreaseTest<IntHeap>();
|
||||
|
||||
typedef QuadHeap<Prio, IntNodeMap > NodeHeap;
|
||||
checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
|
||||
dijkstraHeapTest<NodeHeap>(digraph, length, source);
|
||||
}
|
||||
|
||||
// DHeap
|
||||
{
|
||||
typedef DHeap<Prio, ItemIntMap> IntHeap;
|
||||
checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
|
||||
heapSortTest<IntHeap>();
|
||||
heapIncreaseTest<IntHeap>();
|
||||
|
||||
typedef DHeap<Prio, IntNodeMap > NodeHeap;
|
||||
checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
|
||||
dijkstraHeapTest<NodeHeap>(digraph, length, source);
|
||||
}
|
||||
|
||||
// FibHeap
|
||||
{
|
||||
typedef FibHeap<Prio, ItemIntMap> IntHeap;
|
||||
checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
|
||||
heapSortTest<IntHeap>();
|
||||
heapIncreaseTest<IntHeap>();
|
||||
|
||||
typedef FibHeap<Prio, IntNodeMap > NodeHeap;
|
||||
checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
|
||||
dijkstraHeapTest<NodeHeap>(digraph, length, source);
|
||||
}
|
||||
|
||||
// PairingHeap
|
||||
{
|
||||
typedef PairingHeap<Prio, ItemIntMap> IntHeap;
|
||||
checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
|
||||
heapSortTest<IntHeap>();
|
||||
heapIncreaseTest<IntHeap>();
|
||||
|
||||
typedef PairingHeap<Prio, IntNodeMap > NodeHeap;
|
||||
checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
|
||||
dijkstraHeapTest<NodeHeap>(digraph, length, source);
|
||||
}
|
||||
|
||||
// RadixHeap
|
||||
{
|
||||
typedef RadixHeap<ItemIntMap> IntHeap;
|
||||
checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
|
||||
heapSortTest<IntHeap>();
|
||||
heapIncreaseTest<IntHeap>();
|
||||
|
||||
typedef RadixHeap<IntNodeMap > NodeHeap;
|
||||
checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
|
||||
dijkstraHeapTest<NodeHeap>(digraph, length, source);
|
||||
}
|
||||
|
||||
// BinomialHeap
|
||||
{
|
||||
typedef BinomialHeap<Prio, ItemIntMap> IntHeap;
|
||||
checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
|
||||
heapSortTest<IntHeap>();
|
||||
heapIncreaseTest<IntHeap>();
|
||||
|
||||
typedef BinomialHeap<Prio, IntNodeMap > NodeHeap;
|
||||
checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
|
||||
dijkstraHeapTest<NodeHeap>(digraph, length, source);
|
||||
}
|
||||
|
||||
// BucketHeap, SimpleBucketHeap
|
||||
{
|
||||
typedef BucketHeap<ItemIntMap> IntHeap;
|
||||
checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
|
||||
heapSortTest<IntHeap>();
|
||||
heapIncreaseTest<IntHeap>();
|
||||
|
||||
typedef BucketHeap<IntNodeMap > NodeHeap;
|
||||
checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
|
||||
dijkstraHeapTest<NodeHeap>(digraph, length, source);
|
||||
|
||||
typedef SimpleBucketHeap<ItemIntMap> SimpleIntHeap;
|
||||
heapSortTest<SimpleIntHeap>();
|
||||
}
|
||||
|
||||
{
|
||||
typedef FibHeap<Prio, ItemIntMap> IntHeap;
|
||||
checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
|
||||
heapSortTest<IntHeap>();
|
||||
heapIncreaseTest<IntHeap>();
|
||||
|
||||
typedef FibHeap<Prio, IntNodeMap > NodeHeap;
|
||||
checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
|
||||
dijkstraHeapTest<NodeHeap>(digraph, length, source);
|
||||
}
|
||||
|
||||
{
|
||||
typedef RadixHeap<ItemIntMap> IntHeap;
|
||||
checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
|
||||
heapSortTest<IntHeap>();
|
||||
heapIncreaseTest<IntHeap>();
|
||||
|
||||
typedef RadixHeap<IntNodeMap > NodeHeap;
|
||||
checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
|
||||
dijkstraHeapTest<NodeHeap>(digraph, length, source);
|
||||
}
|
||||
|
||||
{
|
||||
typedef BucketHeap<ItemIntMap> IntHeap;
|
||||
checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
|
||||
heapSortTest<IntHeap>();
|
||||
heapIncreaseTest<IntHeap>();
|
||||
|
||||
typedef BucketHeap<IntNodeMap > NodeHeap;
|
||||
checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
|
||||
dijkstraHeapTest<NodeHeap>(digraph, length, source);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
147
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/kruskal_test.cc
vendored
Normal file
147
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/kruskal_test.cc
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "test_tools.h"
|
||||
#include <lemon/maps.h>
|
||||
#include <lemon/kruskal.h>
|
||||
#include <lemon/list_graph.h>
|
||||
|
||||
#include <lemon/concepts/maps.h>
|
||||
#include <lemon/concepts/digraph.h>
|
||||
#include <lemon/concepts/graph.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace lemon;
|
||||
|
||||
void checkCompileKruskal()
|
||||
{
|
||||
concepts::WriteMap<concepts::Digraph::Arc,bool> w;
|
||||
concepts::WriteMap<concepts::Graph::Edge,bool> uw;
|
||||
|
||||
concepts::ReadMap<concepts::Digraph::Arc,int> r;
|
||||
concepts::ReadMap<concepts::Graph::Edge,int> ur;
|
||||
|
||||
concepts::Digraph g;
|
||||
concepts::Graph ug;
|
||||
|
||||
kruskal(g, r, w);
|
||||
kruskal(ug, ur, uw);
|
||||
|
||||
std::vector<std::pair<concepts::Digraph::Arc, int> > rs;
|
||||
std::vector<std::pair<concepts::Graph::Edge, int> > urs;
|
||||
|
||||
kruskal(g, rs, w);
|
||||
kruskal(ug, urs, uw);
|
||||
|
||||
std::vector<concepts::Digraph::Arc> ws;
|
||||
std::vector<concepts::Graph::Edge> uws;
|
||||
|
||||
kruskal(g, r, ws.begin());
|
||||
kruskal(ug, ur, uws.begin());
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
typedef ListGraph::Node Node;
|
||||
typedef ListGraph::Edge Edge;
|
||||
typedef ListGraph::NodeIt NodeIt;
|
||||
typedef ListGraph::ArcIt ArcIt;
|
||||
|
||||
ListGraph G;
|
||||
|
||||
Node s=G.addNode();
|
||||
Node v1=G.addNode();
|
||||
Node v2=G.addNode();
|
||||
Node v3=G.addNode();
|
||||
Node v4=G.addNode();
|
||||
Node t=G.addNode();
|
||||
|
||||
Edge e1 = G.addEdge(s, v1);
|
||||
Edge e2 = G.addEdge(s, v2);
|
||||
Edge e3 = G.addEdge(v1, v2);
|
||||
Edge e4 = G.addEdge(v2, v1);
|
||||
Edge e5 = G.addEdge(v1, v3);
|
||||
Edge e6 = G.addEdge(v3, v2);
|
||||
Edge e7 = G.addEdge(v2, v4);
|
||||
Edge e8 = G.addEdge(v4, v3);
|
||||
Edge e9 = G.addEdge(v3, t);
|
||||
Edge e10 = G.addEdge(v4, t);
|
||||
|
||||
typedef ListGraph::EdgeMap<int> ECostMap;
|
||||
typedef ListGraph::EdgeMap<bool> EBoolMap;
|
||||
|
||||
ECostMap edge_cost_map(G, 2);
|
||||
EBoolMap tree_map(G);
|
||||
|
||||
|
||||
//Test with const map.
|
||||
check(kruskal(G, ConstMap<ListGraph::Edge,int>(2), tree_map)==10,
|
||||
"Total cost should be 10");
|
||||
//Test with an edge map (filled with uniform costs).
|
||||
check(kruskal(G, edge_cost_map, tree_map)==10,
|
||||
"Total cost should be 10");
|
||||
|
||||
edge_cost_map[e1] = -10;
|
||||
edge_cost_map[e2] = -9;
|
||||
edge_cost_map[e3] = -8;
|
||||
edge_cost_map[e4] = -7;
|
||||
edge_cost_map[e5] = -6;
|
||||
edge_cost_map[e6] = -5;
|
||||
edge_cost_map[e7] = -4;
|
||||
edge_cost_map[e8] = -3;
|
||||
edge_cost_map[e9] = -2;
|
||||
edge_cost_map[e10] = -1;
|
||||
|
||||
vector<Edge> tree_edge_vec(5);
|
||||
|
||||
//Test with a edge map and inserter.
|
||||
check(kruskal(G, edge_cost_map,
|
||||
tree_edge_vec.begin())
|
||||
==-31,
|
||||
"Total cost should be -31.");
|
||||
|
||||
tree_edge_vec.clear();
|
||||
|
||||
check(kruskal(G, edge_cost_map,
|
||||
back_inserter(tree_edge_vec))
|
||||
==-31,
|
||||
"Total cost should be -31.");
|
||||
|
||||
// tree_edge_vec.clear();
|
||||
|
||||
// //The above test could also be coded like this:
|
||||
// check(kruskal(G,
|
||||
// makeKruskalMapInput(G, edge_cost_map),
|
||||
// makeKruskalSequenceOutput(back_inserter(tree_edge_vec)))
|
||||
// ==-31,
|
||||
// "Total cost should be -31.");
|
||||
|
||||
check(tree_edge_vec.size()==5,"The tree should have 5 edges.");
|
||||
|
||||
check(tree_edge_vec[0]==e1 &&
|
||||
tree_edge_vec[1]==e2 &&
|
||||
tree_edge_vec[2]==e5 &&
|
||||
tree_edge_vec[3]==e7 &&
|
||||
tree_edge_vec[4]==e9,
|
||||
"Wrong tree.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
578
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/lgf_reader_writer_test.cc
vendored
Normal file
578
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/lgf_reader_writer_test.cc
vendored
Normal file
@@ -0,0 +1,578 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <lemon/concepts/digraph.h>
|
||||
#include <lemon/concepts/graph.h>
|
||||
#include <lemon/concepts/bpgraph.h>
|
||||
|
||||
#include <lemon/list_graph.h>
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
struct ReaderConverter {
|
||||
int operator()(const std::string& str) const {
|
||||
return str.length();
|
||||
}
|
||||
};
|
||||
|
||||
struct WriterConverter {
|
||||
std::string operator()(int value) const {
|
||||
return std::string(value, '*');
|
||||
}
|
||||
};
|
||||
|
||||
void checkDigraphReaderCompile() {
|
||||
typedef lemon::concepts::ExtendableDigraphComponent<
|
||||
lemon::concepts::Digraph> Digraph;
|
||||
Digraph digraph;
|
||||
Digraph::NodeMap<int> node_map(digraph);
|
||||
Digraph::ArcMap<int> arc_map(digraph);
|
||||
Digraph::Node node;
|
||||
Digraph::Arc arc;
|
||||
int attr;
|
||||
|
||||
lemon::DigraphReader<Digraph> reader(digraph, "filename");
|
||||
reader.nodeMap("node_map", node_map);
|
||||
reader.nodeMap("node_map", node_map, ReaderConverter());
|
||||
reader.arcMap("arc_map", arc_map);
|
||||
reader.arcMap("arc_map", arc_map, ReaderConverter());
|
||||
reader.attribute("attr", attr);
|
||||
reader.attribute("attr", attr, ReaderConverter());
|
||||
reader.node("node", node);
|
||||
reader.arc("arc", arc);
|
||||
|
||||
reader.nodes("alt_nodes_caption");
|
||||
reader.arcs("alt_arcs_caption");
|
||||
reader.attributes("alt_attrs_caption");
|
||||
|
||||
reader.useNodes(node_map);
|
||||
reader.useNodes(node_map, WriterConverter());
|
||||
reader.useArcs(arc_map);
|
||||
reader.useArcs(arc_map, WriterConverter());
|
||||
|
||||
reader.skipNodes();
|
||||
reader.skipArcs();
|
||||
|
||||
reader.run();
|
||||
|
||||
lemon::DigraphReader<Digraph> reader2(digraph, std::cin);
|
||||
}
|
||||
|
||||
void checkDigraphWriterCompile() {
|
||||
typedef lemon::concepts::Digraph Digraph;
|
||||
Digraph digraph;
|
||||
Digraph::NodeMap<int> node_map(digraph);
|
||||
Digraph::ArcMap<int> arc_map(digraph);
|
||||
Digraph::Node node;
|
||||
Digraph::Arc arc;
|
||||
int attr;
|
||||
|
||||
lemon::DigraphWriter<Digraph> writer(digraph, "filename");
|
||||
writer.nodeMap("node_map", node_map);
|
||||
writer.nodeMap("node_map", node_map, WriterConverter());
|
||||
writer.arcMap("arc_map", arc_map);
|
||||
writer.arcMap("arc_map", arc_map, WriterConverter());
|
||||
writer.attribute("attr", attr);
|
||||
writer.attribute("attr", attr, WriterConverter());
|
||||
writer.node("node", node);
|
||||
writer.arc("arc", arc);
|
||||
|
||||
writer.nodes("alt_nodes_caption");
|
||||
writer.arcs("alt_arcs_caption");
|
||||
writer.attributes("alt_attrs_caption");
|
||||
|
||||
writer.skipNodes();
|
||||
writer.skipArcs();
|
||||
|
||||
writer.run();
|
||||
}
|
||||
|
||||
void checkGraphReaderCompile() {
|
||||
typedef lemon::concepts::ExtendableGraphComponent<
|
||||
lemon::concepts::Graph> Graph;
|
||||
Graph graph;
|
||||
Graph::NodeMap<int> node_map(graph);
|
||||
Graph::ArcMap<int> arc_map(graph);
|
||||
Graph::EdgeMap<int> edge_map(graph);
|
||||
Graph::Node node;
|
||||
Graph::Arc arc;
|
||||
Graph::Edge edge;
|
||||
int attr;
|
||||
|
||||
lemon::GraphReader<Graph> reader(graph, "filename");
|
||||
reader.nodeMap("node_map", node_map);
|
||||
reader.nodeMap("node_map", node_map, ReaderConverter());
|
||||
reader.arcMap("arc_map", arc_map);
|
||||
reader.arcMap("arc_map", arc_map, ReaderConverter());
|
||||
reader.edgeMap("edge_map", edge_map);
|
||||
reader.edgeMap("edge_map", edge_map, ReaderConverter());
|
||||
reader.attribute("attr", attr);
|
||||
reader.attribute("attr", attr, ReaderConverter());
|
||||
reader.node("node", node);
|
||||
reader.arc("arc", arc);
|
||||
|
||||
reader.nodes("alt_nodes_caption");
|
||||
reader.edges("alt_edges_caption");
|
||||
reader.attributes("alt_attrs_caption");
|
||||
|
||||
reader.useNodes(node_map);
|
||||
reader.useNodes(node_map, WriterConverter());
|
||||
reader.useEdges(edge_map);
|
||||
reader.useEdges(edge_map, WriterConverter());
|
||||
|
||||
reader.skipNodes();
|
||||
reader.skipEdges();
|
||||
|
||||
reader.run();
|
||||
|
||||
lemon::GraphReader<Graph> reader2(graph, std::cin);
|
||||
}
|
||||
|
||||
void checkGraphWriterCompile() {
|
||||
typedef lemon::concepts::Graph Graph;
|
||||
Graph graph;
|
||||
Graph::NodeMap<int> node_map(graph);
|
||||
Graph::ArcMap<int> arc_map(graph);
|
||||
Graph::EdgeMap<int> edge_map(graph);
|
||||
Graph::Node node;
|
||||
Graph::Arc arc;
|
||||
Graph::Edge edge;
|
||||
int attr;
|
||||
|
||||
lemon::GraphWriter<Graph> writer(graph, "filename");
|
||||
writer.nodeMap("node_map", node_map);
|
||||
writer.nodeMap("node_map", node_map, WriterConverter());
|
||||
writer.arcMap("arc_map", arc_map);
|
||||
writer.arcMap("arc_map", arc_map, WriterConverter());
|
||||
writer.edgeMap("edge_map", edge_map);
|
||||
writer.edgeMap("edge_map", edge_map, WriterConverter());
|
||||
writer.attribute("attr", attr);
|
||||
writer.attribute("attr", attr, WriterConverter());
|
||||
writer.node("node", node);
|
||||
writer.arc("arc", arc);
|
||||
writer.edge("edge", edge);
|
||||
|
||||
writer.nodes("alt_nodes_caption");
|
||||
writer.edges("alt_edges_caption");
|
||||
writer.attributes("alt_attrs_caption");
|
||||
|
||||
writer.skipNodes();
|
||||
writer.skipEdges();
|
||||
|
||||
writer.run();
|
||||
|
||||
lemon::GraphWriter<Graph> writer2(graph, std::cout);
|
||||
}
|
||||
|
||||
void checkBpGraphReaderCompile() {
|
||||
typedef lemon::concepts::ExtendableBpGraphComponent<
|
||||
lemon::concepts::BpGraph> BpGraph;
|
||||
BpGraph graph;
|
||||
BpGraph::NodeMap<int> node_map(graph);
|
||||
BpGraph::RedNodeMap<int> red_node_map(graph);
|
||||
BpGraph::BlueNodeMap<int> blue_node_map(graph);
|
||||
BpGraph::ArcMap<int> arc_map(graph);
|
||||
BpGraph::EdgeMap<int> edge_map(graph);
|
||||
BpGraph::Node node;
|
||||
BpGraph::RedNode red_node;
|
||||
BpGraph::BlueNode blue_node;
|
||||
BpGraph::Arc arc;
|
||||
BpGraph::Edge edge;
|
||||
int attr;
|
||||
|
||||
lemon::BpGraphReader<BpGraph> reader(graph, "filename");
|
||||
reader.nodeMap("node_map", node_map);
|
||||
reader.nodeMap("node_map", node_map, ReaderConverter());
|
||||
reader.redNodeMap("red_node_map", red_node_map);
|
||||
reader.redNodeMap("red_node_map", red_node_map, ReaderConverter());
|
||||
reader.blueNodeMap("blue_node_map", blue_node_map);
|
||||
reader.blueNodeMap("blue_node_map", blue_node_map, ReaderConverter());
|
||||
reader.arcMap("arc_map", arc_map);
|
||||
reader.arcMap("arc_map", arc_map, ReaderConverter());
|
||||
reader.edgeMap("edge_map", edge_map);
|
||||
reader.edgeMap("edge_map", edge_map, ReaderConverter());
|
||||
reader.attribute("attr", attr);
|
||||
reader.attribute("attr", attr, ReaderConverter());
|
||||
reader.node("node", node);
|
||||
reader.redNode("red_node", red_node);
|
||||
reader.blueNode("blue_node", blue_node);
|
||||
reader.arc("arc", arc);
|
||||
|
||||
reader.nodes("alt_nodes_caption");
|
||||
reader.edges("alt_edges_caption");
|
||||
reader.attributes("alt_attrs_caption");
|
||||
|
||||
reader.useNodes(node_map);
|
||||
reader.useNodes(node_map, WriterConverter());
|
||||
reader.useEdges(edge_map);
|
||||
reader.useEdges(edge_map, WriterConverter());
|
||||
|
||||
reader.skipNodes();
|
||||
reader.skipEdges();
|
||||
|
||||
reader.run();
|
||||
|
||||
lemon::BpGraphReader<BpGraph> reader2(graph, std::cin);
|
||||
}
|
||||
|
||||
void checkBpGraphWriterCompile() {
|
||||
typedef lemon::concepts::BpGraph BpGraph;
|
||||
BpGraph graph;
|
||||
BpGraph::NodeMap<int> node_map(graph);
|
||||
BpGraph::RedNodeMap<int> red_node_map(graph);
|
||||
BpGraph::BlueNodeMap<int> blue_node_map(graph);
|
||||
BpGraph::ArcMap<int> arc_map(graph);
|
||||
BpGraph::EdgeMap<int> edge_map(graph);
|
||||
BpGraph::Node node;
|
||||
BpGraph::RedNode red_node;
|
||||
BpGraph::BlueNode blue_node;
|
||||
BpGraph::Arc arc;
|
||||
BpGraph::Edge edge;
|
||||
int attr;
|
||||
|
||||
lemon::BpGraphWriter<BpGraph> writer(graph, "filename");
|
||||
writer.nodeMap("node_map", node_map);
|
||||
writer.nodeMap("node_map", node_map, WriterConverter());
|
||||
writer.redNodeMap("red_node_map", red_node_map);
|
||||
writer.redNodeMap("red_node_map", red_node_map, WriterConverter());
|
||||
writer.blueNodeMap("blue_node_map", blue_node_map);
|
||||
writer.blueNodeMap("blue_node_map", blue_node_map, WriterConverter());
|
||||
writer.arcMap("arc_map", arc_map);
|
||||
writer.arcMap("arc_map", arc_map, WriterConverter());
|
||||
writer.edgeMap("edge_map", edge_map);
|
||||
writer.edgeMap("edge_map", edge_map, WriterConverter());
|
||||
writer.attribute("attr", attr);
|
||||
writer.attribute("attr", attr, WriterConverter());
|
||||
writer.node("node", node);
|
||||
writer.redNode("red_node", red_node);
|
||||
writer.blueNode("blue_node", blue_node);
|
||||
writer.arc("arc", arc);
|
||||
|
||||
writer.nodes("alt_nodes_caption");
|
||||
writer.edges("alt_edges_caption");
|
||||
writer.attributes("alt_attrs_caption");
|
||||
|
||||
writer.skipNodes();
|
||||
writer.skipEdges();
|
||||
|
||||
writer.run();
|
||||
|
||||
lemon::BpGraphWriter<BpGraph> writer2(graph, std::cout);
|
||||
}
|
||||
|
||||
void checkDigraphReaderWriter() {
|
||||
typedef lemon::SmartDigraph Digraph;
|
||||
Digraph digraph;
|
||||
Digraph::Node n1 = digraph.addNode();
|
||||
Digraph::Node n2 = digraph.addNode();
|
||||
Digraph::Node n3 = digraph.addNode();
|
||||
|
||||
Digraph::Arc a1 = digraph.addArc(n1, n2);
|
||||
Digraph::Arc a2 = digraph.addArc(n2, n3);
|
||||
|
||||
Digraph::NodeMap<int> node_map(digraph);
|
||||
node_map[n1] = 11;
|
||||
node_map[n2] = 12;
|
||||
node_map[n3] = 13;
|
||||
|
||||
Digraph::ArcMap<int> arc_map(digraph);
|
||||
arc_map[a1] = 21;
|
||||
arc_map[a2] = 22;
|
||||
|
||||
int attr = 100;
|
||||
|
||||
std::ostringstream os;
|
||||
lemon::DigraphWriter<Digraph> writer(digraph, os);
|
||||
|
||||
writer.nodeMap("node_map1", node_map);
|
||||
writer.nodeMap("node_map2", node_map, WriterConverter());
|
||||
writer.arcMap("arc_map1", arc_map);
|
||||
writer.arcMap("arc_map2", arc_map, WriterConverter());
|
||||
writer.node("node", n2);
|
||||
writer.arc("arc", a1);
|
||||
writer.attribute("attr1", attr);
|
||||
writer.attribute("attr2", attr, WriterConverter());
|
||||
|
||||
writer.run();
|
||||
|
||||
typedef lemon::ListDigraph ExpDigraph;
|
||||
ExpDigraph exp_digraph;
|
||||
ExpDigraph::NodeMap<int> exp_node_map1(exp_digraph);
|
||||
ExpDigraph::NodeMap<int> exp_node_map2(exp_digraph);
|
||||
ExpDigraph::ArcMap<int> exp_arc_map1(exp_digraph);
|
||||
ExpDigraph::ArcMap<int> exp_arc_map2(exp_digraph);
|
||||
ExpDigraph::Node exp_n2;
|
||||
ExpDigraph::Arc exp_a1;
|
||||
int exp_attr1;
|
||||
int exp_attr2;
|
||||
|
||||
std::istringstream is(os.str());
|
||||
lemon::DigraphReader<ExpDigraph> reader(exp_digraph, is);
|
||||
|
||||
reader.nodeMap("node_map1", exp_node_map1);
|
||||
reader.nodeMap("node_map2", exp_node_map2, ReaderConverter());
|
||||
reader.arcMap("arc_map1", exp_arc_map1);
|
||||
reader.arcMap("arc_map2", exp_arc_map2, ReaderConverter());
|
||||
reader.node("node", exp_n2);
|
||||
reader.arc("arc", exp_a1);
|
||||
reader.attribute("attr1", exp_attr1);
|
||||
reader.attribute("attr2", exp_attr2, ReaderConverter());
|
||||
|
||||
reader.run();
|
||||
|
||||
check(lemon::countNodes(exp_digraph) == 3, "Wrong number of nodes");
|
||||
check(lemon::countArcs(exp_digraph) == 2, "Wrong number of arcs");
|
||||
check(exp_node_map1[exp_n2] == 12, "Wrong map value");
|
||||
check(exp_node_map2[exp_n2] == 12, "Wrong map value");
|
||||
check(exp_arc_map1[exp_a1] == 21, "Wrong map value");
|
||||
check(exp_arc_map2[exp_a1] == 21, "Wrong map value");
|
||||
check(exp_attr1 == 100, "Wrong attr value");
|
||||
check(exp_attr2 == 100, "Wrong attr value");
|
||||
}
|
||||
|
||||
void checkGraphReaderWriter() {
|
||||
typedef lemon::SmartGraph Graph;
|
||||
Graph graph;
|
||||
Graph::Node n1 = graph.addNode();
|
||||
Graph::Node n2 = graph.addNode();
|
||||
Graph::Node n3 = graph.addNode();
|
||||
|
||||
Graph::Edge e1 = graph.addEdge(n1, n2);
|
||||
Graph::Edge e2 = graph.addEdge(n2, n3);
|
||||
|
||||
Graph::NodeMap<int> node_map(graph);
|
||||
node_map[n1] = 11;
|
||||
node_map[n2] = 12;
|
||||
node_map[n3] = 13;
|
||||
|
||||
Graph::EdgeMap<int> edge_map(graph);
|
||||
edge_map[e1] = 21;
|
||||
edge_map[e2] = 22;
|
||||
|
||||
Graph::ArcMap<int> arc_map(graph);
|
||||
arc_map[graph.direct(e1, true)] = 211;
|
||||
arc_map[graph.direct(e1, false)] = 212;
|
||||
arc_map[graph.direct(e2, true)] = 221;
|
||||
arc_map[graph.direct(e2, false)] = 222;
|
||||
|
||||
int attr = 100;
|
||||
|
||||
std::ostringstream os;
|
||||
lemon::GraphWriter<Graph> writer(graph, os);
|
||||
|
||||
writer.nodeMap("node_map1", node_map);
|
||||
writer.nodeMap("node_map2", node_map, WriterConverter());
|
||||
writer.edgeMap("edge_map1", edge_map);
|
||||
writer.edgeMap("edge_map2", edge_map, WriterConverter());
|
||||
writer.arcMap("arc_map1", arc_map);
|
||||
writer.arcMap("arc_map2", arc_map, WriterConverter());
|
||||
writer.node("node", n2);
|
||||
writer.edge("edge", e1);
|
||||
writer.arc("arc", graph.direct(e1, false));
|
||||
writer.attribute("attr1", attr);
|
||||
writer.attribute("attr2", attr, WriterConverter());
|
||||
|
||||
writer.run();
|
||||
|
||||
typedef lemon::ListGraph ExpGraph;
|
||||
ExpGraph exp_graph;
|
||||
ExpGraph::NodeMap<int> exp_node_map1(exp_graph);
|
||||
ExpGraph::NodeMap<int> exp_node_map2(exp_graph);
|
||||
ExpGraph::EdgeMap<int> exp_edge_map1(exp_graph);
|
||||
ExpGraph::EdgeMap<int> exp_edge_map2(exp_graph);
|
||||
ExpGraph::ArcMap<int> exp_arc_map1(exp_graph);
|
||||
ExpGraph::ArcMap<int> exp_arc_map2(exp_graph);
|
||||
ExpGraph::Node exp_n2;
|
||||
ExpGraph::Edge exp_e1;
|
||||
ExpGraph::Arc exp_a1;
|
||||
int exp_attr1;
|
||||
int exp_attr2;
|
||||
|
||||
std::istringstream is(os.str());
|
||||
lemon::GraphReader<ExpGraph> reader(exp_graph, is);
|
||||
|
||||
reader.nodeMap("node_map1", exp_node_map1);
|
||||
reader.nodeMap("node_map2", exp_node_map2, ReaderConverter());
|
||||
reader.edgeMap("edge_map1", exp_edge_map1);
|
||||
reader.edgeMap("edge_map2", exp_edge_map2, ReaderConverter());
|
||||
reader.arcMap("arc_map1", exp_arc_map1);
|
||||
reader.arcMap("arc_map2", exp_arc_map2, ReaderConverter());
|
||||
reader.node("node", exp_n2);
|
||||
reader.edge("edge", exp_e1);
|
||||
reader.arc("arc", exp_a1);
|
||||
reader.attribute("attr1", exp_attr1);
|
||||
reader.attribute("attr2", exp_attr2, ReaderConverter());
|
||||
|
||||
reader.run();
|
||||
|
||||
check(lemon::countNodes(exp_graph) == 3, "Wrong number of nodes");
|
||||
check(lemon::countEdges(exp_graph) == 2, "Wrong number of edges");
|
||||
check(lemon::countArcs(exp_graph) == 4, "Wrong number of arcs");
|
||||
check(exp_node_map1[exp_n2] == 12, "Wrong map value");
|
||||
check(exp_node_map2[exp_n2] == 12, "Wrong map value");
|
||||
check(exp_edge_map1[exp_e1] == 21, "Wrong map value");
|
||||
check(exp_edge_map2[exp_e1] == 21, "Wrong map value");
|
||||
check(exp_arc_map1[exp_a1] == 212, "Wrong map value");
|
||||
check(exp_arc_map2[exp_a1] == 212, "Wrong map value");
|
||||
check(exp_attr1 == 100, "Wrong attr value");
|
||||
check(exp_attr2 == 100, "Wrong attr value");
|
||||
}
|
||||
|
||||
void checkBpGraphReaderWriter() {
|
||||
typedef lemon::SmartBpGraph Graph;
|
||||
Graph graph;
|
||||
Graph::RedNode rn1 = graph.addRedNode();
|
||||
Graph::RedNode rn2 = graph.addRedNode();
|
||||
Graph::RedNode rn3 = graph.addRedNode();
|
||||
Graph::BlueNode bn1 = graph.addBlueNode();
|
||||
Graph::BlueNode bn2 = graph.addBlueNode();
|
||||
Graph::Node n = bn1;
|
||||
|
||||
Graph::Edge e1 = graph.addEdge(rn1, bn1);
|
||||
Graph::Edge e2 = graph.addEdge(rn2, bn1);
|
||||
|
||||
Graph::NodeMap<int> node_map(graph);
|
||||
node_map[rn1] = 11;
|
||||
node_map[rn2] = 12;
|
||||
node_map[rn3] = 13;
|
||||
node_map[bn1] = 14;
|
||||
node_map[bn2] = 15;
|
||||
|
||||
Graph::NodeMap<int> red_node_map(graph);
|
||||
red_node_map[rn1] = 411;
|
||||
red_node_map[rn2] = 412;
|
||||
red_node_map[rn3] = 413;
|
||||
|
||||
Graph::NodeMap<int> blue_node_map(graph);
|
||||
blue_node_map[bn1] = 414;
|
||||
blue_node_map[bn2] = 415;
|
||||
|
||||
Graph::EdgeMap<int> edge_map(graph);
|
||||
edge_map[e1] = 21;
|
||||
edge_map[e2] = 22;
|
||||
|
||||
Graph::ArcMap<int> arc_map(graph);
|
||||
arc_map[graph.direct(e1, true)] = 211;
|
||||
arc_map[graph.direct(e1, false)] = 212;
|
||||
arc_map[graph.direct(e2, true)] = 221;
|
||||
arc_map[graph.direct(e2, false)] = 222;
|
||||
|
||||
int attr = 100;
|
||||
|
||||
std::ostringstream os;
|
||||
lemon::BpGraphWriter<Graph> writer(graph, os);
|
||||
|
||||
writer.nodeMap("node_map1", node_map);
|
||||
writer.nodeMap("node_map2", node_map, WriterConverter());
|
||||
writer.nodeMap("red_node_map1", red_node_map);
|
||||
writer.nodeMap("red_node_map2", red_node_map, WriterConverter());
|
||||
writer.nodeMap("blue_node_map1", blue_node_map);
|
||||
writer.nodeMap("blue_node_map2", blue_node_map, WriterConverter());
|
||||
writer.edgeMap("edge_map1", edge_map);
|
||||
writer.edgeMap("edge_map2", edge_map, WriterConverter());
|
||||
writer.arcMap("arc_map1", arc_map);
|
||||
writer.arcMap("arc_map2", arc_map, WriterConverter());
|
||||
writer.node("node", n);
|
||||
writer.redNode("red_node", rn1);
|
||||
writer.blueNode("blue_node", bn2);
|
||||
writer.edge("edge", e1);
|
||||
writer.arc("arc", graph.direct(e1, false));
|
||||
writer.attribute("attr1", attr);
|
||||
writer.attribute("attr2", attr, WriterConverter());
|
||||
|
||||
writer.run();
|
||||
|
||||
typedef lemon::ListBpGraph ExpGraph;
|
||||
ExpGraph exp_graph;
|
||||
ExpGraph::NodeMap<int> exp_node_map1(exp_graph);
|
||||
ExpGraph::NodeMap<int> exp_node_map2(exp_graph);
|
||||
ExpGraph::RedNodeMap<int> exp_red_node_map1(exp_graph);
|
||||
ExpGraph::RedNodeMap<int> exp_red_node_map2(exp_graph);
|
||||
ExpGraph::BlueNodeMap<int> exp_blue_node_map1(exp_graph);
|
||||
ExpGraph::BlueNodeMap<int> exp_blue_node_map2(exp_graph);
|
||||
ExpGraph::EdgeMap<int> exp_edge_map1(exp_graph);
|
||||
ExpGraph::EdgeMap<int> exp_edge_map2(exp_graph);
|
||||
ExpGraph::ArcMap<int> exp_arc_map1(exp_graph);
|
||||
ExpGraph::ArcMap<int> exp_arc_map2(exp_graph);
|
||||
ExpGraph::Node exp_n;
|
||||
ExpGraph::RedNode exp_rn1;
|
||||
ExpGraph::BlueNode exp_bn2;
|
||||
ExpGraph::Edge exp_e1;
|
||||
ExpGraph::Arc exp_a1;
|
||||
int exp_attr1;
|
||||
int exp_attr2;
|
||||
|
||||
std::istringstream is(os.str());
|
||||
lemon::BpGraphReader<ExpGraph> reader(exp_graph, is);
|
||||
|
||||
reader.nodeMap("node_map1", exp_node_map1);
|
||||
reader.nodeMap("node_map2", exp_node_map2, ReaderConverter());
|
||||
reader.redNodeMap("red_node_map1", exp_red_node_map1);
|
||||
reader.redNodeMap("red_node_map2", exp_red_node_map2, ReaderConverter());
|
||||
reader.blueNodeMap("blue_node_map1", exp_blue_node_map1);
|
||||
reader.blueNodeMap("blue_node_map2", exp_blue_node_map2, ReaderConverter());
|
||||
reader.edgeMap("edge_map1", exp_edge_map1);
|
||||
reader.edgeMap("edge_map2", exp_edge_map2, ReaderConverter());
|
||||
reader.arcMap("arc_map1", exp_arc_map1);
|
||||
reader.arcMap("arc_map2", exp_arc_map2, ReaderConverter());
|
||||
reader.node("node", exp_n);
|
||||
reader.redNode("red_node", exp_rn1);
|
||||
reader.blueNode("blue_node", exp_bn2);
|
||||
reader.edge("edge", exp_e1);
|
||||
reader.arc("arc", exp_a1);
|
||||
reader.attribute("attr1", exp_attr1);
|
||||
reader.attribute("attr2", exp_attr2, ReaderConverter());
|
||||
|
||||
reader.run();
|
||||
|
||||
check(lemon::countNodes(exp_graph) == 5, "Wrong number of nodes");
|
||||
check(lemon::countRedNodes(exp_graph) == 3, "Wrong number of red nodes");
|
||||
check(lemon::countBlueNodes(exp_graph) == 2, "Wrong number of blue nodes");
|
||||
check(lemon::countEdges(exp_graph) == 2, "Wrong number of edges");
|
||||
check(lemon::countArcs(exp_graph) == 4, "Wrong number of arcs");
|
||||
check(exp_node_map1[exp_n] == 14, "Wrong map value");
|
||||
check(exp_node_map2[exp_n] == 14, "Wrong map value");
|
||||
check(exp_red_node_map1[exp_rn1] == 411, "Wrong map value");
|
||||
check(exp_red_node_map2[exp_rn1] == 411, "Wrong map value");
|
||||
check(exp_blue_node_map1[exp_bn2] == 415, "Wrong map value");
|
||||
check(exp_blue_node_map2[exp_bn2] == 415, "Wrong map value");
|
||||
check(exp_edge_map1[exp_e1] == 21, "Wrong map value");
|
||||
check(exp_edge_map2[exp_e1] == 21, "Wrong map value");
|
||||
check(exp_arc_map1[exp_a1] == 212, "Wrong map value");
|
||||
check(exp_arc_map2[exp_a1] == 212, "Wrong map value");
|
||||
check(exp_attr1 == 100, "Wrong attr value");
|
||||
check(exp_attr2 == 100, "Wrong attr value");
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
{ // Check digrpah
|
||||
checkDigraphReaderWriter();
|
||||
}
|
||||
{ // Check graph
|
||||
checkGraphReaderWriter();
|
||||
}
|
||||
{ // Check bipartite graph
|
||||
checkBpGraphReaderWriter();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
169
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/lgf_test.cc
vendored
Normal file
169
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/lgf_test.cc
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/list_graph.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
char test_lgf[] =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"@arcs\n"
|
||||
" label\n"
|
||||
"0 1 0\n"
|
||||
"1 0 1\n"
|
||||
"@attributes\n"
|
||||
"source 0\n"
|
||||
"target 1\n";
|
||||
|
||||
char test_lgf_nomap[] =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"@arcs\n"
|
||||
" -\n"
|
||||
"0 1\n";
|
||||
|
||||
char test_lgf_bad1[] =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"@arcs\n"
|
||||
" - another\n"
|
||||
"0 1\n";
|
||||
|
||||
char test_lgf_bad2[] =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"@arcs\n"
|
||||
" label -\n"
|
||||
"0 1\n";
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
ListDigraph d;
|
||||
ListDigraph::Node s,t;
|
||||
ListDigraph::ArcMap<int> label(d);
|
||||
std::istringstream input(test_lgf);
|
||||
digraphReader(d, input).
|
||||
node("source", s).
|
||||
node("target", t).
|
||||
arcMap("label", label).
|
||||
run();
|
||||
check(countNodes(d) == 2,"There should be 2 nodes");
|
||||
check(countArcs(d) == 2,"There should be 2 arcs");
|
||||
}
|
||||
{
|
||||
ListGraph g;
|
||||
ListGraph::Node s,t;
|
||||
ListGraph::EdgeMap<int> label(g);
|
||||
std::istringstream input(test_lgf);
|
||||
graphReader(g, input).
|
||||
node("source", s).
|
||||
node("target", t).
|
||||
edgeMap("label", label).
|
||||
run();
|
||||
check(countNodes(g) == 2,"There should be 2 nodes");
|
||||
check(countEdges(g) == 2,"There should be 2 arcs");
|
||||
}
|
||||
|
||||
{
|
||||
ListDigraph d;
|
||||
std::istringstream input(test_lgf_nomap);
|
||||
digraphReader(d, input).
|
||||
run();
|
||||
check(countNodes(d) == 2,"There should be 2 nodes");
|
||||
check(countArcs(d) == 1,"There should be 1 arc");
|
||||
}
|
||||
{
|
||||
ListGraph g;
|
||||
std::istringstream input(test_lgf_nomap);
|
||||
graphReader(g, input).
|
||||
run();
|
||||
check(countNodes(g) == 2,"There should be 2 nodes");
|
||||
check(countEdges(g) == 1,"There should be 1 edge");
|
||||
}
|
||||
|
||||
{
|
||||
ListDigraph d;
|
||||
std::istringstream input(test_lgf_bad1);
|
||||
bool ok=false;
|
||||
try {
|
||||
digraphReader(d, input).
|
||||
run();
|
||||
}
|
||||
catch (FormatError&)
|
||||
{
|
||||
ok = true;
|
||||
}
|
||||
check(ok,"FormatError exception should have occured");
|
||||
}
|
||||
{
|
||||
ListGraph g;
|
||||
std::istringstream input(test_lgf_bad1);
|
||||
bool ok=false;
|
||||
try {
|
||||
graphReader(g, input).
|
||||
run();
|
||||
}
|
||||
catch (FormatError&)
|
||||
{
|
||||
ok = true;
|
||||
}
|
||||
check(ok,"FormatError exception should have occured");
|
||||
}
|
||||
|
||||
{
|
||||
ListDigraph d;
|
||||
std::istringstream input(test_lgf_bad2);
|
||||
bool ok=false;
|
||||
try {
|
||||
digraphReader(d, input).
|
||||
run();
|
||||
}
|
||||
catch (FormatError&)
|
||||
{
|
||||
ok = true;
|
||||
}
|
||||
check(ok,"FormatError exception should have occured");
|
||||
}
|
||||
{
|
||||
ListGraph g;
|
||||
std::istringstream input(test_lgf_bad2);
|
||||
bool ok=false;
|
||||
try {
|
||||
graphReader(g, input).
|
||||
run();
|
||||
}
|
||||
catch (FormatError&)
|
||||
{
|
||||
ok = true;
|
||||
}
|
||||
check(ok,"FormatError exception should have occured");
|
||||
}
|
||||
}
|
||||
470
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/lp_test.cc
vendored
Normal file
470
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/lp_test.cc
vendored
Normal file
@@ -0,0 +1,470 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include <lemon/lp_skeleton.h>
|
||||
#include "test_tools.h"
|
||||
#include <lemon/tolerance.h>
|
||||
|
||||
#include <lemon/config.h>
|
||||
|
||||
#ifdef LEMON_HAVE_GLPK
|
||||
#include <lemon/glpk.h>
|
||||
#endif
|
||||
|
||||
#ifdef LEMON_HAVE_CPLEX
|
||||
#include <lemon/cplex.h>
|
||||
#endif
|
||||
|
||||
#ifdef LEMON_HAVE_SOPLEX
|
||||
#include <lemon/soplex.h>
|
||||
#endif
|
||||
|
||||
#ifdef LEMON_HAVE_CLP
|
||||
#include <lemon/clp.h>
|
||||
#endif
|
||||
|
||||
#ifdef LEMON_HAVE_LP
|
||||
#include <lemon/lp.h>
|
||||
#endif
|
||||
using namespace lemon;
|
||||
|
||||
int countCols(LpBase & lp) {
|
||||
int count=0;
|
||||
for (LpBase::ColIt c(lp); c!=INVALID; ++c) ++count;
|
||||
return count;
|
||||
}
|
||||
|
||||
int countRows(LpBase & lp) {
|
||||
int count=0;
|
||||
for (LpBase::RowIt r(lp); r!=INVALID; ++r) ++count;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
void lpTest(LpSolver& lp)
|
||||
{
|
||||
|
||||
typedef LpSolver LP;
|
||||
|
||||
// Test LpBase::clear()
|
||||
check(countRows(lp)==0, "Wrong number of rows");
|
||||
check(countCols(lp)==0, "Wrong number of cols");
|
||||
lp.addCol(); lp.addRow(); lp.addRow();
|
||||
check(countRows(lp)==2, "Wrong number of rows");
|
||||
check(countCols(lp)==1, "Wrong number of cols");
|
||||
lp.clear();
|
||||
check(countRows(lp)==0, "Wrong number of rows");
|
||||
check(countCols(lp)==0, "Wrong number of cols");
|
||||
lp.addCol(); lp.addCol(); lp.addCol(); lp.addRow();
|
||||
check(countRows(lp)==1, "Wrong number of rows");
|
||||
check(countCols(lp)==3, "Wrong number of cols");
|
||||
lp.clear();
|
||||
|
||||
std::vector<LP::Col> x(10);
|
||||
// for(int i=0;i<10;i++) x.push_back(lp.addCol());
|
||||
lp.addColSet(x);
|
||||
lp.colLowerBound(x,1);
|
||||
lp.colUpperBound(x,1);
|
||||
lp.colBounds(x,1,2);
|
||||
|
||||
std::vector<LP::Col> y(10);
|
||||
lp.addColSet(y);
|
||||
|
||||
lp.colLowerBound(y,1);
|
||||
lp.colUpperBound(y,1);
|
||||
lp.colBounds(y,1,2);
|
||||
|
||||
std::map<int,LP::Col> z;
|
||||
|
||||
z.insert(std::make_pair(12,INVALID));
|
||||
z.insert(std::make_pair(2,INVALID));
|
||||
z.insert(std::make_pair(7,INVALID));
|
||||
z.insert(std::make_pair(5,INVALID));
|
||||
|
||||
lp.addColSet(z);
|
||||
|
||||
lp.colLowerBound(z,1);
|
||||
lp.colUpperBound(z,1);
|
||||
lp.colBounds(z,1,2);
|
||||
|
||||
{
|
||||
LP::Expr e,f,g;
|
||||
LP::Col p1,p2,p3,p4,p5;
|
||||
LP::Constr c;
|
||||
|
||||
p1=lp.addCol();
|
||||
p2=lp.addCol();
|
||||
p3=lp.addCol();
|
||||
p4=lp.addCol();
|
||||
p5=lp.addCol();
|
||||
|
||||
e[p1]=2;
|
||||
*e=12;
|
||||
e[p1]+=2;
|
||||
*e+=12;
|
||||
e[p1]-=2;
|
||||
*e-=12;
|
||||
|
||||
e=2;
|
||||
e=2.2;
|
||||
e=p1;
|
||||
e=f;
|
||||
|
||||
e+=2;
|
||||
e+=2.2;
|
||||
e+=p1;
|
||||
e+=f;
|
||||
|
||||
e-=2;
|
||||
e-=2.2;
|
||||
e-=p1;
|
||||
e-=f;
|
||||
|
||||
e*=2;
|
||||
e*=2.2;
|
||||
e/=2;
|
||||
e/=2.2;
|
||||
|
||||
e=((p1+p2)+(p1-p2)+(p1+12)+(12+p1)+(p1-12)+(12-p1)+
|
||||
(f+12)+(12+f)+(p1+f)+(f+p1)+(f+g)+
|
||||
(f-12)+(12-f)+(p1-f)+(f-p1)+(f-g)+
|
||||
2.2*f+f*2.2+f/2.2+
|
||||
2*f+f*2+f/2+
|
||||
2.2*p1+p1*2.2+p1/2.2+
|
||||
2*p1+p1*2+p1/2
|
||||
);
|
||||
|
||||
|
||||
c = (e <= f );
|
||||
c = (e <= 2.2);
|
||||
c = (e <= 2 );
|
||||
c = (e <= p1 );
|
||||
c = (2.2<= f );
|
||||
c = (2 <= f );
|
||||
c = (p1 <= f );
|
||||
c = (p1 <= p2 );
|
||||
c = (p1 <= 2.2);
|
||||
c = (p1 <= 2 );
|
||||
c = (2.2<= p2 );
|
||||
c = (2 <= p2 );
|
||||
|
||||
c = (e >= f );
|
||||
c = (e >= 2.2);
|
||||
c = (e >= 2 );
|
||||
c = (e >= p1 );
|
||||
c = (2.2>= f );
|
||||
c = (2 >= f );
|
||||
c = (p1 >= f );
|
||||
c = (p1 >= p2 );
|
||||
c = (p1 >= 2.2);
|
||||
c = (p1 >= 2 );
|
||||
c = (2.2>= p2 );
|
||||
c = (2 >= p2 );
|
||||
|
||||
c = (e == f );
|
||||
c = (e == 2.2);
|
||||
c = (e == 2 );
|
||||
c = (e == p1 );
|
||||
c = (2.2== f );
|
||||
c = (2 == f );
|
||||
c = (p1 == f );
|
||||
//c = (p1 == p2 );
|
||||
c = (p1 == 2.2);
|
||||
c = (p1 == 2 );
|
||||
c = (2.2== p2 );
|
||||
c = (2 == p2 );
|
||||
|
||||
c = ((2 <= e) <= 3);
|
||||
c = ((2 <= p1) <= 3);
|
||||
|
||||
c = ((2 >= e) >= 3);
|
||||
c = ((2 >= p1) >= 3);
|
||||
|
||||
{ //Tests for #430
|
||||
LP::Col v=lp.addCol();
|
||||
LP::Constr c = v >= -3;
|
||||
c = c <= 4;
|
||||
LP::Constr c2;
|
||||
#if ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 3 )
|
||||
c2 = ( -3 <= v ) <= 4;
|
||||
#else
|
||||
c2 = -3 <= v <= 4;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
e[x[3]]=2;
|
||||
e[x[3]]=4;
|
||||
e[x[3]]=1;
|
||||
*e=12;
|
||||
|
||||
lp.addRow(-LP::INF,e,23);
|
||||
lp.addRow(-LP::INF,3.0*(x[1]+x[2]/2)-x[3],23);
|
||||
lp.addRow(-LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23);
|
||||
|
||||
lp.addRow(x[1]+x[3]<=x[5]-3);
|
||||
lp.addRow((-7<=x[1]+x[3]-12)<=3);
|
||||
lp.addRow(x[1]<=x[5]);
|
||||
|
||||
std::ostringstream buf;
|
||||
|
||||
|
||||
e=((p1+p2)+(p1-0.99*p2));
|
||||
//e.prettyPrint(std::cout);
|
||||
//(e<=2).prettyPrint(std::cout);
|
||||
double tolerance=0.001;
|
||||
e.simplify(tolerance);
|
||||
buf << "Coeff. of p2 should be 0.01";
|
||||
check(e[p2]>0, buf.str());
|
||||
|
||||
tolerance=0.02;
|
||||
e.simplify(tolerance);
|
||||
buf << "Coeff. of p2 should be 0";
|
||||
check(const_cast<const LpSolver::Expr&>(e)[p2]==0, buf.str());
|
||||
|
||||
//Test for clone/new
|
||||
LP* lpnew = lp.newSolver();
|
||||
LP* lpclone = lp.cloneSolver();
|
||||
delete lpnew;
|
||||
delete lpclone;
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
LP::DualExpr e,f,g;
|
||||
LP::Row p1 = INVALID, p2 = INVALID;
|
||||
|
||||
e[p1]=2;
|
||||
e[p1]+=2;
|
||||
e[p1]-=2;
|
||||
|
||||
e=p1;
|
||||
e=f;
|
||||
|
||||
e+=p1;
|
||||
e+=f;
|
||||
|
||||
e-=p1;
|
||||
e-=f;
|
||||
|
||||
e*=2;
|
||||
e*=2.2;
|
||||
e/=2;
|
||||
e/=2.2;
|
||||
|
||||
e=((p1+p2)+(p1-p2)+
|
||||
(p1+f)+(f+p1)+(f+g)+
|
||||
(p1-f)+(f-p1)+(f-g)+
|
||||
2.2*f+f*2.2+f/2.2+
|
||||
2*f+f*2+f/2+
|
||||
2.2*p1+p1*2.2+p1/2.2+
|
||||
2*p1+p1*2+p1/2
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void solveAndCheck(LpSolver& lp, LpSolver::ProblemType stat,
|
||||
double exp_opt) {
|
||||
using std::string;
|
||||
lp.solve();
|
||||
|
||||
std::ostringstream buf;
|
||||
buf << "PrimalType should be: " << int(stat) << int(lp.primalType());
|
||||
|
||||
check(lp.primalType()==stat, buf.str());
|
||||
|
||||
if (stat == LpSolver::OPTIMAL) {
|
||||
std::ostringstream sbuf;
|
||||
sbuf << "Wrong optimal value (" << lp.primal() <<") with "
|
||||
<< lp.solverName() <<"\n the right optimum is " << exp_opt;
|
||||
check(std::abs(lp.primal()-exp_opt) < 1e-3, sbuf.str());
|
||||
}
|
||||
}
|
||||
|
||||
void aTest(LpSolver & lp)
|
||||
{
|
||||
typedef LpSolver LP;
|
||||
|
||||
//The following example is very simple
|
||||
|
||||
typedef LpSolver::Row Row;
|
||||
typedef LpSolver::Col Col;
|
||||
|
||||
|
||||
Col x1 = lp.addCol();
|
||||
Col x2 = lp.addCol();
|
||||
|
||||
|
||||
//Constraints
|
||||
Row upright=lp.addRow(x1+2*x2 <=1);
|
||||
lp.addRow(x1+x2 >=-1);
|
||||
lp.addRow(x1-x2 <=1);
|
||||
lp.addRow(x1-x2 >=-1);
|
||||
//Nonnegativity of the variables
|
||||
lp.colLowerBound(x1, 0);
|
||||
lp.colLowerBound(x2, 0);
|
||||
//Objective function
|
||||
lp.obj(x1+x2);
|
||||
|
||||
lp.sense(lp.MAX);
|
||||
|
||||
//Testing the problem retrieving routines
|
||||
check(lp.objCoeff(x1)==1,"First term should be 1 in the obj function!");
|
||||
check(lp.sense() == lp.MAX,"This is a maximization!");
|
||||
check(lp.coeff(upright,x1)==1,"The coefficient in question is 1!");
|
||||
check(lp.colLowerBound(x1)==0,
|
||||
"The lower bound for variable x1 should be 0.");
|
||||
check(lp.colUpperBound(x1)==LpSolver::INF,
|
||||
"The upper bound for variable x1 should be infty.");
|
||||
check(lp.rowLowerBound(upright) == -LpSolver::INF,
|
||||
"The lower bound for the first row should be -infty.");
|
||||
check(lp.rowUpperBound(upright)==1,
|
||||
"The upper bound for the first row should be 1.");
|
||||
LpSolver::Expr e = lp.row(upright);
|
||||
check(e[x1] == 1, "The first coefficient should 1.");
|
||||
check(e[x2] == 2, "The second coefficient should 1.");
|
||||
|
||||
lp.row(upright, x1+x2 <=1);
|
||||
e = lp.row(upright);
|
||||
check(e[x1] == 1, "The first coefficient should 1.");
|
||||
check(e[x2] == 1, "The second coefficient should 1.");
|
||||
|
||||
LpSolver::DualExpr de = lp.col(x1);
|
||||
check( de[upright] == 1, "The first coefficient should 1.");
|
||||
|
||||
LpSolver* clp = lp.cloneSolver();
|
||||
|
||||
//Testing the problem retrieving routines
|
||||
check(clp->objCoeff(x1)==1,"First term should be 1 in the obj function!");
|
||||
check(clp->sense() == clp->MAX,"This is a maximization!");
|
||||
check(clp->coeff(upright,x1)==1,"The coefficient in question is 1!");
|
||||
// std::cout<<lp.colLowerBound(x1)<<std::endl;
|
||||
check(clp->colLowerBound(x1)==0,
|
||||
"The lower bound for variable x1 should be 0.");
|
||||
check(clp->colUpperBound(x1)==LpSolver::INF,
|
||||
"The upper bound for variable x1 should be infty.");
|
||||
|
||||
check(lp.rowLowerBound(upright)==-LpSolver::INF,
|
||||
"The lower bound for the first row should be -infty.");
|
||||
check(lp.rowUpperBound(upright)==1,
|
||||
"The upper bound for the first row should be 1.");
|
||||
e = clp->row(upright);
|
||||
check(e[x1] == 1, "The first coefficient should 1.");
|
||||
check(e[x2] == 1, "The second coefficient should 1.");
|
||||
|
||||
de = clp->col(x1);
|
||||
check(de[upright] == 1, "The first coefficient should 1.");
|
||||
|
||||
delete clp;
|
||||
|
||||
//Maximization of x1+x2
|
||||
//over the triangle with vertices (0,0) (0,1) (1,0)
|
||||
double expected_opt=1;
|
||||
solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
|
||||
|
||||
//Minimization
|
||||
lp.sense(lp.MIN);
|
||||
expected_opt=0;
|
||||
solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
|
||||
|
||||
//Vertex (-1,0) instead of (0,0)
|
||||
lp.colLowerBound(x1, -LpSolver::INF);
|
||||
expected_opt=-1;
|
||||
solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
|
||||
|
||||
//Erase one constraint and return to maximization
|
||||
lp.erase(upright);
|
||||
lp.sense(lp.MAX);
|
||||
expected_opt=LpSolver::INF;
|
||||
solveAndCheck(lp, LpSolver::UNBOUNDED, expected_opt);
|
||||
|
||||
//Infeasibilty
|
||||
lp.addRow(x1+x2 <=-2);
|
||||
solveAndCheck(lp, LpSolver::INFEASIBLE, expected_opt);
|
||||
|
||||
}
|
||||
|
||||
template<class LP>
|
||||
void cloneTest()
|
||||
{
|
||||
//Test for clone/new
|
||||
|
||||
LP* lp = new LP();
|
||||
LP* lpnew = lp->newSolver();
|
||||
LP* lpclone = lp->cloneSolver();
|
||||
delete lp;
|
||||
delete lpnew;
|
||||
delete lpclone;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
LpSkeleton lp_skel;
|
||||
lpTest(lp_skel);
|
||||
|
||||
#ifdef LEMON_HAVE_LP
|
||||
{
|
||||
Lp lp,lp2;
|
||||
lpTest(lp);
|
||||
aTest(lp2);
|
||||
cloneTest<Lp>();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LEMON_HAVE_GLPK
|
||||
{
|
||||
GlpkLp lp_glpk1,lp_glpk2;
|
||||
lpTest(lp_glpk1);
|
||||
aTest(lp_glpk2);
|
||||
cloneTest<GlpkLp>();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LEMON_HAVE_CPLEX
|
||||
try {
|
||||
CplexLp lp_cplex1,lp_cplex2;
|
||||
lpTest(lp_cplex1);
|
||||
aTest(lp_cplex2);
|
||||
cloneTest<CplexLp>();
|
||||
} catch (CplexEnv::LicenseError& error) {
|
||||
check(false, error.what());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LEMON_HAVE_SOPLEX
|
||||
{
|
||||
SoplexLp lp_soplex1,lp_soplex2;
|
||||
lpTest(lp_soplex1);
|
||||
aTest(lp_soplex2);
|
||||
cloneTest<SoplexLp>();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LEMON_HAVE_CLP
|
||||
{
|
||||
ClpLp lp_clp1,lp_clp2;
|
||||
lpTest(lp_clp1);
|
||||
aTest(lp_clp2);
|
||||
cloneTest<ClpLp>();
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
1022
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/maps_test.cc
vendored
Normal file
1022
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/maps_test.cc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
449
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/matching_test.cc
vendored
Normal file
449
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/matching_test.cc
vendored
Normal file
@@ -0,0 +1,449 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <lemon/matching.h>
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/concepts/graph.h>
|
||||
#include <lemon/concepts/maps.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/math.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace lemon;
|
||||
|
||||
GRAPH_TYPEDEFS(SmartGraph);
|
||||
|
||||
|
||||
const int lgfn = 3;
|
||||
const std::string lgf[lgfn] = {
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"6\n"
|
||||
"7\n"
|
||||
"@edges\n"
|
||||
" label weight\n"
|
||||
"7 4 0 984\n"
|
||||
"0 7 1 73\n"
|
||||
"7 1 2 204\n"
|
||||
"2 3 3 583\n"
|
||||
"2 7 4 565\n"
|
||||
"2 1 5 582\n"
|
||||
"0 4 6 551\n"
|
||||
"2 5 7 385\n"
|
||||
"1 5 8 561\n"
|
||||
"5 3 9 484\n"
|
||||
"7 5 10 904\n"
|
||||
"3 6 11 47\n"
|
||||
"7 6 12 888\n"
|
||||
"3 0 13 747\n"
|
||||
"6 1 14 310\n",
|
||||
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"6\n"
|
||||
"7\n"
|
||||
"@edges\n"
|
||||
" label weight\n"
|
||||
"2 5 0 710\n"
|
||||
"0 5 1 241\n"
|
||||
"2 4 2 856\n"
|
||||
"2 6 3 762\n"
|
||||
"4 1 4 747\n"
|
||||
"6 1 5 962\n"
|
||||
"4 7 6 723\n"
|
||||
"1 7 7 661\n"
|
||||
"2 3 8 376\n"
|
||||
"1 0 9 416\n"
|
||||
"6 7 10 391\n",
|
||||
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"6\n"
|
||||
"7\n"
|
||||
"@edges\n"
|
||||
" label weight\n"
|
||||
"6 2 0 553\n"
|
||||
"0 7 1 653\n"
|
||||
"6 3 2 22\n"
|
||||
"4 7 3 846\n"
|
||||
"7 2 4 981\n"
|
||||
"7 6 5 250\n"
|
||||
"5 2 6 539\n",
|
||||
};
|
||||
|
||||
void checkMaxMatchingCompile()
|
||||
{
|
||||
typedef concepts::Graph Graph;
|
||||
typedef Graph::Node Node;
|
||||
typedef Graph::Edge Edge;
|
||||
typedef Graph::EdgeMap<bool> MatMap;
|
||||
|
||||
Graph g;
|
||||
Node n;
|
||||
Edge e;
|
||||
MatMap mat(g);
|
||||
|
||||
MaxMatching<Graph> mat_test(g);
|
||||
const MaxMatching<Graph>&
|
||||
const_mat_test = mat_test;
|
||||
|
||||
mat_test.init();
|
||||
mat_test.greedyInit();
|
||||
mat_test.matchingInit(mat);
|
||||
mat_test.startSparse();
|
||||
mat_test.startDense();
|
||||
mat_test.run();
|
||||
|
||||
const_mat_test.matchingSize();
|
||||
const_mat_test.matching(e);
|
||||
const_mat_test.matching(n);
|
||||
const MaxMatching<Graph>::MatchingMap& mmap =
|
||||
const_mat_test.matchingMap();
|
||||
e = mmap[n];
|
||||
const_mat_test.mate(n);
|
||||
|
||||
MaxMatching<Graph>::Status stat =
|
||||
const_mat_test.status(n);
|
||||
::lemon::ignore_unused_variable_warning(stat);
|
||||
const MaxMatching<Graph>::StatusMap& smap =
|
||||
const_mat_test.statusMap();
|
||||
stat = smap[n];
|
||||
const_mat_test.barrier(n);
|
||||
}
|
||||
|
||||
void checkMaxWeightedMatchingCompile()
|
||||
{
|
||||
typedef concepts::Graph Graph;
|
||||
typedef Graph::Node Node;
|
||||
typedef Graph::Edge Edge;
|
||||
typedef Graph::EdgeMap<int> WeightMap;
|
||||
|
||||
Graph g;
|
||||
Node n;
|
||||
Edge e;
|
||||
WeightMap w(g);
|
||||
|
||||
MaxWeightedMatching<Graph> mat_test(g, w);
|
||||
const MaxWeightedMatching<Graph>&
|
||||
const_mat_test = mat_test;
|
||||
|
||||
mat_test.init();
|
||||
mat_test.start();
|
||||
mat_test.run();
|
||||
|
||||
const_mat_test.matchingWeight();
|
||||
const_mat_test.matchingSize();
|
||||
const_mat_test.matching(e);
|
||||
const_mat_test.matching(n);
|
||||
const MaxWeightedMatching<Graph>::MatchingMap& mmap =
|
||||
const_mat_test.matchingMap();
|
||||
e = mmap[n];
|
||||
const_mat_test.mate(n);
|
||||
|
||||
int k = 0;
|
||||
const_mat_test.dualValue();
|
||||
const_mat_test.nodeValue(n);
|
||||
const_mat_test.blossomNum();
|
||||
const_mat_test.blossomSize(k);
|
||||
const_mat_test.blossomValue(k);
|
||||
}
|
||||
|
||||
void checkMaxWeightedPerfectMatchingCompile()
|
||||
{
|
||||
typedef concepts::Graph Graph;
|
||||
typedef Graph::Node Node;
|
||||
typedef Graph::Edge Edge;
|
||||
typedef Graph::EdgeMap<int> WeightMap;
|
||||
|
||||
Graph g;
|
||||
Node n;
|
||||
Edge e;
|
||||
WeightMap w(g);
|
||||
|
||||
MaxWeightedPerfectMatching<Graph> mat_test(g, w);
|
||||
const MaxWeightedPerfectMatching<Graph>&
|
||||
const_mat_test = mat_test;
|
||||
|
||||
mat_test.init();
|
||||
mat_test.start();
|
||||
mat_test.run();
|
||||
|
||||
const_mat_test.matchingWeight();
|
||||
const_mat_test.matching(e);
|
||||
const_mat_test.matching(n);
|
||||
const MaxWeightedPerfectMatching<Graph>::MatchingMap& mmap =
|
||||
const_mat_test.matchingMap();
|
||||
e = mmap[n];
|
||||
const_mat_test.mate(n);
|
||||
|
||||
int k = 0;
|
||||
const_mat_test.dualValue();
|
||||
const_mat_test.nodeValue(n);
|
||||
const_mat_test.blossomNum();
|
||||
const_mat_test.blossomSize(k);
|
||||
const_mat_test.blossomValue(k);
|
||||
}
|
||||
|
||||
void checkMatching(const SmartGraph& graph,
|
||||
const MaxMatching<SmartGraph>& mm) {
|
||||
int num = 0;
|
||||
|
||||
IntNodeMap comp_index(graph);
|
||||
UnionFind<IntNodeMap> comp(comp_index);
|
||||
|
||||
int barrier_num = 0;
|
||||
|
||||
for (NodeIt n(graph); n != INVALID; ++n) {
|
||||
check(mm.status(n) == MaxMatching<SmartGraph>::EVEN ||
|
||||
mm.matching(n) != INVALID, "Wrong Gallai-Edmonds decomposition");
|
||||
if (mm.status(n) == MaxMatching<SmartGraph>::ODD) {
|
||||
++barrier_num;
|
||||
} else {
|
||||
comp.insert(n);
|
||||
}
|
||||
}
|
||||
|
||||
for (EdgeIt e(graph); e != INVALID; ++e) {
|
||||
if (mm.matching(e)) {
|
||||
check(e == mm.matching(graph.u(e)), "Wrong matching");
|
||||
check(e == mm.matching(graph.v(e)), "Wrong matching");
|
||||
++num;
|
||||
}
|
||||
check(mm.status(graph.u(e)) != MaxMatching<SmartGraph>::EVEN ||
|
||||
mm.status(graph.v(e)) != MaxMatching<SmartGraph>::MATCHED,
|
||||
"Wrong Gallai-Edmonds decomposition");
|
||||
|
||||
check(mm.status(graph.v(e)) != MaxMatching<SmartGraph>::EVEN ||
|
||||
mm.status(graph.u(e)) != MaxMatching<SmartGraph>::MATCHED,
|
||||
"Wrong Gallai-Edmonds decomposition");
|
||||
|
||||
if (mm.status(graph.u(e)) != MaxMatching<SmartGraph>::ODD &&
|
||||
mm.status(graph.v(e)) != MaxMatching<SmartGraph>::ODD) {
|
||||
comp.join(graph.u(e), graph.v(e));
|
||||
}
|
||||
}
|
||||
|
||||
std::set<int> comp_root;
|
||||
int odd_comp_num = 0;
|
||||
for (NodeIt n(graph); n != INVALID; ++n) {
|
||||
if (mm.status(n) != MaxMatching<SmartGraph>::ODD) {
|
||||
int root = comp.find(n);
|
||||
if (comp_root.find(root) == comp_root.end()) {
|
||||
comp_root.insert(root);
|
||||
if (comp.size(n) % 2 == 1) {
|
||||
++odd_comp_num;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
check(mm.matchingSize() == num, "Wrong matching");
|
||||
check(2 * num == countNodes(graph) - (odd_comp_num - barrier_num),
|
||||
"Wrong matching");
|
||||
return;
|
||||
}
|
||||
|
||||
void checkWeightedMatching(const SmartGraph& graph,
|
||||
const SmartGraph::EdgeMap<int>& weight,
|
||||
const MaxWeightedMatching<SmartGraph>& mwm) {
|
||||
for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
|
||||
if (graph.u(e) == graph.v(e)) continue;
|
||||
int rw = mwm.nodeValue(graph.u(e)) + mwm.nodeValue(graph.v(e));
|
||||
|
||||
for (int i = 0; i < mwm.blossomNum(); ++i) {
|
||||
bool s = false, t = false;
|
||||
for (MaxWeightedMatching<SmartGraph>::BlossomIt n(mwm, i);
|
||||
n != INVALID; ++n) {
|
||||
if (graph.u(e) == n) s = true;
|
||||
if (graph.v(e) == n) t = true;
|
||||
}
|
||||
if (s == true && t == true) {
|
||||
rw += mwm.blossomValue(i);
|
||||
}
|
||||
}
|
||||
rw -= weight[e] * mwm.dualScale;
|
||||
|
||||
check(rw >= 0, "Negative reduced weight");
|
||||
check(rw == 0 || !mwm.matching(e),
|
||||
"Non-zero reduced weight on matching edge");
|
||||
}
|
||||
|
||||
int pv = 0;
|
||||
for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
|
||||
if (mwm.matching(n) != INVALID) {
|
||||
check(mwm.nodeValue(n) >= 0, "Invalid node value");
|
||||
pv += weight[mwm.matching(n)];
|
||||
SmartGraph::Node o = graph.target(mwm.matching(n));
|
||||
check(mwm.mate(n) == o, "Invalid matching");
|
||||
check(mwm.matching(n) == graph.oppositeArc(mwm.matching(o)),
|
||||
"Invalid matching");
|
||||
} else {
|
||||
check(mwm.mate(n) == INVALID, "Invalid matching");
|
||||
check(mwm.nodeValue(n) == 0, "Invalid matching");
|
||||
}
|
||||
}
|
||||
|
||||
int dv = 0;
|
||||
for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
|
||||
dv += mwm.nodeValue(n);
|
||||
}
|
||||
|
||||
for (int i = 0; i < mwm.blossomNum(); ++i) {
|
||||
check(mwm.blossomValue(i) >= 0, "Invalid blossom value");
|
||||
check(mwm.blossomSize(i) % 2 == 1, "Even blossom size");
|
||||
dv += mwm.blossomValue(i) * ((mwm.blossomSize(i) - 1) / 2);
|
||||
}
|
||||
|
||||
check(pv * mwm.dualScale == dv * 2, "Wrong duality");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void checkWeightedPerfectMatching(const SmartGraph& graph,
|
||||
const SmartGraph::EdgeMap<int>& weight,
|
||||
const MaxWeightedPerfectMatching<SmartGraph>& mwpm) {
|
||||
for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
|
||||
if (graph.u(e) == graph.v(e)) continue;
|
||||
int rw = mwpm.nodeValue(graph.u(e)) + mwpm.nodeValue(graph.v(e));
|
||||
|
||||
for (int i = 0; i < mwpm.blossomNum(); ++i) {
|
||||
bool s = false, t = false;
|
||||
for (MaxWeightedPerfectMatching<SmartGraph>::BlossomIt n(mwpm, i);
|
||||
n != INVALID; ++n) {
|
||||
if (graph.u(e) == n) s = true;
|
||||
if (graph.v(e) == n) t = true;
|
||||
}
|
||||
if (s == true && t == true) {
|
||||
rw += mwpm.blossomValue(i);
|
||||
}
|
||||
}
|
||||
rw -= weight[e] * mwpm.dualScale;
|
||||
|
||||
check(rw >= 0, "Negative reduced weight");
|
||||
check(rw == 0 || !mwpm.matching(e),
|
||||
"Non-zero reduced weight on matching edge");
|
||||
}
|
||||
|
||||
int pv = 0;
|
||||
for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
|
||||
check(mwpm.matching(n) != INVALID, "Non perfect");
|
||||
pv += weight[mwpm.matching(n)];
|
||||
SmartGraph::Node o = graph.target(mwpm.matching(n));
|
||||
check(mwpm.mate(n) == o, "Invalid matching");
|
||||
check(mwpm.matching(n) == graph.oppositeArc(mwpm.matching(o)),
|
||||
"Invalid matching");
|
||||
}
|
||||
|
||||
int dv = 0;
|
||||
for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
|
||||
dv += mwpm.nodeValue(n);
|
||||
}
|
||||
|
||||
for (int i = 0; i < mwpm.blossomNum(); ++i) {
|
||||
check(mwpm.blossomValue(i) >= 0, "Invalid blossom value");
|
||||
check(mwpm.blossomSize(i) % 2 == 1, "Even blossom size");
|
||||
dv += mwpm.blossomValue(i) * ((mwpm.blossomSize(i) - 1) / 2);
|
||||
}
|
||||
|
||||
check(pv * mwpm.dualScale == dv * 2, "Wrong duality");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
for (int i = 0; i < lgfn; ++i) {
|
||||
SmartGraph graph;
|
||||
SmartGraph::EdgeMap<int> weight(graph);
|
||||
|
||||
istringstream lgfs(lgf[i]);
|
||||
graphReader(graph, lgfs).
|
||||
edgeMap("weight", weight).run();
|
||||
|
||||
bool perfect;
|
||||
{
|
||||
MaxMatching<SmartGraph> mm(graph);
|
||||
mm.run();
|
||||
checkMatching(graph, mm);
|
||||
perfect = 2 * mm.matchingSize() == countNodes(graph);
|
||||
}
|
||||
|
||||
{
|
||||
MaxWeightedMatching<SmartGraph> mwm(graph, weight);
|
||||
mwm.run();
|
||||
checkWeightedMatching(graph, weight, mwm);
|
||||
}
|
||||
|
||||
{
|
||||
MaxWeightedMatching<SmartGraph> mwm(graph, weight);
|
||||
mwm.init();
|
||||
mwm.start();
|
||||
checkWeightedMatching(graph, weight, mwm);
|
||||
}
|
||||
|
||||
{
|
||||
MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
|
||||
bool result = mwpm.run();
|
||||
|
||||
check(result == perfect, "Perfect matching found");
|
||||
if (perfect) {
|
||||
checkWeightedPerfectMatching(graph, weight, mwpm);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
|
||||
mwpm.init();
|
||||
bool result = mwpm.start();
|
||||
|
||||
check(result == perfect, "Perfect matching found");
|
||||
if (perfect) {
|
||||
checkWeightedPerfectMatching(graph, weight, mwpm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
162
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/max_cardinality_search_test.cc
vendored
Normal file
162
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/max_cardinality_search_test.cc
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "test_tools.h"
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/max_cardinality_search.h>
|
||||
#include <lemon/concepts/digraph.h>
|
||||
#include <lemon/concepts/maps.h>
|
||||
#include <lemon/concepts/heap.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
|
||||
using namespace lemon;
|
||||
using namespace std;
|
||||
|
||||
char test_lgf[] =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"@arcs\n"
|
||||
" label capacity\n"
|
||||
"0 1 0 2\n"
|
||||
"1 0 1 2\n"
|
||||
"2 1 2 1\n"
|
||||
"2 3 3 3\n"
|
||||
"3 2 4 3\n"
|
||||
"3 1 5 5\n"
|
||||
"@attributes\n"
|
||||
"s 0\n"
|
||||
"x 1\n"
|
||||
"y 2\n"
|
||||
"z 3\n";
|
||||
|
||||
void checkMaxCardSearchCompile() {
|
||||
|
||||
typedef concepts::Digraph Digraph;
|
||||
typedef int Value;
|
||||
typedef Digraph::Node Node;
|
||||
typedef Digraph::Arc Arc;
|
||||
typedef concepts::ReadMap<Arc,Value> CapMap;
|
||||
typedef concepts::ReadWriteMap<Node,Value> CardMap;
|
||||
typedef concepts::ReadWriteMap<Node,bool> ProcMap;
|
||||
typedef Digraph::NodeMap<int> HeapCrossRef;
|
||||
|
||||
Digraph g;
|
||||
Node n,s;
|
||||
CapMap cap;
|
||||
CardMap card;
|
||||
ProcMap proc;
|
||||
HeapCrossRef crossref(g);
|
||||
|
||||
typedef MaxCardinalitySearch<Digraph,CapMap>
|
||||
::SetCapacityMap<CapMap>
|
||||
::SetCardinalityMap<CardMap>
|
||||
::SetProcessedMap<ProcMap>
|
||||
::SetStandardHeap<BinHeap<Value,HeapCrossRef> >
|
||||
::Create MaxCardType;
|
||||
|
||||
MaxCardType maxcard(g,cap);
|
||||
const MaxCardType& const_maxcard = maxcard;
|
||||
|
||||
const MaxCardType::Heap& heap_const = const_maxcard.heap();
|
||||
MaxCardType::Heap& heap = const_cast<MaxCardType::Heap&>(heap_const);
|
||||
maxcard.heap(heap,crossref);
|
||||
|
||||
maxcard.capacityMap(cap).cardinalityMap(card).processedMap(proc);
|
||||
|
||||
maxcard.init();
|
||||
maxcard.addSource(s);
|
||||
n = maxcard.nextNode();
|
||||
maxcard.processNextNode();
|
||||
maxcard.start();
|
||||
maxcard.run(s);
|
||||
maxcard.run();
|
||||
}
|
||||
|
||||
void checkWithIntMap( std::istringstream& input)
|
||||
{
|
||||
typedef SmartDigraph Digraph;
|
||||
typedef Digraph::Node Node;
|
||||
typedef Digraph::ArcMap<int> CapMap;
|
||||
|
||||
Digraph g;
|
||||
Node s,x,y,z,a;
|
||||
CapMap cap(g);
|
||||
|
||||
DigraphReader<Digraph>(g,input).
|
||||
arcMap("capacity", cap).
|
||||
node("s",s).
|
||||
node("x",x).
|
||||
node("y",y).
|
||||
node("z",z).
|
||||
run();
|
||||
|
||||
MaxCardinalitySearch<Digraph,CapMap> maxcard(g,cap);
|
||||
|
||||
maxcard.init();
|
||||
maxcard.addSource(s);
|
||||
maxcard.start(x);
|
||||
|
||||
check(maxcard.processed(s) && !maxcard.processed(x) &&
|
||||
!maxcard.processed(y), "Wrong processed()!");
|
||||
|
||||
a=maxcard.nextNode();
|
||||
check(maxcard.processNextNode()==a,
|
||||
"Wrong nextNode() or processNextNode() return value!");
|
||||
|
||||
check(maxcard.processed(a), "Wrong processNextNode()!");
|
||||
|
||||
maxcard.start();
|
||||
check(maxcard.cardinality(x)==2 && maxcard.cardinality(y)>=4,
|
||||
"Wrong cardinalities!");
|
||||
}
|
||||
|
||||
void checkWithConst1Map(std::istringstream &input) {
|
||||
typedef SmartDigraph Digraph;
|
||||
typedef Digraph::Node Node;
|
||||
|
||||
Digraph g;
|
||||
Node s,x,y,z;
|
||||
|
||||
DigraphReader<Digraph>(g,input).
|
||||
node("s",s).
|
||||
node("x",x).
|
||||
node("y",y).
|
||||
node("z",z).
|
||||
run();
|
||||
|
||||
MaxCardinalitySearch<Digraph> maxcard(g);
|
||||
maxcard.run(s);
|
||||
check(maxcard.cardinality(x)==1 &&
|
||||
maxcard.cardinality(y)+maxcard.cardinality(z)==3,
|
||||
"Wrong cardinalities!");
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
std::istringstream input1(test_lgf);
|
||||
checkWithIntMap(input1);
|
||||
|
||||
std::istringstream input2(test_lgf);
|
||||
checkWithConst1Map(input2);
|
||||
}
|
||||
188
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/max_clique_test.cc
vendored
Normal file
188
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/max_clique_test.cc
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include <lemon/list_graph.h>
|
||||
#include <lemon/full_graph.h>
|
||||
#include <lemon/grid_graph.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/grosso_locatelli_pullan_mc.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
char test_lgf[] =
|
||||
"@nodes\n"
|
||||
"label max_clique\n"
|
||||
"1 0\n"
|
||||
"2 0\n"
|
||||
"3 0\n"
|
||||
"4 1\n"
|
||||
"5 1\n"
|
||||
"6 1\n"
|
||||
"7 1\n"
|
||||
"@edges\n"
|
||||
" label\n"
|
||||
"1 2 1\n"
|
||||
"1 3 2\n"
|
||||
"1 4 3\n"
|
||||
"1 6 4\n"
|
||||
"2 3 5\n"
|
||||
"2 5 6\n"
|
||||
"2 7 7\n"
|
||||
"3 4 8\n"
|
||||
"3 5 9\n"
|
||||
"4 5 10\n"
|
||||
"4 6 11\n"
|
||||
"4 7 12\n"
|
||||
"5 6 13\n"
|
||||
"5 7 14\n"
|
||||
"6 7 15\n";
|
||||
|
||||
|
||||
// Check with general graphs
|
||||
template <typename Param>
|
||||
void checkMaxCliqueGeneral(Param rule) {
|
||||
typedef ListGraph GR;
|
||||
typedef GrossoLocatelliPullanMc<GR> McAlg;
|
||||
typedef McAlg::CliqueNodeIt CliqueIt;
|
||||
|
||||
// Basic tests
|
||||
{
|
||||
GR g;
|
||||
GR::NodeMap<bool> map(g);
|
||||
McAlg mc(g);
|
||||
mc.iterationLimit(50);
|
||||
check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
|
||||
check(mc.cliqueSize() == 0, "Wrong clique size");
|
||||
check(CliqueIt(mc) == INVALID, "Wrong CliqueNodeIt");
|
||||
|
||||
GR::Node u = g.addNode();
|
||||
check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
|
||||
check(mc.cliqueSize() == 1, "Wrong clique size");
|
||||
mc.cliqueMap(map);
|
||||
check(map[u], "Wrong clique map");
|
||||
CliqueIt it1(mc);
|
||||
check(static_cast<GR::Node>(it1) == u && ++it1 == INVALID,
|
||||
"Wrong CliqueNodeIt");
|
||||
|
||||
GR::Node v = g.addNode();
|
||||
check(mc.run(rule) == McAlg::ITERATION_LIMIT, "Wrong termination cause");
|
||||
check(mc.cliqueSize() == 1, "Wrong clique size");
|
||||
mc.cliqueMap(map);
|
||||
check((map[u] && !map[v]) || (map[v] && !map[u]), "Wrong clique map");
|
||||
CliqueIt it2(mc);
|
||||
check(it2 != INVALID && ++it2 == INVALID, "Wrong CliqueNodeIt");
|
||||
|
||||
g.addEdge(u, v);
|
||||
check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
|
||||
check(mc.cliqueSize() == 2, "Wrong clique size");
|
||||
mc.cliqueMap(map);
|
||||
check(map[u] && map[v], "Wrong clique map");
|
||||
CliqueIt it3(mc);
|
||||
check(it3 != INVALID && ++it3 != INVALID && ++it3 == INVALID,
|
||||
"Wrong CliqueNodeIt");
|
||||
}
|
||||
|
||||
// Test graph
|
||||
{
|
||||
GR g;
|
||||
GR::NodeMap<bool> max_clique(g);
|
||||
GR::NodeMap<bool> map(g);
|
||||
std::istringstream input(test_lgf);
|
||||
graphReader(g, input)
|
||||
.nodeMap("max_clique", max_clique)
|
||||
.run();
|
||||
|
||||
McAlg mc(g);
|
||||
mc.iterationLimit(50);
|
||||
check(mc.run(rule) == McAlg::ITERATION_LIMIT, "Wrong termination cause");
|
||||
check(mc.cliqueSize() == 4, "Wrong clique size");
|
||||
mc.cliqueMap(map);
|
||||
for (GR::NodeIt n(g); n != INVALID; ++n) {
|
||||
check(map[n] == max_clique[n], "Wrong clique map");
|
||||
}
|
||||
int cnt = 0;
|
||||
for (CliqueIt n(mc); n != INVALID; ++n) {
|
||||
cnt++;
|
||||
check(map[n] && max_clique[n], "Wrong CliqueNodeIt");
|
||||
}
|
||||
check(cnt == 4, "Wrong CliqueNodeIt");
|
||||
}
|
||||
}
|
||||
|
||||
// Check with full graphs
|
||||
template <typename Param>
|
||||
void checkMaxCliqueFullGraph(Param rule) {
|
||||
typedef FullGraph GR;
|
||||
typedef GrossoLocatelliPullanMc<FullGraph> McAlg;
|
||||
typedef McAlg::CliqueNodeIt CliqueIt;
|
||||
|
||||
for (int size = 0; size <= 40; size = size * 3 + 1) {
|
||||
GR g(size);
|
||||
GR::NodeMap<bool> map(g);
|
||||
McAlg mc(g);
|
||||
check(mc.run(rule) == McAlg::SIZE_LIMIT, "Wrong termination cause");
|
||||
check(mc.cliqueSize() == size, "Wrong clique size");
|
||||
mc.cliqueMap(map);
|
||||
for (GR::NodeIt n(g); n != INVALID; ++n) {
|
||||
check(map[n], "Wrong clique map");
|
||||
}
|
||||
int cnt = 0;
|
||||
for (CliqueIt n(mc); n != INVALID; ++n) cnt++;
|
||||
check(cnt == size, "Wrong CliqueNodeIt");
|
||||
}
|
||||
}
|
||||
|
||||
// Check with grid graphs
|
||||
template <typename Param>
|
||||
void checkMaxCliqueGridGraph(Param rule) {
|
||||
GridGraph g(5, 7);
|
||||
GridGraph::NodeMap<char> map(g);
|
||||
GrossoLocatelliPullanMc<GridGraph> mc(g);
|
||||
|
||||
mc.iterationLimit(100);
|
||||
check(mc.run(rule) == mc.ITERATION_LIMIT, "Wrong termination cause");
|
||||
check(mc.cliqueSize() == 2, "Wrong clique size");
|
||||
|
||||
mc.stepLimit(100);
|
||||
check(mc.run(rule) == mc.STEP_LIMIT, "Wrong termination cause");
|
||||
check(mc.cliqueSize() == 2, "Wrong clique size");
|
||||
|
||||
mc.sizeLimit(2);
|
||||
check(mc.run(rule) == mc.SIZE_LIMIT, "Wrong termination cause");
|
||||
check(mc.cliqueSize() == 2, "Wrong clique size");
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
checkMaxCliqueGeneral(GrossoLocatelliPullanMc<ListGraph>::RANDOM);
|
||||
checkMaxCliqueGeneral(GrossoLocatelliPullanMc<ListGraph>::DEGREE_BASED);
|
||||
checkMaxCliqueGeneral(GrossoLocatelliPullanMc<ListGraph>::PENALTY_BASED);
|
||||
|
||||
checkMaxCliqueFullGraph(GrossoLocatelliPullanMc<FullGraph>::RANDOM);
|
||||
checkMaxCliqueFullGraph(GrossoLocatelliPullanMc<FullGraph>::DEGREE_BASED);
|
||||
checkMaxCliqueFullGraph(GrossoLocatelliPullanMc<FullGraph>::PENALTY_BASED);
|
||||
|
||||
checkMaxCliqueGridGraph(GrossoLocatelliPullanMc<GridGraph>::RANDOM);
|
||||
checkMaxCliqueGridGraph(GrossoLocatelliPullanMc<GridGraph>::DEGREE_BASED);
|
||||
checkMaxCliqueGridGraph(GrossoLocatelliPullanMc<GridGraph>::PENALTY_BASED);
|
||||
|
||||
return 0;
|
||||
}
|
||||
395
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/max_flow_test.cc
vendored
Normal file
395
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/max_flow_test.cc
vendored
Normal file
@@ -0,0 +1,395 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "test_tools.h"
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/preflow.h>
|
||||
#include <lemon/edmonds_karp.h>
|
||||
#include <lemon/concepts/digraph.h>
|
||||
#include <lemon/concepts/maps.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/elevator.h>
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
char test_lgf[] =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"6\n"
|
||||
"7\n"
|
||||
"8\n"
|
||||
"9\n"
|
||||
"@arcs\n"
|
||||
" label capacity\n"
|
||||
"0 1 0 20\n"
|
||||
"0 2 1 0\n"
|
||||
"1 1 2 3\n"
|
||||
"1 2 3 8\n"
|
||||
"1 3 4 8\n"
|
||||
"2 5 5 5\n"
|
||||
"3 2 6 5\n"
|
||||
"3 5 7 5\n"
|
||||
"3 6 8 5\n"
|
||||
"4 3 9 3\n"
|
||||
"5 7 10 3\n"
|
||||
"5 6 11 10\n"
|
||||
"5 8 12 10\n"
|
||||
"6 8 13 8\n"
|
||||
"8 9 14 20\n"
|
||||
"8 1 15 5\n"
|
||||
"9 5 16 5\n"
|
||||
"@attributes\n"
|
||||
"source 1\n"
|
||||
"target 8\n";
|
||||
|
||||
|
||||
// Checks the general interface of a max flow algorithm
|
||||
template <typename GR, typename CAP>
|
||||
struct MaxFlowClassConcept
|
||||
{
|
||||
|
||||
template <typename MF>
|
||||
struct Constraints {
|
||||
|
||||
typedef typename GR::Node Node;
|
||||
typedef typename GR::Arc Arc;
|
||||
typedef typename CAP::Value Value;
|
||||
typedef concepts::ReadWriteMap<Arc, Value> FlowMap;
|
||||
typedef concepts::WriteMap<Node, bool> CutMap;
|
||||
|
||||
GR g;
|
||||
Node n;
|
||||
Arc e;
|
||||
CAP cap;
|
||||
FlowMap flow;
|
||||
CutMap cut;
|
||||
Value v;
|
||||
bool b;
|
||||
|
||||
void constraints() {
|
||||
checkConcept<concepts::Digraph, GR>();
|
||||
|
||||
const Constraints& me = *this;
|
||||
|
||||
typedef typename MF
|
||||
::template SetFlowMap<FlowMap>
|
||||
::Create MaxFlowType;
|
||||
typedef typename MF::Create MaxFlowType2;
|
||||
MaxFlowType max_flow(me.g, me.cap, me.n, me.n);
|
||||
const MaxFlowType& const_max_flow = max_flow;
|
||||
|
||||
max_flow
|
||||
.capacityMap(cap)
|
||||
.flowMap(flow)
|
||||
.source(n)
|
||||
.target(n);
|
||||
|
||||
typename MaxFlowType::Tolerance tol = const_max_flow.tolerance();
|
||||
max_flow.tolerance(tol);
|
||||
|
||||
max_flow.init();
|
||||
max_flow.init(cap);
|
||||
max_flow.run();
|
||||
|
||||
v = const_max_flow.flowValue();
|
||||
v = const_max_flow.flow(e);
|
||||
const FlowMap& fm = const_max_flow.flowMap();
|
||||
|
||||
b = const_max_flow.minCut(n);
|
||||
const_max_flow.minCutMap(cut);
|
||||
|
||||
::lemon::ignore_unused_variable_warning(fm);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
// Checks the specific parts of Preflow's interface
|
||||
void checkPreflowCompile()
|
||||
{
|
||||
typedef int Value;
|
||||
typedef concepts::Digraph Digraph;
|
||||
typedef concepts::ReadMap<Digraph::Arc, Value> CapMap;
|
||||
typedef Elevator<Digraph, Digraph::Node> Elev;
|
||||
typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
|
||||
|
||||
Digraph g;
|
||||
Digraph::Node n;
|
||||
CapMap cap;
|
||||
|
||||
typedef Preflow<Digraph, CapMap>
|
||||
::SetElevator<Elev>
|
||||
::SetStandardElevator<LinkedElev>
|
||||
::Create PreflowType;
|
||||
PreflowType preflow_test(g, cap, n, n);
|
||||
const PreflowType& const_preflow_test = preflow_test;
|
||||
|
||||
const PreflowType::Elevator& elev = const_preflow_test.elevator();
|
||||
preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
|
||||
|
||||
bool b = preflow_test.init(cap);
|
||||
preflow_test.startFirstPhase();
|
||||
preflow_test.startSecondPhase();
|
||||
preflow_test.runMinCut();
|
||||
|
||||
::lemon::ignore_unused_variable_warning(b);
|
||||
}
|
||||
|
||||
// Checks the specific parts of EdmondsKarp's interface
|
||||
void checkEdmondsKarpCompile()
|
||||
{
|
||||
typedef int Value;
|
||||
typedef concepts::Digraph Digraph;
|
||||
typedef concepts::ReadMap<Digraph::Arc, Value> CapMap;
|
||||
typedef Elevator<Digraph, Digraph::Node> Elev;
|
||||
typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
|
||||
|
||||
Digraph g;
|
||||
Digraph::Node n;
|
||||
CapMap cap;
|
||||
|
||||
EdmondsKarp<Digraph, CapMap> ek_test(g, cap, n, n);
|
||||
|
||||
ek_test.init(cap);
|
||||
bool b = ek_test.checkedInit(cap);
|
||||
b = ek_test.augment();
|
||||
ek_test.start();
|
||||
|
||||
::lemon::ignore_unused_variable_warning(b);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T cutValue (const SmartDigraph& g,
|
||||
const SmartDigraph::NodeMap<bool>& cut,
|
||||
const SmartDigraph::ArcMap<T>& cap) {
|
||||
|
||||
T c=0;
|
||||
for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
|
||||
if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool checkFlow(const SmartDigraph& g,
|
||||
const SmartDigraph::ArcMap<T>& flow,
|
||||
const SmartDigraph::ArcMap<T>& cap,
|
||||
SmartDigraph::Node s, SmartDigraph::Node t) {
|
||||
|
||||
for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
|
||||
if (flow[e] < 0 || flow[e] > cap[e]) return false;
|
||||
}
|
||||
|
||||
for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
|
||||
if (n == s || n == t) continue;
|
||||
T sum = 0;
|
||||
for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
|
||||
sum += flow[e];
|
||||
}
|
||||
for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
|
||||
sum -= flow[e];
|
||||
}
|
||||
if (sum != 0) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void initFlowTest()
|
||||
{
|
||||
DIGRAPH_TYPEDEFS(SmartDigraph);
|
||||
|
||||
SmartDigraph g;
|
||||
SmartDigraph::ArcMap<int> cap(g),iflow(g);
|
||||
Node s=g.addNode(); Node t=g.addNode();
|
||||
Node n1=g.addNode(); Node n2=g.addNode();
|
||||
Arc a;
|
||||
a=g.addArc(s,n1); cap[a]=20; iflow[a]=20;
|
||||
a=g.addArc(n1,n2); cap[a]=10; iflow[a]=0;
|
||||
a=g.addArc(n2,t); cap[a]=20; iflow[a]=0;
|
||||
|
||||
Preflow<SmartDigraph> pre(g,cap,s,t);
|
||||
pre.init(iflow);
|
||||
pre.startFirstPhase();
|
||||
check(pre.flowValue() == 10, "The incorrect max flow value.");
|
||||
check(pre.minCut(s), "Wrong min cut (Node s).");
|
||||
check(pre.minCut(n1), "Wrong min cut (Node n1).");
|
||||
check(!pre.minCut(n2), "Wrong min cut (Node n2).");
|
||||
check(!pre.minCut(t), "Wrong min cut (Node t).");
|
||||
}
|
||||
|
||||
template <typename MF, typename SF>
|
||||
void checkMaxFlowAlg() {
|
||||
typedef SmartDigraph Digraph;
|
||||
DIGRAPH_TYPEDEFS(Digraph);
|
||||
|
||||
typedef typename MF::Value Value;
|
||||
typedef Digraph::ArcMap<Value> CapMap;
|
||||
typedef CapMap FlowMap;
|
||||
typedef BoolNodeMap CutMap;
|
||||
|
||||
Digraph g;
|
||||
Node s, t;
|
||||
CapMap cap(g);
|
||||
std::istringstream input(test_lgf);
|
||||
DigraphReader<Digraph>(g,input)
|
||||
.arcMap("capacity", cap)
|
||||
.node("source",s)
|
||||
.node("target",t)
|
||||
.run();
|
||||
|
||||
MF max_flow(g, cap, s, t);
|
||||
max_flow.run();
|
||||
|
||||
check(checkFlow(g, max_flow.flowMap(), cap, s, t),
|
||||
"The flow is not feasible.");
|
||||
|
||||
CutMap min_cut(g);
|
||||
max_flow.minCutMap(min_cut);
|
||||
Value min_cut_value = cutValue(g, min_cut, cap);
|
||||
|
||||
check(max_flow.flowValue() == min_cut_value,
|
||||
"The max flow value is not equal to the min cut value.");
|
||||
|
||||
FlowMap flow(g);
|
||||
for (ArcIt e(g); e != INVALID; ++e) flow[e] = max_flow.flowMap()[e];
|
||||
|
||||
Value flow_value = max_flow.flowValue();
|
||||
|
||||
for (ArcIt e(g); e != INVALID; ++e) cap[e] = 2 * cap[e];
|
||||
max_flow.init(flow);
|
||||
|
||||
SF::startFirstPhase(max_flow); // start first phase of the algorithm
|
||||
|
||||
CutMap min_cut1(g);
|
||||
max_flow.minCutMap(min_cut1);
|
||||
min_cut_value = cutValue(g, min_cut1, cap);
|
||||
|
||||
check(max_flow.flowValue() == min_cut_value &&
|
||||
min_cut_value == 2 * flow_value,
|
||||
"The max flow value or the min cut value is wrong.");
|
||||
|
||||
SF::startSecondPhase(max_flow); // start second phase of the algorithm
|
||||
|
||||
check(checkFlow(g, max_flow.flowMap(), cap, s, t),
|
||||
"The flow is not feasible.");
|
||||
|
||||
CutMap min_cut2(g);
|
||||
max_flow.minCutMap(min_cut2);
|
||||
min_cut_value = cutValue(g, min_cut2, cap);
|
||||
|
||||
check(max_flow.flowValue() == min_cut_value &&
|
||||
min_cut_value == 2 * flow_value,
|
||||
"The max flow value or the min cut value was not doubled");
|
||||
|
||||
|
||||
max_flow.flowMap(flow);
|
||||
|
||||
NodeIt tmp1(g, s);
|
||||
++tmp1;
|
||||
if (tmp1 != INVALID) s = tmp1;
|
||||
|
||||
NodeIt tmp2(g, t);
|
||||
++tmp2;
|
||||
if (tmp2 != INVALID) t = tmp2;
|
||||
|
||||
max_flow.source(s);
|
||||
max_flow.target(t);
|
||||
|
||||
max_flow.run();
|
||||
|
||||
CutMap min_cut3(g);
|
||||
max_flow.minCutMap(min_cut3);
|
||||
min_cut_value=cutValue(g, min_cut3, cap);
|
||||
|
||||
check(max_flow.flowValue() == min_cut_value,
|
||||
"The max flow value or the min cut value is wrong.");
|
||||
}
|
||||
|
||||
// Struct for calling start functions of a general max flow algorithm
|
||||
template <typename MF>
|
||||
struct GeneralStartFunctions {
|
||||
|
||||
static void startFirstPhase(MF& mf) {
|
||||
mf.start();
|
||||
}
|
||||
|
||||
static void startSecondPhase(MF& mf) {
|
||||
::lemon::ignore_unused_variable_warning(mf);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Struct for calling start functions of Preflow
|
||||
template <typename MF>
|
||||
struct PreflowStartFunctions {
|
||||
|
||||
static void startFirstPhase(MF& mf) {
|
||||
mf.startFirstPhase();
|
||||
}
|
||||
|
||||
static void startSecondPhase(MF& mf) {
|
||||
mf.startSecondPhase();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
int main() {
|
||||
|
||||
typedef concepts::Digraph GR;
|
||||
typedef concepts::ReadMap<GR::Arc, int> CM1;
|
||||
typedef concepts::ReadMap<GR::Arc, double> CM2;
|
||||
|
||||
// Check the interface of Preflow
|
||||
checkConcept< MaxFlowClassConcept<GR, CM1>,
|
||||
Preflow<GR, CM1> >();
|
||||
checkConcept< MaxFlowClassConcept<GR, CM2>,
|
||||
Preflow<GR, CM2> >();
|
||||
|
||||
// Check the interface of EdmondsKarp
|
||||
checkConcept< MaxFlowClassConcept<GR, CM1>,
|
||||
EdmondsKarp<GR, CM1> >();
|
||||
checkConcept< MaxFlowClassConcept<GR, CM2>,
|
||||
EdmondsKarp<GR, CM2> >();
|
||||
|
||||
// Check Preflow
|
||||
typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<int> > PType1;
|
||||
typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<float> > PType2;
|
||||
checkMaxFlowAlg<PType1, PreflowStartFunctions<PType1> >();
|
||||
checkMaxFlowAlg<PType2, PreflowStartFunctions<PType2> >();
|
||||
initFlowTest();
|
||||
|
||||
// Check EdmondsKarp
|
||||
typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<int> > EKType1;
|
||||
typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<float> > EKType2;
|
||||
checkMaxFlowAlg<EKType1, GeneralStartFunctions<EKType1> >();
|
||||
checkMaxFlowAlg<EKType2, GeneralStartFunctions<EKType2> >();
|
||||
|
||||
initFlowTest();
|
||||
|
||||
return 0;
|
||||
}
|
||||
207
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/min_cost_arborescence_test.cc
vendored
Normal file
207
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/min_cost_arborescence_test.cc
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/min_cost_arborescence.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/concepts/digraph.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
using namespace std;
|
||||
|
||||
const char test_lgf[] =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"6\n"
|
||||
"7\n"
|
||||
"8\n"
|
||||
"9\n"
|
||||
"@arcs\n"
|
||||
" label cost\n"
|
||||
"1 8 0 107\n"
|
||||
"0 3 1 70\n"
|
||||
"2 1 2 46\n"
|
||||
"4 1 3 28\n"
|
||||
"4 4 4 91\n"
|
||||
"3 9 5 76\n"
|
||||
"9 8 6 61\n"
|
||||
"8 1 7 39\n"
|
||||
"9 8 8 74\n"
|
||||
"8 0 9 39\n"
|
||||
"4 3 10 45\n"
|
||||
"2 2 11 34\n"
|
||||
"0 1 12 100\n"
|
||||
"6 3 13 95\n"
|
||||
"4 1 14 22\n"
|
||||
"1 1 15 31\n"
|
||||
"7 2 16 51\n"
|
||||
"2 6 17 29\n"
|
||||
"8 3 18 115\n"
|
||||
"6 9 19 32\n"
|
||||
"1 1 20 60\n"
|
||||
"0 3 21 40\n"
|
||||
"@attributes\n"
|
||||
"source 0\n";
|
||||
|
||||
|
||||
void checkMinCostArborescenceCompile()
|
||||
{
|
||||
typedef double VType;
|
||||
typedef concepts::Digraph Digraph;
|
||||
typedef concepts::ReadMap<Digraph::Arc, VType> CostMap;
|
||||
typedef Digraph::Node Node;
|
||||
typedef Digraph::Arc Arc;
|
||||
typedef concepts::WriteMap<Digraph::Arc, bool> ArbMap;
|
||||
typedef concepts::ReadWriteMap<Digraph::Node, Digraph::Arc> PredMap;
|
||||
|
||||
typedef MinCostArborescence<Digraph, CostMap>::
|
||||
SetArborescenceMap<ArbMap>::
|
||||
SetPredMap<PredMap>::Create MinCostArbType;
|
||||
|
||||
Digraph g;
|
||||
Node s, n;
|
||||
Arc e;
|
||||
VType c;
|
||||
bool b;
|
||||
::lemon::ignore_unused_variable_warning(c,b);
|
||||
int i;
|
||||
CostMap cost;
|
||||
ArbMap arb;
|
||||
PredMap pred;
|
||||
|
||||
MinCostArbType mcarb_test(g, cost);
|
||||
const MinCostArbType& const_mcarb_test = mcarb_test;
|
||||
|
||||
mcarb_test
|
||||
.arborescenceMap(arb)
|
||||
.predMap(pred)
|
||||
.run(s);
|
||||
|
||||
mcarb_test.init();
|
||||
mcarb_test.addSource(s);
|
||||
mcarb_test.start();
|
||||
n = mcarb_test.processNextNode();
|
||||
b = const_mcarb_test.emptyQueue();
|
||||
i = const_mcarb_test.queueSize();
|
||||
|
||||
c = const_mcarb_test.arborescenceCost();
|
||||
b = const_mcarb_test.arborescence(e);
|
||||
e = const_mcarb_test.pred(n);
|
||||
const MinCostArbType::ArborescenceMap &am =
|
||||
const_mcarb_test.arborescenceMap();
|
||||
const MinCostArbType::PredMap &pm =
|
||||
const_mcarb_test.predMap();
|
||||
b = const_mcarb_test.reached(n);
|
||||
b = const_mcarb_test.processed(n);
|
||||
|
||||
i = const_mcarb_test.dualNum();
|
||||
c = const_mcarb_test.dualValue();
|
||||
i = const_mcarb_test.dualSize(i);
|
||||
c = const_mcarb_test.dualValue(i);
|
||||
|
||||
::lemon::ignore_unused_variable_warning(am);
|
||||
::lemon::ignore_unused_variable_warning(pm);
|
||||
}
|
||||
|
||||
int main() {
|
||||
typedef SmartDigraph Digraph;
|
||||
DIGRAPH_TYPEDEFS(Digraph);
|
||||
|
||||
typedef Digraph::ArcMap<double> CostMap;
|
||||
|
||||
Digraph digraph;
|
||||
CostMap cost(digraph);
|
||||
Node source;
|
||||
|
||||
std::istringstream is(test_lgf);
|
||||
digraphReader(digraph, is).
|
||||
arcMap("cost", cost).
|
||||
node("source", source).run();
|
||||
|
||||
MinCostArborescence<Digraph, CostMap> mca(digraph, cost);
|
||||
mca.run(source);
|
||||
|
||||
vector<pair<double, set<Node> > > dualSolution(mca.dualNum());
|
||||
|
||||
for (int i = 0; i < mca.dualNum(); ++i) {
|
||||
dualSolution[i].first = mca.dualValue(i);
|
||||
for (MinCostArborescence<Digraph, CostMap>::DualIt it(mca, i);
|
||||
it != INVALID; ++it) {
|
||||
dualSolution[i].second.insert(it);
|
||||
}
|
||||
}
|
||||
|
||||
for (ArcIt it(digraph); it != INVALID; ++it) {
|
||||
if (mca.reached(digraph.source(it))) {
|
||||
double sum = 0.0;
|
||||
for (int i = 0; i < int(dualSolution.size()); ++i) {
|
||||
if (dualSolution[i].second.find(digraph.target(it))
|
||||
!= dualSolution[i].second.end() &&
|
||||
dualSolution[i].second.find(digraph.source(it))
|
||||
== dualSolution[i].second.end()) {
|
||||
sum += dualSolution[i].first;
|
||||
}
|
||||
}
|
||||
if (mca.arborescence(it)) {
|
||||
check(sum == cost[it], "Invalid dual solution");
|
||||
}
|
||||
check(sum <= cost[it], "Invalid dual solution");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
check(mca.dualValue() == mca.arborescenceCost(), "Invalid dual solution");
|
||||
|
||||
check(mca.reached(source), "Invalid arborescence");
|
||||
for (ArcIt a(digraph); a != INVALID; ++a) {
|
||||
check(!mca.reached(digraph.source(a)) ||
|
||||
mca.reached(digraph.target(a)), "Invalid arborescence");
|
||||
}
|
||||
|
||||
for (NodeIt n(digraph); n != INVALID; ++n) {
|
||||
if (!mca.reached(n)) continue;
|
||||
int cnt = 0;
|
||||
for (InArcIt a(digraph, n); a != INVALID; ++a) {
|
||||
if (mca.arborescence(a)) {
|
||||
check(mca.pred(n) == a, "Invalid arborescence");
|
||||
++cnt;
|
||||
}
|
||||
}
|
||||
check((n == source ? cnt == 0 : cnt == 1), "Invalid arborescence");
|
||||
}
|
||||
|
||||
Digraph::ArcMap<bool> arborescence(digraph);
|
||||
check(mca.arborescenceCost() ==
|
||||
minCostArborescence(digraph, cost, source, arborescence),
|
||||
"Wrong result of the function interface");
|
||||
|
||||
return 0;
|
||||
}
|
||||
548
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/min_cost_flow_test.cc
vendored
Normal file
548
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/min_cost_flow_test.cc
vendored
Normal file
@@ -0,0 +1,548 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
|
||||
#include <lemon/list_graph.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
|
||||
#include <lemon/network_simplex.h>
|
||||
#include <lemon/capacity_scaling.h>
|
||||
#include <lemon/cost_scaling.h>
|
||||
#include <lemon/cycle_canceling.h>
|
||||
|
||||
#include <lemon/concepts/digraph.h>
|
||||
#include <lemon/concepts/heap.h>
|
||||
#include <lemon/concept_check.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
// Test networks
|
||||
char test_lgf[] =
|
||||
"@nodes\n"
|
||||
"label sup1 sup2 sup3 sup4 sup5 sup6\n"
|
||||
" 1 20 27 0 30 20 30\n"
|
||||
" 2 -4 0 0 0 -8 -3\n"
|
||||
" 3 0 0 0 0 0 0\n"
|
||||
" 4 0 0 0 0 0 0\n"
|
||||
" 5 9 0 0 0 6 11\n"
|
||||
" 6 -6 0 0 0 -5 -6\n"
|
||||
" 7 0 0 0 0 0 0\n"
|
||||
" 8 0 0 0 0 0 3\n"
|
||||
" 9 3 0 0 0 0 0\n"
|
||||
" 10 -2 0 0 0 -7 -2\n"
|
||||
" 11 0 0 0 0 -10 0\n"
|
||||
" 12 -20 -27 0 -30 -30 -20\n"
|
||||
"\n"
|
||||
"@arcs\n"
|
||||
" cost cap low1 low2 low3\n"
|
||||
" 1 2 70 11 0 8 8\n"
|
||||
" 1 3 150 3 0 1 0\n"
|
||||
" 1 4 80 15 0 2 2\n"
|
||||
" 2 8 80 12 0 0 0\n"
|
||||
" 3 5 140 5 0 3 1\n"
|
||||
" 4 6 60 10 0 1 0\n"
|
||||
" 4 7 80 2 0 0 0\n"
|
||||
" 4 8 110 3 0 0 0\n"
|
||||
" 5 7 60 14 0 0 0\n"
|
||||
" 5 11 120 12 0 0 0\n"
|
||||
" 6 3 0 3 0 0 0\n"
|
||||
" 6 9 140 4 0 0 0\n"
|
||||
" 6 10 90 8 0 0 0\n"
|
||||
" 7 1 30 5 0 0 -5\n"
|
||||
" 8 12 60 16 0 4 3\n"
|
||||
" 9 12 50 6 0 0 0\n"
|
||||
"10 12 70 13 0 5 2\n"
|
||||
"10 2 100 7 0 0 0\n"
|
||||
"10 7 60 10 0 0 -3\n"
|
||||
"11 10 20 14 0 6 -20\n"
|
||||
"12 11 30 10 0 0 -10\n"
|
||||
"\n"
|
||||
"@attributes\n"
|
||||
"source 1\n"
|
||||
"target 12\n";
|
||||
|
||||
char test_neg1_lgf[] =
|
||||
"@nodes\n"
|
||||
"label sup\n"
|
||||
" 1 100\n"
|
||||
" 2 0\n"
|
||||
" 3 0\n"
|
||||
" 4 -100\n"
|
||||
" 5 0\n"
|
||||
" 6 0\n"
|
||||
" 7 0\n"
|
||||
"@arcs\n"
|
||||
" cost low1 low2\n"
|
||||
"1 2 100 0 0\n"
|
||||
"1 3 30 0 0\n"
|
||||
"2 4 20 0 0\n"
|
||||
"3 4 80 0 0\n"
|
||||
"3 2 50 0 0\n"
|
||||
"5 3 10 0 0\n"
|
||||
"5 6 80 0 1000\n"
|
||||
"6 7 30 0 -1000\n"
|
||||
"7 5 -120 0 0\n";
|
||||
|
||||
char test_neg2_lgf[] =
|
||||
"@nodes\n"
|
||||
"label sup\n"
|
||||
" 1 100\n"
|
||||
" 2 -300\n"
|
||||
"@arcs\n"
|
||||
" cost\n"
|
||||
"1 2 -1\n";
|
||||
|
||||
|
||||
// Test data
|
||||
typedef ListDigraph Digraph;
|
||||
DIGRAPH_TYPEDEFS(ListDigraph);
|
||||
|
||||
Digraph gr;
|
||||
Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), l3(gr), u(gr);
|
||||
Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr), s6(gr);
|
||||
ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
|
||||
Node v, w;
|
||||
|
||||
Digraph neg1_gr;
|
||||
Digraph::ArcMap<int> neg1_c(neg1_gr), neg1_l1(neg1_gr), neg1_l2(neg1_gr);
|
||||
ConstMap<Arc, int> neg1_u1(std::numeric_limits<int>::max()), neg1_u2(5000);
|
||||
Digraph::NodeMap<int> neg1_s(neg1_gr);
|
||||
|
||||
Digraph neg2_gr;
|
||||
Digraph::ArcMap<int> neg2_c(neg2_gr);
|
||||
ConstMap<Arc, int> neg2_l(0), neg2_u(1000);
|
||||
Digraph::NodeMap<int> neg2_s(neg2_gr);
|
||||
|
||||
|
||||
enum SupplyType {
|
||||
EQ,
|
||||
GEQ,
|
||||
LEQ
|
||||
};
|
||||
|
||||
|
||||
// Check the interface of an MCF algorithm
|
||||
template <typename GR, typename Value, typename Cost>
|
||||
class McfClassConcept
|
||||
{
|
||||
public:
|
||||
|
||||
template <typename MCF>
|
||||
struct Constraints {
|
||||
void constraints() {
|
||||
checkConcept<concepts::Digraph, GR>();
|
||||
|
||||
const Constraints& me = *this;
|
||||
|
||||
MCF mcf(me.g);
|
||||
const MCF& const_mcf = mcf;
|
||||
|
||||
b = mcf.reset().resetParams()
|
||||
.lowerMap(me.lower)
|
||||
.upperMap(me.upper)
|
||||
.costMap(me.cost)
|
||||
.supplyMap(me.sup)
|
||||
.stSupply(me.n, me.n, me.k)
|
||||
.run();
|
||||
|
||||
c = const_mcf.totalCost();
|
||||
x = const_mcf.template totalCost<double>();
|
||||
v = const_mcf.flow(me.a);
|
||||
c = const_mcf.potential(me.n);
|
||||
const_mcf.flowMap(fm);
|
||||
const_mcf.potentialMap(pm);
|
||||
}
|
||||
|
||||
typedef typename GR::Node Node;
|
||||
typedef typename GR::Arc Arc;
|
||||
typedef concepts::ReadMap<Node, Value> NM;
|
||||
typedef concepts::ReadMap<Arc, Value> VAM;
|
||||
typedef concepts::ReadMap<Arc, Cost> CAM;
|
||||
typedef concepts::WriteMap<Arc, Value> FlowMap;
|
||||
typedef concepts::WriteMap<Node, Cost> PotMap;
|
||||
|
||||
GR g;
|
||||
VAM lower;
|
||||
VAM upper;
|
||||
CAM cost;
|
||||
NM sup;
|
||||
Node n;
|
||||
Arc a;
|
||||
Value k;
|
||||
|
||||
FlowMap fm;
|
||||
PotMap pm;
|
||||
bool b;
|
||||
double x;
|
||||
typename MCF::Value v;
|
||||
typename MCF::Cost c;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Check the feasibility of the given flow (primal soluiton)
|
||||
template < typename GR, typename LM, typename UM,
|
||||
typename SM, typename FM >
|
||||
bool checkFlow( const GR& gr, const LM& lower, const UM& upper,
|
||||
const SM& supply, const FM& flow,
|
||||
SupplyType type = EQ )
|
||||
{
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(GR);
|
||||
|
||||
for (ArcIt e(gr); e != INVALID; ++e) {
|
||||
if (flow[e] < lower[e] || flow[e] > upper[e]) return false;
|
||||
}
|
||||
|
||||
for (NodeIt n(gr); n != INVALID; ++n) {
|
||||
typename SM::Value sum = 0;
|
||||
for (OutArcIt e(gr, n); e != INVALID; ++e)
|
||||
sum += flow[e];
|
||||
for (InArcIt e(gr, n); e != INVALID; ++e)
|
||||
sum -= flow[e];
|
||||
bool b = (type == EQ && sum == supply[n]) ||
|
||||
(type == GEQ && sum >= supply[n]) ||
|
||||
(type == LEQ && sum <= supply[n]);
|
||||
if (!b) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check the feasibility of the given potentials (dual soluiton)
|
||||
// using the "Complementary Slackness" optimality condition
|
||||
template < typename GR, typename LM, typename UM,
|
||||
typename CM, typename SM, typename FM, typename PM >
|
||||
bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
|
||||
const CM& cost, const SM& supply, const FM& flow,
|
||||
const PM& pi, SupplyType type )
|
||||
{
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(GR);
|
||||
|
||||
bool opt = true;
|
||||
for (ArcIt e(gr); opt && e != INVALID; ++e) {
|
||||
typename CM::Value red_cost =
|
||||
cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
|
||||
opt = red_cost == 0 ||
|
||||
(red_cost > 0 && flow[e] == lower[e]) ||
|
||||
(red_cost < 0 && flow[e] == upper[e]);
|
||||
}
|
||||
|
||||
for (NodeIt n(gr); opt && n != INVALID; ++n) {
|
||||
typename SM::Value sum = 0;
|
||||
for (OutArcIt e(gr, n); e != INVALID; ++e)
|
||||
sum += flow[e];
|
||||
for (InArcIt e(gr, n); e != INVALID; ++e)
|
||||
sum -= flow[e];
|
||||
if (type != LEQ) {
|
||||
opt = (pi[n] <= 0) && (sum == supply[n] || pi[n] == 0);
|
||||
} else {
|
||||
opt = (pi[n] >= 0) && (sum == supply[n] || pi[n] == 0);
|
||||
}
|
||||
}
|
||||
|
||||
return opt;
|
||||
}
|
||||
|
||||
// Check whether the dual cost is equal to the primal cost
|
||||
template < typename GR, typename LM, typename UM,
|
||||
typename CM, typename SM, typename PM >
|
||||
bool checkDualCost( const GR& gr, const LM& lower, const UM& upper,
|
||||
const CM& cost, const SM& supply, const PM& pi,
|
||||
typename CM::Value total )
|
||||
{
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(GR);
|
||||
|
||||
typename CM::Value dual_cost = 0;
|
||||
SM red_supply(gr);
|
||||
for (NodeIt n(gr); n != INVALID; ++n) {
|
||||
red_supply[n] = supply[n];
|
||||
}
|
||||
for (ArcIt a(gr); a != INVALID; ++a) {
|
||||
if (lower[a] != 0) {
|
||||
dual_cost += lower[a] * cost[a];
|
||||
red_supply[gr.source(a)] -= lower[a];
|
||||
red_supply[gr.target(a)] += lower[a];
|
||||
}
|
||||
}
|
||||
|
||||
for (NodeIt n(gr); n != INVALID; ++n) {
|
||||
dual_cost -= red_supply[n] * pi[n];
|
||||
}
|
||||
for (ArcIt a(gr); a != INVALID; ++a) {
|
||||
typename CM::Value red_cost =
|
||||
cost[a] + pi[gr.source(a)] - pi[gr.target(a)];
|
||||
dual_cost -= (upper[a] - lower[a]) * std::max(-red_cost, 0);
|
||||
}
|
||||
|
||||
return dual_cost == total;
|
||||
}
|
||||
|
||||
// Run a minimum cost flow algorithm and check the results
|
||||
template < typename MCF, typename GR,
|
||||
typename LM, typename UM,
|
||||
typename CM, typename SM,
|
||||
typename PT >
|
||||
void checkMcf( const MCF& mcf, PT mcf_result,
|
||||
const GR& gr, const LM& lower, const UM& upper,
|
||||
const CM& cost, const SM& supply,
|
||||
PT result, bool optimal, typename CM::Value total,
|
||||
const std::string &test_id = "",
|
||||
SupplyType type = EQ )
|
||||
{
|
||||
check(mcf_result == result, "Wrong result " + test_id);
|
||||
if (optimal) {
|
||||
typename GR::template ArcMap<typename SM::Value> flow(gr);
|
||||
typename GR::template NodeMap<typename CM::Value> pi(gr);
|
||||
mcf.flowMap(flow);
|
||||
mcf.potentialMap(pi);
|
||||
check(checkFlow(gr, lower, upper, supply, flow, type),
|
||||
"The flow is not feasible " + test_id);
|
||||
check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
|
||||
check(checkPotential(gr, lower, upper, cost, supply, flow, pi, type),
|
||||
"Wrong potentials " + test_id);
|
||||
check(checkDualCost(gr, lower, upper, cost, supply, pi, total),
|
||||
"Wrong dual cost " + test_id);
|
||||
}
|
||||
}
|
||||
|
||||
template < typename MCF, typename Param >
|
||||
void runMcfGeqTests( Param param,
|
||||
const std::string &test_str = "",
|
||||
bool full_neg_cost_support = false )
|
||||
{
|
||||
MCF mcf1(gr), mcf2(neg1_gr), mcf3(neg2_gr);
|
||||
|
||||
// Basic tests
|
||||
mcf1.upperMap(u).costMap(c).supplyMap(s1);
|
||||
checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s1,
|
||||
mcf1.OPTIMAL, true, 5240, test_str + "-1");
|
||||
mcf1.stSupply(v, w, 27);
|
||||
checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s2,
|
||||
mcf1.OPTIMAL, true, 7620, test_str + "-2");
|
||||
mcf1.lowerMap(l2).supplyMap(s1);
|
||||
checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s1,
|
||||
mcf1.OPTIMAL, true, 5970, test_str + "-3");
|
||||
mcf1.stSupply(v, w, 27);
|
||||
checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s2,
|
||||
mcf1.OPTIMAL, true, 8010, test_str + "-4");
|
||||
mcf1.resetParams().supplyMap(s1);
|
||||
checkMcf(mcf1, mcf1.run(param), gr, l1, cu, cc, s1,
|
||||
mcf1.OPTIMAL, true, 74, test_str + "-5");
|
||||
mcf1.lowerMap(l2).stSupply(v, w, 27);
|
||||
checkMcf(mcf1, mcf1.run(param), gr, l2, cu, cc, s2,
|
||||
mcf1.OPTIMAL, true, 94, test_str + "-6");
|
||||
mcf1.reset();
|
||||
checkMcf(mcf1, mcf1.run(param), gr, l1, cu, cc, s3,
|
||||
mcf1.OPTIMAL, true, 0, test_str + "-7");
|
||||
mcf1.lowerMap(l2).upperMap(u);
|
||||
checkMcf(mcf1, mcf1.run(param), gr, l2, u, cc, s3,
|
||||
mcf1.INFEASIBLE, false, 0, test_str + "-8");
|
||||
mcf1.lowerMap(l3).upperMap(u).costMap(c).supplyMap(s4);
|
||||
checkMcf(mcf1, mcf1.run(param), gr, l3, u, c, s4,
|
||||
mcf1.OPTIMAL, true, 6360, test_str + "-9");
|
||||
|
||||
// Tests for the GEQ form
|
||||
mcf1.resetParams().upperMap(u).costMap(c).supplyMap(s5);
|
||||
checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s5,
|
||||
mcf1.OPTIMAL, true, 3530, test_str + "-10", GEQ);
|
||||
mcf1.lowerMap(l2);
|
||||
checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s5,
|
||||
mcf1.OPTIMAL, true, 4540, test_str + "-11", GEQ);
|
||||
mcf1.supplyMap(s6);
|
||||
checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s6,
|
||||
mcf1.INFEASIBLE, false, 0, test_str + "-12", GEQ);
|
||||
|
||||
// Tests with negative costs
|
||||
mcf2.lowerMap(neg1_l1).costMap(neg1_c).supplyMap(neg1_s);
|
||||
checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l1, neg1_u1, neg1_c, neg1_s,
|
||||
mcf2.UNBOUNDED, false, 0, test_str + "-13");
|
||||
mcf2.upperMap(neg1_u2);
|
||||
checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l1, neg1_u2, neg1_c, neg1_s,
|
||||
mcf2.OPTIMAL, true, -40000, test_str + "-14");
|
||||
mcf2.resetParams().lowerMap(neg1_l2).costMap(neg1_c).supplyMap(neg1_s);
|
||||
checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l2, neg1_u1, neg1_c, neg1_s,
|
||||
mcf2.UNBOUNDED, false, 0, test_str + "-15");
|
||||
|
||||
mcf3.costMap(neg2_c).supplyMap(neg2_s);
|
||||
if (full_neg_cost_support) {
|
||||
checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
|
||||
mcf3.OPTIMAL, true, -300, test_str + "-16", GEQ);
|
||||
} else {
|
||||
checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
|
||||
mcf3.UNBOUNDED, false, 0, test_str + "-17", GEQ);
|
||||
}
|
||||
mcf3.upperMap(neg2_u);
|
||||
checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
|
||||
mcf3.OPTIMAL, true, -300, test_str + "-18", GEQ);
|
||||
|
||||
// Tests for empty graph
|
||||
Digraph gr0;
|
||||
MCF mcf0(gr0);
|
||||
mcf0.run(param);
|
||||
check(mcf0.totalCost() == 0, "Wrong total cost");
|
||||
}
|
||||
|
||||
template < typename MCF, typename Param >
|
||||
void runMcfLeqTests( Param param,
|
||||
const std::string &test_str = "" )
|
||||
{
|
||||
// Tests for the LEQ form
|
||||
MCF mcf1(gr);
|
||||
mcf1.supplyType(mcf1.LEQ);
|
||||
mcf1.upperMap(u).costMap(c).supplyMap(s6);
|
||||
checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s6,
|
||||
mcf1.OPTIMAL, true, 5080, test_str + "-19", LEQ);
|
||||
mcf1.lowerMap(l2);
|
||||
checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s6,
|
||||
mcf1.OPTIMAL, true, 5930, test_str + "-20", LEQ);
|
||||
mcf1.supplyMap(s5);
|
||||
checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s5,
|
||||
mcf1.INFEASIBLE, false, 0, test_str + "-21", LEQ);
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
// Read the test networks
|
||||
std::istringstream input(test_lgf);
|
||||
DigraphReader<Digraph>(gr, input)
|
||||
.arcMap("cost", c)
|
||||
.arcMap("cap", u)
|
||||
.arcMap("low1", l1)
|
||||
.arcMap("low2", l2)
|
||||
.arcMap("low3", l3)
|
||||
.nodeMap("sup1", s1)
|
||||
.nodeMap("sup2", s2)
|
||||
.nodeMap("sup3", s3)
|
||||
.nodeMap("sup4", s4)
|
||||
.nodeMap("sup5", s5)
|
||||
.nodeMap("sup6", s6)
|
||||
.node("source", v)
|
||||
.node("target", w)
|
||||
.run();
|
||||
|
||||
std::istringstream neg_inp1(test_neg1_lgf);
|
||||
DigraphReader<Digraph>(neg1_gr, neg_inp1)
|
||||
.arcMap("cost", neg1_c)
|
||||
.arcMap("low1", neg1_l1)
|
||||
.arcMap("low2", neg1_l2)
|
||||
.nodeMap("sup", neg1_s)
|
||||
.run();
|
||||
|
||||
std::istringstream neg_inp2(test_neg2_lgf);
|
||||
DigraphReader<Digraph>(neg2_gr, neg_inp2)
|
||||
.arcMap("cost", neg2_c)
|
||||
.nodeMap("sup", neg2_s)
|
||||
.run();
|
||||
|
||||
// Check the interface of NetworkSimplex
|
||||
{
|
||||
typedef concepts::Digraph GR;
|
||||
checkConcept< McfClassConcept<GR, int, int>,
|
||||
NetworkSimplex<GR> >();
|
||||
checkConcept< McfClassConcept<GR, double, double>,
|
||||
NetworkSimplex<GR, double> >();
|
||||
checkConcept< McfClassConcept<GR, int, double>,
|
||||
NetworkSimplex<GR, int, double> >();
|
||||
}
|
||||
|
||||
// Check the interface of CapacityScaling
|
||||
{
|
||||
typedef concepts::Digraph GR;
|
||||
checkConcept< McfClassConcept<GR, int, int>,
|
||||
CapacityScaling<GR> >();
|
||||
checkConcept< McfClassConcept<GR, double, double>,
|
||||
CapacityScaling<GR, double> >();
|
||||
checkConcept< McfClassConcept<GR, int, double>,
|
||||
CapacityScaling<GR, int, double> >();
|
||||
typedef CapacityScaling<GR>::
|
||||
SetHeap<concepts::Heap<int, RangeMap<int> > >::Create CAS;
|
||||
checkConcept< McfClassConcept<GR, int, int>, CAS >();
|
||||
}
|
||||
|
||||
// Check the interface of CostScaling
|
||||
{
|
||||
typedef concepts::Digraph GR;
|
||||
checkConcept< McfClassConcept<GR, int, int>,
|
||||
CostScaling<GR> >();
|
||||
checkConcept< McfClassConcept<GR, double, double>,
|
||||
CostScaling<GR, double> >();
|
||||
checkConcept< McfClassConcept<GR, int, double>,
|
||||
CostScaling<GR, int, double> >();
|
||||
typedef CostScaling<GR>::
|
||||
SetLargeCost<double>::Create COS;
|
||||
checkConcept< McfClassConcept<GR, int, int>, COS >();
|
||||
}
|
||||
|
||||
// Check the interface of CycleCanceling
|
||||
{
|
||||
typedef concepts::Digraph GR;
|
||||
checkConcept< McfClassConcept<GR, int, int>,
|
||||
CycleCanceling<GR> >();
|
||||
checkConcept< McfClassConcept<GR, double, double>,
|
||||
CycleCanceling<GR, double> >();
|
||||
checkConcept< McfClassConcept<GR, int, double>,
|
||||
CycleCanceling<GR, int, double> >();
|
||||
}
|
||||
|
||||
// Test NetworkSimplex
|
||||
{
|
||||
typedef NetworkSimplex<Digraph> MCF;
|
||||
runMcfGeqTests<MCF>(MCF::FIRST_ELIGIBLE, "NS-FE", true);
|
||||
runMcfLeqTests<MCF>(MCF::FIRST_ELIGIBLE, "NS-FE");
|
||||
runMcfGeqTests<MCF>(MCF::BEST_ELIGIBLE, "NS-BE", true);
|
||||
runMcfLeqTests<MCF>(MCF::BEST_ELIGIBLE, "NS-BE");
|
||||
runMcfGeqTests<MCF>(MCF::BLOCK_SEARCH, "NS-BS", true);
|
||||
runMcfLeqTests<MCF>(MCF::BLOCK_SEARCH, "NS-BS");
|
||||
runMcfGeqTests<MCF>(MCF::CANDIDATE_LIST, "NS-CL", true);
|
||||
runMcfLeqTests<MCF>(MCF::CANDIDATE_LIST, "NS-CL");
|
||||
runMcfGeqTests<MCF>(MCF::ALTERING_LIST, "NS-AL", true);
|
||||
runMcfLeqTests<MCF>(MCF::ALTERING_LIST, "NS-AL");
|
||||
}
|
||||
|
||||
// Test CapacityScaling
|
||||
{
|
||||
typedef CapacityScaling<Digraph> MCF;
|
||||
runMcfGeqTests<MCF>(0, "SSP");
|
||||
runMcfGeqTests<MCF>(2, "CAS");
|
||||
}
|
||||
|
||||
// Test CostScaling
|
||||
{
|
||||
typedef CostScaling<Digraph> MCF;
|
||||
runMcfGeqTests<MCF>(MCF::PUSH, "COS-PR");
|
||||
runMcfGeqTests<MCF>(MCF::AUGMENT, "COS-AR");
|
||||
runMcfGeqTests<MCF>(MCF::PARTIAL_AUGMENT, "COS-PAR");
|
||||
}
|
||||
|
||||
// Test CycleCanceling
|
||||
{
|
||||
typedef CycleCanceling<Digraph> MCF;
|
||||
runMcfGeqTests<MCF>(MCF::SIMPLE_CYCLE_CANCELING, "SCC");
|
||||
runMcfGeqTests<MCF>(MCF::MINIMUM_MEAN_CYCLE_CANCELING, "MMCC");
|
||||
runMcfGeqTests<MCF>(MCF::CANCEL_AND_TIGHTEN, "CAT");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
223
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/min_mean_cycle_test.cc
vendored
Normal file
223
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/min_mean_cycle_test.cc
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/path.h>
|
||||
#include <lemon/concepts/digraph.h>
|
||||
#include <lemon/concept_check.h>
|
||||
|
||||
#include <lemon/karp_mmc.h>
|
||||
#include <lemon/hartmann_orlin_mmc.h>
|
||||
#include <lemon/howard_mmc.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
char test_lgf[] =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"6\n"
|
||||
"7\n"
|
||||
"@arcs\n"
|
||||
" len1 len2 len3 len4 c1 c2 c3 c4\n"
|
||||
"1 2 1 1 1 1 0 0 0 0\n"
|
||||
"2 4 5 5 5 5 1 0 0 0\n"
|
||||
"2 3 8 8 8 8 0 0 0 0\n"
|
||||
"3 2 -2 0 0 0 1 0 0 0\n"
|
||||
"3 4 4 4 4 4 0 0 0 0\n"
|
||||
"3 7 -4 -4 -4 -4 0 0 0 0\n"
|
||||
"4 1 2 2 2 2 0 0 0 0\n"
|
||||
"4 3 3 3 3 3 1 0 0 0\n"
|
||||
"4 4 3 3 0 0 0 0 1 0\n"
|
||||
"5 2 4 4 4 4 0 0 0 0\n"
|
||||
"5 6 3 3 3 3 0 1 0 0\n"
|
||||
"6 5 2 2 2 2 0 1 0 0\n"
|
||||
"6 4 -1 -1 -1 -1 0 0 0 0\n"
|
||||
"6 7 1 1 1 1 0 0 0 0\n"
|
||||
"7 7 4 4 4 -1 0 0 0 1\n";
|
||||
|
||||
|
||||
// Check the interface of an MMC algorithm
|
||||
template <typename GR, typename Cost>
|
||||
struct MmcClassConcept
|
||||
{
|
||||
template <typename MMC>
|
||||
struct Constraints {
|
||||
void constraints() {
|
||||
const Constraints& me = *this;
|
||||
|
||||
typedef typename MMC
|
||||
::template SetPath<ListPath<GR> >
|
||||
::template SetLargeCost<Cost>
|
||||
::Create MmcAlg;
|
||||
MmcAlg mmc(me.g, me.cost);
|
||||
const MmcAlg& const_mmc = mmc;
|
||||
|
||||
typename MmcAlg::Tolerance tol = const_mmc.tolerance();
|
||||
mmc.tolerance(tol);
|
||||
|
||||
b = mmc.cycle(p).run();
|
||||
b = mmc.findCycleMean();
|
||||
b = mmc.findCycle();
|
||||
|
||||
v = const_mmc.cycleCost();
|
||||
i = const_mmc.cycleSize();
|
||||
d = const_mmc.cycleMean();
|
||||
p = const_mmc.cycle();
|
||||
}
|
||||
|
||||
typedef concepts::ReadMap<typename GR::Arc, Cost> CM;
|
||||
|
||||
GR g;
|
||||
CM cost;
|
||||
ListPath<GR> p;
|
||||
Cost v;
|
||||
int i;
|
||||
double d;
|
||||
bool b;
|
||||
};
|
||||
};
|
||||
|
||||
// Perform a test with the given parameters
|
||||
template <typename MMC>
|
||||
void checkMmcAlg(const SmartDigraph& gr,
|
||||
const SmartDigraph::ArcMap<int>& lm,
|
||||
const SmartDigraph::ArcMap<int>& cm,
|
||||
int cost, int size) {
|
||||
MMC alg(gr, lm);
|
||||
check(alg.findCycleMean(), "Wrong result");
|
||||
check(alg.cycleMean() == static_cast<double>(cost) / size,
|
||||
"Wrong cycle mean");
|
||||
alg.findCycle();
|
||||
check(alg.cycleCost() == cost && alg.cycleSize() == size,
|
||||
"Wrong path");
|
||||
SmartDigraph::ArcMap<int> cycle(gr, 0);
|
||||
for (typename MMC::Path::ArcIt a(alg.cycle()); a != INVALID; ++a) {
|
||||
++cycle[a];
|
||||
}
|
||||
for (SmartDigraph::ArcIt a(gr); a != INVALID; ++a) {
|
||||
check(cm[a] == cycle[a], "Wrong path");
|
||||
}
|
||||
}
|
||||
|
||||
// Class for comparing types
|
||||
template <typename T1, typename T2>
|
||||
struct IsSameType {
|
||||
static const int result = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IsSameType<T,T> {
|
||||
static const int result = 1;
|
||||
};
|
||||
|
||||
|
||||
int main() {
|
||||
#ifdef LEMON_HAVE_LONG_LONG
|
||||
typedef long long long_int;
|
||||
#else
|
||||
typedef long long_int;
|
||||
#endif
|
||||
|
||||
// Check the interface
|
||||
{
|
||||
typedef concepts::Digraph GR;
|
||||
|
||||
// KarpMmc
|
||||
checkConcept< MmcClassConcept<GR, int>,
|
||||
KarpMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
|
||||
checkConcept< MmcClassConcept<GR, float>,
|
||||
KarpMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
|
||||
|
||||
// HartmannOrlinMmc
|
||||
checkConcept< MmcClassConcept<GR, int>,
|
||||
HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
|
||||
checkConcept< MmcClassConcept<GR, float>,
|
||||
HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
|
||||
|
||||
// HowardMmc
|
||||
checkConcept< MmcClassConcept<GR, int>,
|
||||
HowardMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
|
||||
checkConcept< MmcClassConcept<GR, float>,
|
||||
HowardMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
|
||||
|
||||
check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, int> >
|
||||
::LargeCost, long_int>::result == 1), "Wrong LargeCost type");
|
||||
check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, float> >
|
||||
::LargeCost, double>::result == 1), "Wrong LargeCost type");
|
||||
}
|
||||
|
||||
// Run various tests
|
||||
{
|
||||
typedef SmartDigraph GR;
|
||||
DIGRAPH_TYPEDEFS(GR);
|
||||
|
||||
GR gr;
|
||||
IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
|
||||
IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
|
||||
|
||||
std::istringstream input(test_lgf);
|
||||
digraphReader(gr, input).
|
||||
arcMap("len1", l1).
|
||||
arcMap("len2", l2).
|
||||
arcMap("len3", l3).
|
||||
arcMap("len4", l4).
|
||||
arcMap("c1", c1).
|
||||
arcMap("c2", c2).
|
||||
arcMap("c3", c3).
|
||||
arcMap("c4", c4).
|
||||
run();
|
||||
|
||||
// Karp
|
||||
checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l1, c1, 6, 3);
|
||||
checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l2, c2, 5, 2);
|
||||
checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l3, c3, 0, 1);
|
||||
checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
|
||||
|
||||
// HartmannOrlin
|
||||
checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l1, c1, 6, 3);
|
||||
checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l2, c2, 5, 2);
|
||||
checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l3, c3, 0, 1);
|
||||
checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
|
||||
|
||||
// Howard
|
||||
checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l1, c1, 6, 3);
|
||||
checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l2, c2, 5, 2);
|
||||
checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l3, c3, 0, 1);
|
||||
checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
|
||||
|
||||
// Howard with iteration limit
|
||||
HowardMmc<GR, IntArcMap> mmc(gr, l1);
|
||||
check((mmc.findCycleMean(2) == HowardMmc<GR, IntArcMap>::ITERATION_LIMIT),
|
||||
"Wrong termination cause");
|
||||
check((mmc.findCycleMean(4) == HowardMmc<GR, IntArcMap>::OPTIMAL),
|
||||
"Wrong termination cause");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
171
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/mip_test.cc
vendored
Normal file
171
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/mip_test.cc
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
#include <lemon/config.h>
|
||||
|
||||
#ifdef LEMON_HAVE_CPLEX
|
||||
#include <lemon/cplex.h>
|
||||
#endif
|
||||
|
||||
#ifdef LEMON_HAVE_GLPK
|
||||
#include <lemon/glpk.h>
|
||||
#endif
|
||||
|
||||
#ifdef LEMON_HAVE_CBC
|
||||
#include <lemon/cbc.h>
|
||||
#endif
|
||||
|
||||
#ifdef LEMON_HAVE_MIP
|
||||
#include <lemon/lp.h>
|
||||
#endif
|
||||
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
void solveAndCheck(MipSolver& mip, MipSolver::ProblemType stat,
|
||||
double exp_opt) {
|
||||
using std::string;
|
||||
|
||||
mip.solve();
|
||||
//int decimal,sign;
|
||||
std::ostringstream buf;
|
||||
buf << "Type should be: " << int(stat)<<" and it is "<<int(mip.type());
|
||||
|
||||
|
||||
// itoa(stat,buf1, 10);
|
||||
check(mip.type()==stat, buf.str());
|
||||
|
||||
if (stat == MipSolver::OPTIMAL) {
|
||||
std::ostringstream sbuf;
|
||||
sbuf << "Wrong optimal value ("<< mip.solValue()
|
||||
<<" instead of " << exp_opt << ")";
|
||||
check(std::abs(mip.solValue()-exp_opt) < 1e-3, sbuf.str());
|
||||
//+ecvt(exp_opt,2)
|
||||
}
|
||||
}
|
||||
|
||||
void aTest(MipSolver& mip)
|
||||
{
|
||||
//The following example is very simple
|
||||
|
||||
|
||||
typedef MipSolver::Row Row;
|
||||
typedef MipSolver::Col Col;
|
||||
|
||||
|
||||
Col x1 = mip.addCol();
|
||||
Col x2 = mip.addCol();
|
||||
|
||||
|
||||
//Objective function
|
||||
mip.obj(x1);
|
||||
|
||||
mip.max();
|
||||
|
||||
//Unconstrained optimization
|
||||
mip.solve();
|
||||
//Check it out!
|
||||
|
||||
//Constraints
|
||||
mip.addRow(2 * x1 + x2 <= 2);
|
||||
Row y2 = mip.addRow(x1 - 2 * x2 <= 0);
|
||||
|
||||
//Nonnegativity of the variable x1
|
||||
mip.colLowerBound(x1, 0);
|
||||
|
||||
|
||||
//Maximization of x1
|
||||
//over the triangle with vertices (0,0),(4/5,2/5),(0,2)
|
||||
double expected_opt=4.0/5.0;
|
||||
solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
|
||||
|
||||
|
||||
//Restrict x2 to integer
|
||||
mip.colType(x2,MipSolver::INTEGER);
|
||||
expected_opt=1.0/2.0;
|
||||
solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
|
||||
|
||||
|
||||
//Restrict both to integer
|
||||
mip.colType(x1,MipSolver::INTEGER);
|
||||
expected_opt=0;
|
||||
solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
|
||||
|
||||
//Erase a variable
|
||||
mip.erase(x2);
|
||||
mip.rowUpperBound(y2, 8);
|
||||
expected_opt=1;
|
||||
solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<class MIP>
|
||||
void cloneTest()
|
||||
{
|
||||
|
||||
MIP* mip = new MIP();
|
||||
MIP* mipnew = mip->newSolver();
|
||||
MIP* mipclone = mip->cloneSolver();
|
||||
delete mip;
|
||||
delete mipnew;
|
||||
delete mipclone;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
#ifdef LEMON_HAVE_MIP
|
||||
{
|
||||
Mip mip1;
|
||||
aTest(mip1);
|
||||
cloneTest<Mip>();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LEMON_HAVE_GLPK
|
||||
{
|
||||
GlpkMip mip1;
|
||||
aTest(mip1);
|
||||
cloneTest<GlpkMip>();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LEMON_HAVE_CPLEX
|
||||
try {
|
||||
CplexMip mip2;
|
||||
aTest(mip2);
|
||||
cloneTest<CplexMip>();
|
||||
} catch (CplexEnv::LicenseError& error) {
|
||||
check(false, error.what());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LEMON_HAVE_CBC
|
||||
{
|
||||
CbcMip mip1;
|
||||
aTest(mip1);
|
||||
cloneTest<CbcMip>();
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
142
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/nagamochi_ibaraki_test.cc
vendored
Normal file
142
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/nagamochi_ibaraki_test.cc
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/adaptors.h>
|
||||
#include <lemon/concepts/graph.h>
|
||||
#include <lemon/concepts/maps.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/nagamochi_ibaraki.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
using namespace std;
|
||||
|
||||
const std::string lgf =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"@edges\n"
|
||||
" cap1 cap2 cap3\n"
|
||||
"0 1 1 1 1 \n"
|
||||
"0 2 2 2 4 \n"
|
||||
"1 2 4 4 4 \n"
|
||||
"3 4 1 1 1 \n"
|
||||
"3 5 2 2 4 \n"
|
||||
"4 5 4 4 4 \n"
|
||||
"2 3 1 6 6 \n";
|
||||
|
||||
void checkNagamochiIbarakiCompile()
|
||||
{
|
||||
typedef int Value;
|
||||
typedef concepts::Graph Graph;
|
||||
|
||||
typedef Graph::Node Node;
|
||||
typedef Graph::Edge Edge;
|
||||
typedef concepts::ReadMap<Edge, Value> CapMap;
|
||||
typedef concepts::WriteMap<Node, bool> CutMap;
|
||||
|
||||
Graph g;
|
||||
Node n;
|
||||
CapMap cap;
|
||||
CutMap cut;
|
||||
Value v;
|
||||
bool b;
|
||||
::lemon::ignore_unused_variable_warning(v,b);
|
||||
|
||||
NagamochiIbaraki<Graph, CapMap> ni_test(g, cap);
|
||||
const NagamochiIbaraki<Graph, CapMap>& const_ni_test = ni_test;
|
||||
|
||||
ni_test.init();
|
||||
ni_test.start();
|
||||
b = ni_test.processNextPhase();
|
||||
ni_test.run();
|
||||
|
||||
v = const_ni_test.minCutValue();
|
||||
v = const_ni_test.minCutMap(cut);
|
||||
}
|
||||
|
||||
template <typename Graph, typename CapMap, typename CutMap>
|
||||
typename CapMap::Value
|
||||
cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut)
|
||||
{
|
||||
typename CapMap::Value sum = 0;
|
||||
for (typename Graph::EdgeIt e(graph); e != INVALID; ++e) {
|
||||
if (cut[graph.u(e)] != cut[graph.v(e)]) {
|
||||
sum += cap[e];
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
int main() {
|
||||
SmartGraph graph;
|
||||
SmartGraph::EdgeMap<int> cap1(graph), cap2(graph), cap3(graph);
|
||||
SmartGraph::NodeMap<bool> cut(graph);
|
||||
|
||||
istringstream input(lgf);
|
||||
graphReader(graph, input)
|
||||
.edgeMap("cap1", cap1)
|
||||
.edgeMap("cap2", cap2)
|
||||
.edgeMap("cap3", cap3)
|
||||
.run();
|
||||
|
||||
{
|
||||
NagamochiIbaraki<SmartGraph> ni(graph, cap1);
|
||||
ni.run();
|
||||
ni.minCutMap(cut);
|
||||
|
||||
check(ni.minCutValue() == 1, "Wrong cut value");
|
||||
check(ni.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value");
|
||||
}
|
||||
{
|
||||
NagamochiIbaraki<SmartGraph> ni(graph, cap2);
|
||||
ni.run();
|
||||
ni.minCutMap(cut);
|
||||
|
||||
check(ni.minCutValue() == 3, "Wrong cut value");
|
||||
check(ni.minCutValue() == cutValue(graph, cap2, cut), "Wrong cut value");
|
||||
}
|
||||
{
|
||||
NagamochiIbaraki<SmartGraph> ni(graph, cap3);
|
||||
ni.run();
|
||||
ni.minCutMap(cut);
|
||||
|
||||
check(ni.minCutValue() == 5, "Wrong cut value");
|
||||
check(ni.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value");
|
||||
}
|
||||
{
|
||||
NagamochiIbaraki<SmartGraph>::SetUnitCapacity::Create ni(graph);
|
||||
ni.run();
|
||||
ni.minCutMap(cut);
|
||||
|
||||
ConstMap<SmartGraph::Edge, int> cap4(1);
|
||||
check(ni.minCutValue() == 1, "Wrong cut value");
|
||||
check(ni.minCutValue() == cutValue(graph, cap4, cut), "Wrong cut value");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
339
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/path_test.cc
vendored
Normal file
339
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/path_test.cc
vendored
Normal file
@@ -0,0 +1,339 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include <lemon/concepts/path.h>
|
||||
#include <lemon/concepts/digraph.h>
|
||||
#include <lemon/concept_check.h>
|
||||
|
||||
#include <lemon/path.h>
|
||||
#include <lemon/list_graph.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace lemon;
|
||||
|
||||
template <typename GR>
|
||||
void checkConcepts() {
|
||||
checkConcept<concepts::Path<GR>, concepts::Path<GR> >();
|
||||
checkConcept<concepts::Path<GR>, Path<GR> >();
|
||||
checkConcept<concepts::Path<GR>, SimplePath<GR> >();
|
||||
checkConcept<concepts::Path<GR>, StaticPath<GR> >();
|
||||
checkConcept<concepts::Path<GR>, ListPath<GR> >();
|
||||
}
|
||||
|
||||
// Conecpt checking for path structures
|
||||
void checkPathConcepts() {
|
||||
checkConcepts<concepts::Digraph>();
|
||||
checkConcepts<ListDigraph>();
|
||||
}
|
||||
|
||||
// Check if proper copy consructor is called (use valgrind for testing)
|
||||
template <typename GR, typename P1, typename P2>
|
||||
void checkCopy(typename GR::Arc a) {
|
||||
P1 p;
|
||||
p.addBack(a);
|
||||
P1 q;
|
||||
q = p;
|
||||
P1 r(p);
|
||||
P2 q2;
|
||||
q2 = p;
|
||||
P2 r2(p);
|
||||
}
|
||||
|
||||
// Tests for copy constructors and assignment operators of paths
|
||||
void checkPathCopy() {
|
||||
ListDigraph g;
|
||||
ListDigraph::Arc a = g.addArc(g.addNode(), g.addNode());
|
||||
|
||||
typedef Path<ListDigraph> Path1;
|
||||
typedef SimplePath<ListDigraph> Path2;
|
||||
typedef ListPath<ListDigraph> Path3;
|
||||
typedef StaticPath<ListDigraph> Path4;
|
||||
checkCopy<ListDigraph, Path1, Path2>(a);
|
||||
checkCopy<ListDigraph, Path1, Path3>(a);
|
||||
checkCopy<ListDigraph, Path1, Path4>(a);
|
||||
checkCopy<ListDigraph, Path2, Path1>(a);
|
||||
checkCopy<ListDigraph, Path2, Path3>(a);
|
||||
checkCopy<ListDigraph, Path2, Path4>(a);
|
||||
checkCopy<ListDigraph, Path3, Path1>(a);
|
||||
checkCopy<ListDigraph, Path3, Path2>(a);
|
||||
checkCopy<ListDigraph, Path3, Path4>(a);
|
||||
}
|
||||
|
||||
// Class for testing path functions
|
||||
class CheckPathFunctions {
|
||||
typedef ListDigraph GR;
|
||||
DIGRAPH_TYPEDEFS(GR);
|
||||
GR gr;
|
||||
const GR& cgr;
|
||||
Node n1, n2, n3, n4;
|
||||
Node tmp_n;
|
||||
Arc a1, a2, a3, a4;
|
||||
Arc tmp_a;
|
||||
|
||||
public:
|
||||
|
||||
CheckPathFunctions() : cgr(gr) {
|
||||
n1 = gr.addNode();
|
||||
n2 = gr.addNode();
|
||||
n3 = gr.addNode();
|
||||
n4 = gr.addNode();
|
||||
a1 = gr.addArc(n1, n2);
|
||||
a2 = gr.addArc(n2, n3);
|
||||
a3 = gr.addArc(n3, n4);
|
||||
a4 = gr.addArc(n4, n1);
|
||||
}
|
||||
|
||||
void run() {
|
||||
checkBackAndFrontInsertablePath<Path<GR> >();
|
||||
checkBackAndFrontInsertablePath<ListPath<GR> >();
|
||||
checkBackInsertablePath<SimplePath<GR> >();
|
||||
|
||||
checkListPathSplitAndSplice();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template <typename P>
|
||||
void checkBackInsertablePath() {
|
||||
|
||||
// Create and check empty path
|
||||
P p;
|
||||
const P& cp = p;
|
||||
check(cp.empty(), "The path is not empty");
|
||||
check(cp.length() == 0, "The path is not empty");
|
||||
// check(cp.front() == INVALID, "Wrong front()");
|
||||
// check(cp.back() == INVALID, "Wrong back()");
|
||||
typename P::ArcIt ai(cp);
|
||||
check(ai == INVALID, "Wrong ArcIt");
|
||||
check(pathSource(cgr, cp) == INVALID, "Wrong pathSource()");
|
||||
check(pathTarget(cgr, cp) == INVALID, "Wrong pathTarget()");
|
||||
check(checkPath(cgr, cp), "Wrong checkPath()");
|
||||
PathNodeIt<P> ni(cgr, cp);
|
||||
check(ni == INVALID, "Wrong PathNodeIt");
|
||||
|
||||
// Check single-arc path
|
||||
p.addBack(a1);
|
||||
check(!cp.empty(), "Wrong empty()");
|
||||
check(cp.length() == 1, "Wrong length");
|
||||
check(cp.front() == a1, "Wrong front()");
|
||||
check(cp.back() == a1, "Wrong back()");
|
||||
check(cp.nth(0) == a1, "Wrong nth()");
|
||||
ai = cp.nthIt(0);
|
||||
check((tmp_a = ai) == a1, "Wrong nthIt()");
|
||||
check(++ai == INVALID, "Wrong nthIt()");
|
||||
typename P::ArcIt ai2(cp);
|
||||
check((tmp_a = ai2) == a1, "Wrong ArcIt");
|
||||
check(++ai2 == INVALID, "Wrong ArcIt");
|
||||
check(pathSource(cgr, cp) == n1, "Wrong pathSource()");
|
||||
check(pathTarget(cgr, cp) == n2, "Wrong pathTarget()");
|
||||
check(checkPath(cgr, cp), "Wrong checkPath()");
|
||||
PathNodeIt<P> ni2(cgr, cp);
|
||||
check((tmp_n = ni2) == n1, "Wrong PathNodeIt");
|
||||
check((tmp_n = ++ni2) == n2, "Wrong PathNodeIt");
|
||||
check(++ni2 == INVALID, "Wrong PathNodeIt");
|
||||
|
||||
// Check adding more arcs
|
||||
p.addBack(a2);
|
||||
p.addBack(a3);
|
||||
check(!cp.empty(), "Wrong empty()");
|
||||
check(cp.length() == 3, "Wrong length");
|
||||
check(cp.front() == a1, "Wrong front()");
|
||||
check(cp.back() == a3, "Wrong back()");
|
||||
check(cp.nth(0) == a1, "Wrong nth()");
|
||||
check(cp.nth(1) == a2, "Wrong nth()");
|
||||
check(cp.nth(2) == a3, "Wrong nth()");
|
||||
typename P::ArcIt ai3(cp);
|
||||
check((tmp_a = ai3) == a1, "Wrong ArcIt");
|
||||
check((tmp_a = ++ai3) == a2, "Wrong nthIt()");
|
||||
check((tmp_a = ++ai3) == a3, "Wrong nthIt()");
|
||||
check(++ai3 == INVALID, "Wrong nthIt()");
|
||||
ai = cp.nthIt(0);
|
||||
check((tmp_a = ai) == a1, "Wrong nthIt()");
|
||||
check((tmp_a = ++ai) == a2, "Wrong nthIt()");
|
||||
ai = cp.nthIt(2);
|
||||
check((tmp_a = ai) == a3, "Wrong nthIt()");
|
||||
check(++ai == INVALID, "Wrong nthIt()");
|
||||
check(pathSource(cgr, cp) == n1, "Wrong pathSource()");
|
||||
check(pathTarget(cgr, cp) == n4, "Wrong pathTarget()");
|
||||
check(checkPath(cgr, cp), "Wrong checkPath()");
|
||||
PathNodeIt<P> ni3(cgr, cp);
|
||||
check((tmp_n = ni3) == n1, "Wrong PathNodeIt");
|
||||
check((tmp_n = ++ni3) == n2, "Wrong PathNodeIt");
|
||||
check((tmp_n = ++ni3) == n3, "Wrong PathNodeIt");
|
||||
check((tmp_n = ++ni3) == n4, "Wrong PathNodeIt");
|
||||
check(++ni3 == INVALID, "Wrong PathNodeIt");
|
||||
|
||||
// Check arc removal and addition
|
||||
p.eraseBack();
|
||||
p.eraseBack();
|
||||
p.addBack(a2);
|
||||
check(!cp.empty(), "Wrong empty()");
|
||||
check(cp.length() == 2, "Wrong length");
|
||||
check(cp.front() == a1, "Wrong front()");
|
||||
check(cp.back() == a2, "Wrong back()");
|
||||
check(pathSource(cgr, cp) == n1, "Wrong pathSource()");
|
||||
check(pathTarget(cgr, cp) == n3, "Wrong pathTarget()");
|
||||
check(checkPath(cgr, cp), "Wrong checkPath()");
|
||||
|
||||
// Check clear()
|
||||
p.clear();
|
||||
check(cp.empty(), "The path is not empty");
|
||||
check(cp.length() == 0, "The path is not empty");
|
||||
|
||||
// Check inconsistent path
|
||||
p.addBack(a4);
|
||||
p.addBack(a2);
|
||||
p.addBack(a1);
|
||||
check(!cp.empty(), "Wrong empty()");
|
||||
check(cp.length() == 3, "Wrong length");
|
||||
check(cp.front() == a4, "Wrong front()");
|
||||
check(cp.back() == a1, "Wrong back()");
|
||||
check(pathSource(cgr, cp) == n4, "Wrong pathSource()");
|
||||
check(pathTarget(cgr, cp) == n2, "Wrong pathTarget()");
|
||||
check(!checkPath(cgr, cp), "Wrong checkPath()");
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
void checkBackAndFrontInsertablePath() {
|
||||
|
||||
// Include back insertable test cases
|
||||
checkBackInsertablePath<P>();
|
||||
|
||||
// Check front and back insertion
|
||||
P p;
|
||||
const P& cp = p;
|
||||
p.addFront(a4);
|
||||
p.addBack(a1);
|
||||
p.addFront(a3);
|
||||
check(!cp.empty(), "Wrong empty()");
|
||||
check(cp.length() == 3, "Wrong length");
|
||||
check(cp.front() == a3, "Wrong front()");
|
||||
check(cp.back() == a1, "Wrong back()");
|
||||
check(cp.nth(0) == a3, "Wrong nth()");
|
||||
check(cp.nth(1) == a4, "Wrong nth()");
|
||||
check(cp.nth(2) == a1, "Wrong nth()");
|
||||
typename P::ArcIt ai(cp);
|
||||
check((tmp_a = ai) == a3, "Wrong ArcIt");
|
||||
check((tmp_a = ++ai) == a4, "Wrong nthIt()");
|
||||
check((tmp_a = ++ai) == a1, "Wrong nthIt()");
|
||||
check(++ai == INVALID, "Wrong nthIt()");
|
||||
ai = cp.nthIt(0);
|
||||
check((tmp_a = ai) == a3, "Wrong nthIt()");
|
||||
check((tmp_a = ++ai) == a4, "Wrong nthIt()");
|
||||
ai = cp.nthIt(2);
|
||||
check((tmp_a = ai) == a1, "Wrong nthIt()");
|
||||
check(++ai == INVALID, "Wrong nthIt()");
|
||||
check(pathSource(cgr, cp) == n3, "Wrong pathSource()");
|
||||
check(pathTarget(cgr, cp) == n2, "Wrong pathTarget()");
|
||||
check(checkPath(cgr, cp), "Wrong checkPath()");
|
||||
|
||||
// Check eraseFront()
|
||||
p.eraseFront();
|
||||
p.addBack(a2);
|
||||
check(!cp.empty(), "Wrong empty()");
|
||||
check(cp.length() == 3, "Wrong length");
|
||||
check(cp.front() == a4, "Wrong front()");
|
||||
check(cp.back() == a2, "Wrong back()");
|
||||
check(cp.nth(0) == a4, "Wrong nth()");
|
||||
check(cp.nth(1) == a1, "Wrong nth()");
|
||||
check(cp.nth(2) == a2, "Wrong nth()");
|
||||
typename P::ArcIt ai2(cp);
|
||||
check((tmp_a = ai2) == a4, "Wrong ArcIt");
|
||||
check((tmp_a = ++ai2) == a1, "Wrong nthIt()");
|
||||
check((tmp_a = ++ai2) == a2, "Wrong nthIt()");
|
||||
check(++ai2 == INVALID, "Wrong nthIt()");
|
||||
ai = cp.nthIt(0);
|
||||
check((tmp_a = ai) == a4, "Wrong nthIt()");
|
||||
check((tmp_a = ++ai) == a1, "Wrong nthIt()");
|
||||
ai = cp.nthIt(2);
|
||||
check((tmp_a = ai) == a2, "Wrong nthIt()");
|
||||
check(++ai == INVALID, "Wrong nthIt()");
|
||||
check(pathSource(cgr, cp) == n4, "Wrong pathSource()");
|
||||
check(pathTarget(cgr, cp) == n3, "Wrong pathTarget()");
|
||||
check(checkPath(cgr, cp), "Wrong checkPath()");
|
||||
}
|
||||
|
||||
void checkListPathSplitAndSplice() {
|
||||
|
||||
// Build a path with spliceFront() and spliceBack()
|
||||
ListPath<GR> p1, p2, p3, p4;
|
||||
p1.addBack(a3);
|
||||
p1.addFront(a2);
|
||||
p2.addBack(a1);
|
||||
p1.spliceFront(p2);
|
||||
p3.addFront(a4);
|
||||
p1.spliceBack(p3);
|
||||
check(p1.length() == 4, "Wrong length");
|
||||
check(p1.front() == a1, "Wrong front()");
|
||||
check(p1.back() == a4, "Wrong back()");
|
||||
ListPath<GR>::ArcIt ai(p1);
|
||||
check((tmp_a = ai) == a1, "Wrong ArcIt");
|
||||
check((tmp_a = ++ai) == a2, "Wrong nthIt()");
|
||||
check((tmp_a = ++ai) == a3, "Wrong nthIt()");
|
||||
check((tmp_a = ++ai) == a4, "Wrong nthIt()");
|
||||
check(++ai == INVALID, "Wrong nthIt()");
|
||||
check(checkPath(cgr, p1), "Wrong checkPath()");
|
||||
|
||||
// Check split()
|
||||
p1.split(p1.nthIt(2), p2);
|
||||
check(p1.length() == 2, "Wrong length");
|
||||
ai = p1.nthIt(0);
|
||||
check((tmp_a = ai) == a1, "Wrong ArcIt");
|
||||
check((tmp_a = ++ai) == a2, "Wrong nthIt()");
|
||||
check(++ai == INVALID, "Wrong nthIt()");
|
||||
check(checkPath(cgr, p1), "Wrong checkPath()");
|
||||
check(p2.length() == 2, "Wrong length");
|
||||
ai = p2.nthIt(0);
|
||||
check((tmp_a = ai) == a3, "Wrong ArcIt");
|
||||
check((tmp_a = ++ai) == a4, "Wrong nthIt()");
|
||||
check(++ai == INVALID, "Wrong nthIt()");
|
||||
check(checkPath(cgr, p2), "Wrong checkPath()");
|
||||
|
||||
// Check split() and splice()
|
||||
p1.spliceFront(p2);
|
||||
p1.split(p1.nthIt(2), p2);
|
||||
p2.split(p2.nthIt(1), p3);
|
||||
p2.spliceBack(p1);
|
||||
p2.splice(p2.nthIt(1), p3);
|
||||
check(p2.length() == 4, "Wrong length");
|
||||
check(p2.front() == a1, "Wrong front()");
|
||||
check(p2.back() == a4, "Wrong back()");
|
||||
ai = p2.nthIt(0);
|
||||
check((tmp_a = ai) == a1, "Wrong ArcIt");
|
||||
check((tmp_a = ++ai) == a2, "Wrong nthIt()");
|
||||
check((tmp_a = ++ai) == a3, "Wrong nthIt()");
|
||||
check((tmp_a = ++ai) == a4, "Wrong nthIt()");
|
||||
check(++ai == INVALID, "Wrong nthIt()");
|
||||
check(checkPath(cgr, p2), "Wrong checkPath()");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
int main() {
|
||||
checkPathConcepts();
|
||||
checkPathCopy();
|
||||
CheckPathFunctions cpf;
|
||||
cpf.run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
262
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/planarity_test.cc
vendored
Normal file
262
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/planarity_test.cc
vendored
Normal file
@@ -0,0 +1,262 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <lemon/planarity.h>
|
||||
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/connectivity.h>
|
||||
#include <lemon/dim2.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
using namespace lemon::dim2;
|
||||
|
||||
const int lgfn = 4;
|
||||
const std::string lgf[lgfn] = {
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"@edges\n"
|
||||
" label\n"
|
||||
"0 1 0\n"
|
||||
"0 2 0\n"
|
||||
"0 3 0\n"
|
||||
"0 4 0\n"
|
||||
"1 2 0\n"
|
||||
"1 3 0\n"
|
||||
"1 4 0\n"
|
||||
"2 3 0\n"
|
||||
"2 4 0\n"
|
||||
"3 4 0\n",
|
||||
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"@edges\n"
|
||||
" label\n"
|
||||
"0 1 0\n"
|
||||
"0 2 0\n"
|
||||
"0 3 0\n"
|
||||
"0 4 0\n"
|
||||
"1 2 0\n"
|
||||
"1 3 0\n"
|
||||
"2 3 0\n"
|
||||
"2 4 0\n"
|
||||
"3 4 0\n",
|
||||
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"@edges\n"
|
||||
" label\n"
|
||||
"0 3 0\n"
|
||||
"0 4 0\n"
|
||||
"0 5 0\n"
|
||||
"1 3 0\n"
|
||||
"1 4 0\n"
|
||||
"1 5 0\n"
|
||||
"2 3 0\n"
|
||||
"2 4 0\n"
|
||||
"2 5 0\n",
|
||||
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"0\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"@edges\n"
|
||||
" label\n"
|
||||
"0 3 0\n"
|
||||
"0 4 0\n"
|
||||
"0 5 0\n"
|
||||
"1 3 0\n"
|
||||
"1 4 0\n"
|
||||
"1 5 0\n"
|
||||
"2 3 0\n"
|
||||
"2 5 0\n"
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef SmartGraph Graph;
|
||||
GRAPH_TYPEDEFS(Graph);
|
||||
|
||||
typedef PlanarEmbedding<SmartGraph> PE;
|
||||
typedef PlanarDrawing<SmartGraph> PD;
|
||||
typedef PlanarColoring<SmartGraph> PC;
|
||||
|
||||
void checkEmbedding(const Graph& graph, PE& pe) {
|
||||
int face_num = 0;
|
||||
|
||||
Graph::ArcMap<int> face(graph, -1);
|
||||
|
||||
for (ArcIt a(graph); a != INVALID; ++a) {
|
||||
if (face[a] == -1) {
|
||||
Arc b = a;
|
||||
while (face[b] == -1) {
|
||||
face[b] = face_num;
|
||||
b = pe.next(graph.oppositeArc(b));
|
||||
}
|
||||
check(face[b] == face_num, "Wrong face");
|
||||
++face_num;
|
||||
}
|
||||
}
|
||||
check(face_num + countNodes(graph) - countConnectedComponents(graph) ==
|
||||
countEdges(graph) + 1, "Euler test does not passed");
|
||||
}
|
||||
|
||||
void checkKuratowski(const Graph& graph, PE& pe) {
|
||||
std::map<int, int> degs;
|
||||
for (NodeIt n(graph); n != INVALID; ++n) {
|
||||
int deg = 0;
|
||||
for (IncEdgeIt e(graph, n); e != INVALID; ++e) {
|
||||
if (pe.kuratowski(e)) {
|
||||
++deg;
|
||||
}
|
||||
}
|
||||
++degs[deg];
|
||||
}
|
||||
for (std::map<int, int>::iterator it = degs.begin(); it != degs.end(); ++it) {
|
||||
check(it->first == 0 || it->first == 2 ||
|
||||
(it->first == 3 && it->second == 6) ||
|
||||
(it->first == 4 && it->second == 5),
|
||||
"Wrong degree in Kuratowski graph");
|
||||
}
|
||||
|
||||
// Not full test
|
||||
check((degs[3] == 0) != (degs[4] == 0), "Wrong Kuratowski graph");
|
||||
}
|
||||
|
||||
bool intersect(Point<int> e1, Point<int> e2, Point<int> f1, Point<int> f2) {
|
||||
int l, r;
|
||||
if (std::min(e1.x, e2.x) > std::max(f1.x, f2.x)) return false;
|
||||
if (std::max(e1.x, e2.x) < std::min(f1.x, f2.x)) return false;
|
||||
if (std::min(e1.y, e2.y) > std::max(f1.y, f2.y)) return false;
|
||||
if (std::max(e1.y, e2.y) < std::min(f1.y, f2.y)) return false;
|
||||
|
||||
l = (e2.x - e1.x) * (f1.y - e1.y) - (e2.y - e1.y) * (f1.x - e1.x);
|
||||
r = (e2.x - e1.x) * (f2.y - e1.y) - (e2.y - e1.y) * (f2.x - e1.x);
|
||||
if (!((l >= 0 && r <= 0) || (l <= 0 && r >= 0))) return false;
|
||||
l = (f2.x - f1.x) * (e1.y - f1.y) - (f2.y - f1.y) * (e1.x - f1.x);
|
||||
r = (f2.x - f1.x) * (e2.y - f1.y) - (f2.y - f1.y) * (e2.x - f1.x);
|
||||
if (!((l >= 0 && r <= 0) || (l <= 0 && r >= 0))) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool collinear(Point<int> p, Point<int> q, Point<int> r) {
|
||||
int v;
|
||||
v = (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x);
|
||||
if (v != 0) return false;
|
||||
v = (q.x - p.x) * (r.x - p.x) + (q.y - p.y) * (r.y - p.y);
|
||||
if (v < 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void checkDrawing(const Graph& graph, PD& pd) {
|
||||
for (Graph::NodeIt n(graph); n != INVALID; ++n) {
|
||||
Graph::NodeIt m(n);
|
||||
for (++m; m != INVALID; ++m) {
|
||||
check(pd[m] != pd[n], "Two nodes with identical coordinates");
|
||||
}
|
||||
}
|
||||
|
||||
for (Graph::EdgeIt e(graph); e != INVALID; ++e) {
|
||||
for (Graph::EdgeIt f(e); f != e; ++f) {
|
||||
Point<int> e1 = pd[graph.u(e)];
|
||||
Point<int> e2 = pd[graph.v(e)];
|
||||
Point<int> f1 = pd[graph.u(f)];
|
||||
Point<int> f2 = pd[graph.v(f)];
|
||||
|
||||
if (graph.u(e) == graph.u(f)) {
|
||||
check(!collinear(e1, e2, f2), "Wrong drawing");
|
||||
} else if (graph.u(e) == graph.v(f)) {
|
||||
check(!collinear(e1, e2, f1), "Wrong drawing");
|
||||
} else if (graph.v(e) == graph.u(f)) {
|
||||
check(!collinear(e2, e1, f2), "Wrong drawing");
|
||||
} else if (graph.v(e) == graph.v(f)) {
|
||||
check(!collinear(e2, e1, f1), "Wrong drawing");
|
||||
} else {
|
||||
check(!intersect(e1, e2, f1, f2), "Wrong drawing");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void checkColoring(const Graph& graph, PC& pc, int num) {
|
||||
for (NodeIt n(graph); n != INVALID; ++n) {
|
||||
check(pc.colorIndex(n) >= 0 && pc.colorIndex(n) < num,
|
||||
"Wrong coloring");
|
||||
}
|
||||
for (EdgeIt e(graph); e != INVALID; ++e) {
|
||||
check(pc.colorIndex(graph.u(e)) != pc.colorIndex(graph.v(e)),
|
||||
"Wrong coloring");
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
for (int i = 0; i < lgfn; ++i) {
|
||||
std::istringstream lgfs(lgf[i]);
|
||||
|
||||
SmartGraph graph;
|
||||
graphReader(graph, lgfs).run();
|
||||
|
||||
check(simpleGraph(graph), "Test graphs must be simple");
|
||||
|
||||
PE pe(graph);
|
||||
bool planar = pe.run();
|
||||
check(checkPlanarity(graph) == planar, "Planarity checking failed");
|
||||
|
||||
if (planar) {
|
||||
checkEmbedding(graph, pe);
|
||||
|
||||
PlanarDrawing<Graph> pd(graph);
|
||||
pd.run(pe.embeddingMap());
|
||||
checkDrawing(graph, pd);
|
||||
|
||||
PlanarColoring<Graph> pc(graph);
|
||||
pc.runFiveColoring(pe.embeddingMap());
|
||||
checkColoring(graph, pc, 5);
|
||||
|
||||
} else {
|
||||
checkKuratowski(graph, pe);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
266
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/radix_sort_test.cc
vendored
Normal file
266
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/radix_sort_test.cc
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/time_measure.h>
|
||||
#include <lemon/smart_graph.h>
|
||||
#include <lemon/maps.h>
|
||||
#include <lemon/radix_sort.h>
|
||||
#include <lemon/math.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
static const int n = 10000;
|
||||
|
||||
struct Negate {
|
||||
typedef int argument_type;
|
||||
typedef int result_type;
|
||||
int operator()(int a) { return - a; }
|
||||
};
|
||||
|
||||
int negate(int a) { return - a; }
|
||||
|
||||
template<class T>
|
||||
bool isTheSame(T &a, T&b)
|
||||
{
|
||||
typename T::iterator ai=a.begin();
|
||||
typename T::iterator bi=b.begin();
|
||||
for(;ai!=a.end()||bi!=b.end();++ai,++bi)
|
||||
if(*ai!=*bi) return false;
|
||||
return ai==a.end()&&bi==b.end();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T listsort(typename T::iterator b, typename T::iterator e)
|
||||
{
|
||||
if(b==e) return T();
|
||||
typename T::iterator bn=b;
|
||||
if(++bn==e) {
|
||||
T l;
|
||||
l.push_back(*b);
|
||||
return l;
|
||||
}
|
||||
typename T::iterator m=b;
|
||||
bool x=false;
|
||||
for(typename T::iterator i=b;i!=e;++i,x=!x)
|
||||
if(x) ++m;
|
||||
T l1(listsort<T>(b,m));
|
||||
T l2(listsort<T>(m,e));
|
||||
T l;
|
||||
while((!l1.empty())&&(!l2.empty()))
|
||||
if(l1.front()<=l2.front())
|
||||
{
|
||||
l.push_back(l1.front());
|
||||
l1.pop_front();
|
||||
}
|
||||
else {
|
||||
l.push_back(l2.front());
|
||||
l2.pop_front();
|
||||
}
|
||||
while(!l1.empty())
|
||||
{
|
||||
l.push_back(l1.front());
|
||||
l1.pop_front();
|
||||
}
|
||||
while(!l2.empty())
|
||||
{
|
||||
l.push_back(l2.front());
|
||||
l2.pop_front();
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void generateIntSequence(int n, T & data) {
|
||||
int prime = 9973;
|
||||
int root = 136, value = 1;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
data.push_back(value - prime / 2);
|
||||
value = (value * root) % prime;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void generateCharSequence(int n, T & data) {
|
||||
int prime = 251;
|
||||
int root = 3, value = root;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
data.push_back(static_cast<unsigned char>(value));
|
||||
value = (value * root) % prime;
|
||||
}
|
||||
}
|
||||
|
||||
void checkRadixSort() {
|
||||
{
|
||||
std::vector<int> data1;
|
||||
generateIntSequence(n, data1);
|
||||
|
||||
std::vector<int> data2(data1);
|
||||
std::sort(data1.begin(), data1.end());
|
||||
|
||||
radixSort(data2.begin(), data2.end());
|
||||
for (int i = 0; i < n; ++i) {
|
||||
check(data1[i] == data2[i], "Test failed");
|
||||
}
|
||||
|
||||
// radixSort(data2.begin(), data2.end(), Negate());
|
||||
// for (int i = 0; i < n; ++i) {
|
||||
// check(data1[i] == data2[n - 1 - i], "Test failed");
|
||||
// }
|
||||
|
||||
// radixSort(data2.begin(), data2.end(), negate);
|
||||
// for (int i = 0; i < n; ++i) {
|
||||
// check(data1[i] == data2[n - 1 - i], "Test failed");
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<unsigned char> data1(n);
|
||||
generateCharSequence(n, data1);
|
||||
|
||||
std::vector<unsigned char> data2(data1);
|
||||
std::sort(data1.begin(), data1.end());
|
||||
|
||||
radixSort(data2.begin(), data2.end());
|
||||
for (int i = 0; i < n; ++i) {
|
||||
check(data1[i] == data2[i], "Test failed");
|
||||
}
|
||||
|
||||
}
|
||||
{
|
||||
std::list<int> data1;
|
||||
generateIntSequence(n, data1);
|
||||
|
||||
std::list<int> data2(listsort<std::list<int> >(data1.begin(), data1.end()));
|
||||
|
||||
radixSort(data1.begin(), data1.end());
|
||||
|
||||
check(isTheSame(data1,data2), "Test failed");
|
||||
|
||||
|
||||
// radixSort(data2.begin(), data2.end(), Negate());
|
||||
// check(isTheSame(data1,data2), "Test failed");
|
||||
// for (int i = 0; i < n; ++i) {
|
||||
// check(data1[i] == data2[n - 1 - i], "Test failed");
|
||||
// }
|
||||
|
||||
// radixSort(data2.begin(), data2.end(), negate);
|
||||
// for (int i = 0; i < n; ++i) {
|
||||
// check(data1[i] == data2[n - 1 - i], "Test failed");
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
std::list<unsigned char> data1(n);
|
||||
generateCharSequence(n, data1);
|
||||
|
||||
std::list<unsigned char> data2(listsort<std::list<unsigned char> >
|
||||
(data1.begin(),
|
||||
data1.end()));
|
||||
|
||||
radixSort(data1.begin(), data1.end());
|
||||
check(isTheSame(data1,data2), "Test failed");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void checkStableRadixSort() {
|
||||
{
|
||||
std::vector<int> data1;
|
||||
generateIntSequence(n, data1);
|
||||
|
||||
std::vector<int> data2(data1);
|
||||
std::sort(data1.begin(), data1.end());
|
||||
|
||||
stableRadixSort(data2.begin(), data2.end());
|
||||
for (int i = 0; i < n; ++i) {
|
||||
check(data1[i] == data2[i], "Test failed");
|
||||
}
|
||||
|
||||
stableRadixSort(data2.begin(), data2.end(), Negate());
|
||||
for (int i = 0; i < n; ++i) {
|
||||
check(data1[i] == data2[n - 1 - i], "Test failed");
|
||||
}
|
||||
|
||||
stableRadixSort(data2.begin(), data2.end(), negate);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
check(data1[i] == data2[n - 1 - i], "Test failed");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<unsigned char> data1(n);
|
||||
generateCharSequence(n, data1);
|
||||
|
||||
std::vector<unsigned char> data2(data1);
|
||||
std::sort(data1.begin(), data1.end());
|
||||
|
||||
radixSort(data2.begin(), data2.end());
|
||||
for (int i = 0; i < n; ++i) {
|
||||
check(data1[i] == data2[i], "Test failed");
|
||||
}
|
||||
|
||||
}
|
||||
{
|
||||
std::list<int> data1;
|
||||
generateIntSequence(n, data1);
|
||||
|
||||
std::list<int> data2(listsort<std::list<int> >(data1.begin(),
|
||||
data1.end()));
|
||||
stableRadixSort(data1.begin(), data1.end());
|
||||
check(isTheSame(data1,data2), "Test failed");
|
||||
|
||||
// stableRadixSort(data2.begin(), data2.end(), Negate());
|
||||
// for (int i = 0; i < n; ++i) {
|
||||
// check(data1[i] == data2[n - 1 - i], "Test failed");
|
||||
// }
|
||||
|
||||
// stableRadixSort(data2.begin(), data2.end(), negate);
|
||||
// for (int i = 0; i < n; ++i) {
|
||||
// check(data1[i] == data2[n - 1 - i], "Test failed");
|
||||
// }
|
||||
}
|
||||
|
||||
{
|
||||
std::list<unsigned char> data1(n);
|
||||
generateCharSequence(n, data1);
|
||||
|
||||
std::list<unsigned char> data2(listsort<std::list<unsigned char> >
|
||||
(data1.begin(),
|
||||
data1.end()));
|
||||
radixSort(data1.begin(), data1.end());
|
||||
check(isTheSame(data1,data2), "Test failed");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
checkRadixSort();
|
||||
checkStableRadixSort();
|
||||
|
||||
return 0;
|
||||
}
|
||||
40
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/random_test.cc
vendored
Normal file
40
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/random_test.cc
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/random.h>
|
||||
#include "test_tools.h"
|
||||
|
||||
int seed_array[] = {1, 2};
|
||||
|
||||
int main()
|
||||
{
|
||||
double a=lemon::rnd();
|
||||
check(a<1.0&&a>0.0,"This should be in [0,1)");
|
||||
a=lemon::rnd.gauss();
|
||||
a=lemon::rnd.gamma(3.45,0);
|
||||
a=lemon::rnd.gamma(4);
|
||||
//Does gamma work with integer k?
|
||||
a=lemon::rnd.gamma(4.0,0);
|
||||
a=lemon::rnd.poisson(.5);
|
||||
|
||||
lemon::rnd.seed(100);
|
||||
lemon::rnd.seed(seed_array, seed_array +
|
||||
(sizeof(seed_array) / sizeof(seed_array[0])));
|
||||
|
||||
return 0;
|
||||
}
|
||||
267
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/suurballe_test.cc
vendored
Normal file
267
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/suurballe_test.cc
vendored
Normal file
@@ -0,0 +1,267 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <lemon/list_graph.h>
|
||||
#include <lemon/lgf_reader.h>
|
||||
#include <lemon/path.h>
|
||||
#include <lemon/suurballe.h>
|
||||
#include <lemon/concepts/digraph.h>
|
||||
#include <lemon/concepts/heap.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
char test_lgf[] =
|
||||
"@nodes\n"
|
||||
"label\n"
|
||||
"1\n"
|
||||
"2\n"
|
||||
"3\n"
|
||||
"4\n"
|
||||
"5\n"
|
||||
"6\n"
|
||||
"7\n"
|
||||
"8\n"
|
||||
"9\n"
|
||||
"10\n"
|
||||
"11\n"
|
||||
"12\n"
|
||||
"@arcs\n"
|
||||
" length\n"
|
||||
" 1 2 70\n"
|
||||
" 1 3 150\n"
|
||||
" 1 4 80\n"
|
||||
" 2 8 80\n"
|
||||
" 3 5 140\n"
|
||||
" 4 6 60\n"
|
||||
" 4 7 80\n"
|
||||
" 4 8 110\n"
|
||||
" 5 7 60\n"
|
||||
" 5 11 120\n"
|
||||
" 6 3 0\n"
|
||||
" 6 9 140\n"
|
||||
" 6 10 90\n"
|
||||
" 7 1 30\n"
|
||||
" 8 12 60\n"
|
||||
" 9 12 50\n"
|
||||
"10 12 70\n"
|
||||
"10 2 100\n"
|
||||
"10 7 60\n"
|
||||
"11 10 20\n"
|
||||
"12 11 30\n"
|
||||
"@attributes\n"
|
||||
"source 1\n"
|
||||
"target 12\n"
|
||||
"@end\n";
|
||||
|
||||
// Check the interface of Suurballe
|
||||
void checkSuurballeCompile()
|
||||
{
|
||||
typedef int VType;
|
||||
typedef concepts::Digraph Digraph;
|
||||
|
||||
typedef Digraph::Node Node;
|
||||
typedef Digraph::Arc Arc;
|
||||
typedef concepts::ReadMap<Arc, VType> LengthMap;
|
||||
|
||||
typedef Suurballe<Digraph, LengthMap> ST;
|
||||
typedef Suurballe<Digraph, LengthMap>
|
||||
::SetFlowMap<ST::FlowMap>
|
||||
::SetPotentialMap<ST::PotentialMap>
|
||||
::SetPath<SimplePath<Digraph> >
|
||||
::SetHeap<concepts::Heap<VType, Digraph::NodeMap<int> > >
|
||||
::Create SuurballeType;
|
||||
|
||||
Digraph g;
|
||||
Node n;
|
||||
Arc e;
|
||||
LengthMap len;
|
||||
SuurballeType::FlowMap flow(g);
|
||||
SuurballeType::PotentialMap pi(g);
|
||||
|
||||
SuurballeType suurb_test(g, len);
|
||||
const SuurballeType& const_suurb_test = suurb_test;
|
||||
|
||||
suurb_test
|
||||
.flowMap(flow)
|
||||
.potentialMap(pi);
|
||||
|
||||
int k;
|
||||
k = suurb_test.run(n, n);
|
||||
k = suurb_test.run(n, n, k);
|
||||
suurb_test.init(n);
|
||||
suurb_test.fullInit(n);
|
||||
suurb_test.start(n);
|
||||
suurb_test.start(n, k);
|
||||
k = suurb_test.findFlow(n);
|
||||
k = suurb_test.findFlow(n, k);
|
||||
suurb_test.findPaths();
|
||||
|
||||
int f;
|
||||
VType c;
|
||||
::lemon::ignore_unused_variable_warning(f,c);
|
||||
|
||||
c = const_suurb_test.totalLength();
|
||||
f = const_suurb_test.flow(e);
|
||||
const SuurballeType::FlowMap& fm =
|
||||
const_suurb_test.flowMap();
|
||||
c = const_suurb_test.potential(n);
|
||||
const SuurballeType::PotentialMap& pm =
|
||||
const_suurb_test.potentialMap();
|
||||
k = const_suurb_test.pathNum();
|
||||
Path<Digraph> p = const_suurb_test.path(k);
|
||||
|
||||
::lemon::ignore_unused_variable_warning(fm);
|
||||
::lemon::ignore_unused_variable_warning(pm);
|
||||
}
|
||||
|
||||
// Check the feasibility of the flow
|
||||
template <typename Digraph, typename FlowMap>
|
||||
bool checkFlow( const Digraph& gr, const FlowMap& flow,
|
||||
typename Digraph::Node s, typename Digraph::Node t,
|
||||
int value )
|
||||
{
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
for (ArcIt e(gr); e != INVALID; ++e)
|
||||
if (!(flow[e] == 0 || flow[e] == 1)) return false;
|
||||
|
||||
for (NodeIt n(gr); n != INVALID; ++n) {
|
||||
int sum = 0;
|
||||
for (OutArcIt e(gr, n); e != INVALID; ++e)
|
||||
sum += flow[e];
|
||||
for (InArcIt e(gr, n); e != INVALID; ++e)
|
||||
sum -= flow[e];
|
||||
if (n == s && sum != value) return false;
|
||||
if (n == t && sum != -value) return false;
|
||||
if (n != s && n != t && sum != 0) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check the optimalitiy of the flow
|
||||
template < typename Digraph, typename CostMap,
|
||||
typename FlowMap, typename PotentialMap >
|
||||
bool checkOptimality( const Digraph& gr, const CostMap& cost,
|
||||
const FlowMap& flow, const PotentialMap& pi )
|
||||
{
|
||||
// Check the "Complementary Slackness" optimality condition
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
bool opt = true;
|
||||
for (ArcIt e(gr); e != INVALID; ++e) {
|
||||
typename CostMap::Value red_cost =
|
||||
cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
|
||||
opt = (flow[e] == 0 && red_cost >= 0) ||
|
||||
(flow[e] == 1 && red_cost <= 0);
|
||||
if (!opt) break;
|
||||
}
|
||||
return opt;
|
||||
}
|
||||
|
||||
// Check a path
|
||||
template <typename Digraph, typename Path>
|
||||
bool checkPath( const Digraph& gr, const Path& path,
|
||||
typename Digraph::Node s, typename Digraph::Node t)
|
||||
{
|
||||
TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
|
||||
Node n = s;
|
||||
for (int i = 0; i < path.length(); ++i) {
|
||||
if (gr.source(path.nth(i)) != n) return false;
|
||||
n = gr.target(path.nth(i));
|
||||
}
|
||||
return n == t;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
DIGRAPH_TYPEDEFS(ListDigraph);
|
||||
|
||||
// Read the test digraph
|
||||
ListDigraph digraph;
|
||||
ListDigraph::ArcMap<int> length(digraph);
|
||||
Node s, t;
|
||||
|
||||
std::istringstream input(test_lgf);
|
||||
DigraphReader<ListDigraph>(digraph, input).
|
||||
arcMap("length", length).
|
||||
node("source", s).
|
||||
node("target", t).
|
||||
run();
|
||||
|
||||
// Check run()
|
||||
{
|
||||
Suurballe<ListDigraph> suurballe(digraph, length);
|
||||
|
||||
// Find 2 paths
|
||||
check(suurballe.run(s, t) == 2, "Wrong number of paths");
|
||||
check(checkFlow(digraph, suurballe.flowMap(), s, t, 2),
|
||||
"The flow is not feasible");
|
||||
check(suurballe.totalLength() == 510, "The flow is not optimal");
|
||||
check(checkOptimality(digraph, length, suurballe.flowMap(),
|
||||
suurballe.potentialMap()),
|
||||
"Wrong potentials");
|
||||
for (int i = 0; i < suurballe.pathNum(); ++i)
|
||||
check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
|
||||
|
||||
// Find 3 paths
|
||||
check(suurballe.run(s, t, 3) == 3, "Wrong number of paths");
|
||||
check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
|
||||
"The flow is not feasible");
|
||||
check(suurballe.totalLength() == 1040, "The flow is not optimal");
|
||||
check(checkOptimality(digraph, length, suurballe.flowMap(),
|
||||
suurballe.potentialMap()),
|
||||
"Wrong potentials");
|
||||
for (int i = 0; i < suurballe.pathNum(); ++i)
|
||||
check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
|
||||
|
||||
// Find 5 paths (only 3 can be found)
|
||||
check(suurballe.run(s, t, 5) == 3, "Wrong number of paths");
|
||||
check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
|
||||
"The flow is not feasible");
|
||||
check(suurballe.totalLength() == 1040, "The flow is not optimal");
|
||||
check(checkOptimality(digraph, length, suurballe.flowMap(),
|
||||
suurballe.potentialMap()),
|
||||
"Wrong potentials");
|
||||
for (int i = 0; i < suurballe.pathNum(); ++i)
|
||||
check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
|
||||
}
|
||||
|
||||
// Check fullInit() + start()
|
||||
{
|
||||
Suurballe<ListDigraph> suurballe(digraph, length);
|
||||
suurballe.fullInit(s);
|
||||
|
||||
// Find 2 paths
|
||||
check(suurballe.start(t) == 2, "Wrong number of paths");
|
||||
check(suurballe.totalLength() == 510, "The flow is not optimal");
|
||||
|
||||
// Find 3 paths
|
||||
check(suurballe.start(t, 3) == 3, "Wrong number of paths");
|
||||
check(suurballe.totalLength() == 1040, "The flow is not optimal");
|
||||
|
||||
// Find 5 paths (only 3 can be found)
|
||||
check(suurballe.start(t, 5) == 3, "Wrong number of paths");
|
||||
check(suurballe.totalLength() == 1040, "The flow is not optimal");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
50
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/test_tools.h
vendored
Normal file
50
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/test_tools.h
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2010
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LEMON_TEST_TEST_TOOLS_H
|
||||
#define LEMON_TEST_TEST_TOOLS_H
|
||||
|
||||
///\ingroup misc
|
||||
///\file
|
||||
///\brief Some utilities to write test programs.
|
||||
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
|
||||
///If \c rc is fail, writes an error message and exits.
|
||||
|
||||
///If \c rc is fail, writes an error message and exits.
|
||||
///The error message contains the file name and the line number of the
|
||||
///source code in a standard from, which makes it possible to go there
|
||||
///using good source browsers like e.g. \c emacs.
|
||||
///
|
||||
///For example
|
||||
///\code check(0==1,"This is obviously false.");\endcode will
|
||||
///print something like this (and then exits).
|
||||
///\verbatim file_name.cc:123: error: This is obviously false. \endverbatim
|
||||
#define check(rc, msg) \
|
||||
{ \
|
||||
if(!(rc)) { \
|
||||
std::cerr << __FILE__ ":" << __LINE__ << ": error: " \
|
||||
<< msg << std::endl; \
|
||||
abort(); \
|
||||
} else { } \
|
||||
} \
|
||||
|
||||
|
||||
#endif
|
||||
25
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/test_tools_fail.cc
vendored
Normal file
25
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/test_tools_fail.cc
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
check(false, "Don't panic. Failing is the right behaviour here.");
|
||||
return 0;
|
||||
}
|
||||
25
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/test_tools_pass.cc
vendored
Normal file
25
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/test_tools_pass.cc
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
check(true, "It should pass.");
|
||||
return 0;
|
||||
}
|
||||
60
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/time_measure_test.cc
vendored
Normal file
60
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/time_measure_test.cc
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/time_measure.h>
|
||||
#include <lemon/concept_check.h>
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
void f()
|
||||
{
|
||||
double d=0;
|
||||
for(int i=0;i<1000;i++)
|
||||
d+=0.1;
|
||||
}
|
||||
|
||||
void g()
|
||||
{
|
||||
static Timer T;
|
||||
|
||||
for(int i=0;i<1000;i++)
|
||||
{
|
||||
TimeStamp x(T);
|
||||
::lemon::ignore_unused_variable_warning(x);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Timer T;
|
||||
unsigned int n;
|
||||
for(n=0;T.realTime()<0.1;n++) ;
|
||||
std::cout << T << " (" << n << " time queries)\n";
|
||||
|
||||
TimeStamp full;
|
||||
TimeStamp t;
|
||||
t=runningTimeTest(f,0.1,&n,&full);
|
||||
std::cout << t << " (" << n << " tests)\n";
|
||||
std::cout << "Total: " << full << "\n";
|
||||
|
||||
t=runningTimeTest(g,0.1,&n,&full);
|
||||
std::cout << t << " (" << n << " tests)\n";
|
||||
std::cout << "Total: " << full << "\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
287
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/tsp_test.cc
vendored
Normal file
287
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/tsp_test.cc
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2013
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <lemon/full_graph.h>
|
||||
#include <lemon/math.h>
|
||||
#include <lemon/maps.h>
|
||||
#include <lemon/random.h>
|
||||
#include <lemon/dim2.h>
|
||||
|
||||
#include <lemon/nearest_neighbor_tsp.h>
|
||||
#include <lemon/greedy_tsp.h>
|
||||
#include <lemon/insertion_tsp.h>
|
||||
#include <lemon/christofides_tsp.h>
|
||||
#include <lemon/opt2_tsp.h>
|
||||
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
|
||||
// // Tests checkMetricCost() function
|
||||
// void metricCostTest() {
|
||||
// GRAPH_TYPEDEFS(FullGraph);
|
||||
// FullGraph g(10);
|
||||
// check(checkMetricCost(g, constMap<Edge>(0)), "Wrong checkMetricCost()");
|
||||
// check(checkMetricCost(g, constMap<Edge>(1)), "Wrong checkMetricCost()");
|
||||
// check(!checkMetricCost(g, constMap<Edge>(-1)), "Wrong checkMetricCost()");
|
||||
//
|
||||
// FullGraph::EdgeMap<float> cost(g);
|
||||
// for (NodeIt u(g); u != INVALID; ++u) {
|
||||
// for (NodeIt v(g); v != INVALID; ++v) {
|
||||
// if (u == v) continue;
|
||||
// float x1 = g.id(u), x2 = g.id(v);
|
||||
// float y1 = x1 * x1, y2 = x2 * x2;
|
||||
// cost[g.edge(u, v)] = std::sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
|
||||
// }
|
||||
// }
|
||||
// check(checkMetricCost(g, cost), "Wrong checkMetricCost()");
|
||||
// float eps = Tolerance<float>::defaultEpsilon();
|
||||
// cost[g.edge(g(0), g(9))] =
|
||||
// cost[g.edge(g(0), g(8))] + cost[g.edge(g(8), g(9))] + eps * 2;
|
||||
// check(!checkMetricCost(g, cost), "Wrong checkMetricCost()");
|
||||
// check(checkMetricCost(g, cost, Tolerance<float>(eps * 4)),
|
||||
// "Wrong checkMetricCost()");
|
||||
// }
|
||||
|
||||
// Checks tour validity
|
||||
template <typename Container>
|
||||
bool checkTour(const FullGraph &gr, const Container &p) {
|
||||
FullGraph::NodeMap<bool> used(gr, false);
|
||||
|
||||
int node_cnt = 0;
|
||||
for (typename Container::const_iterator it = p.begin(); it != p.end(); ++it)
|
||||
{
|
||||
FullGraph::Node node = *it;
|
||||
if (used[node]) return false;
|
||||
used[node] = true;
|
||||
++node_cnt;
|
||||
}
|
||||
|
||||
return (node_cnt == gr.nodeNum());
|
||||
}
|
||||
|
||||
// Checks tour validity
|
||||
bool checkTourPath(const FullGraph &gr, const Path<FullGraph> &p) {
|
||||
FullGraph::NodeMap<bool> used(gr, false);
|
||||
|
||||
if (!checkPath(gr, p)) return false;
|
||||
if (gr.nodeNum() <= 1 && p.length() != 0) return false;
|
||||
if (gr.nodeNum() > 1 && p.length() != gr.nodeNum()) return false;
|
||||
|
||||
for (int i = 0; i < p.length(); ++i) {
|
||||
if (used[gr.target(p.nth(i))]) return false;
|
||||
used[gr.target(p.nth(i))] = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Checks tour cost
|
||||
template <typename CostMap>
|
||||
bool checkCost(const FullGraph &gr, const std::vector<FullGraph::Node> &p,
|
||||
const CostMap &cost, typename CostMap::Value total)
|
||||
{
|
||||
typedef typename CostMap::Value Cost;
|
||||
|
||||
Cost s = 0;
|
||||
for (int i = 0; i < int(p.size()) - 1; ++i)
|
||||
s += cost[gr.edge(p[i], p[i+1])];
|
||||
if (int(p.size()) >= 2)
|
||||
s += cost[gr.edge(p.back(), p.front())];
|
||||
|
||||
return !Tolerance<Cost>().different(s, total);
|
||||
}
|
||||
|
||||
// Checks tour cost
|
||||
template <typename CostMap>
|
||||
bool checkCost(const FullGraph &, const Path<FullGraph> &p,
|
||||
const CostMap &cost, typename CostMap::Value total)
|
||||
{
|
||||
typedef typename CostMap::Value Cost;
|
||||
|
||||
Cost s = 0;
|
||||
for (int i = 0; i < p.length(); ++i)
|
||||
s += cost[p.nth(i)];
|
||||
|
||||
return !Tolerance<Cost>().different(s, total);
|
||||
}
|
||||
|
||||
// Tests a TSP algorithm on small graphs
|
||||
template <typename TSP>
|
||||
void tspTestSmall(const std::string &alg_name) {
|
||||
GRAPH_TYPEDEFS(FullGraph);
|
||||
|
||||
for (int n = 0; n <= 5; ++n) {
|
||||
FullGraph g(n);
|
||||
unsigned nsize = n;
|
||||
int esize = n <= 1 ? 0 : n;
|
||||
|
||||
ConstMap<Edge, int> cost_map(1);
|
||||
TSP alg(g, cost_map);
|
||||
|
||||
check(alg.run() == esize, alg_name + ": Wrong total cost");
|
||||
check(alg.tourCost() == esize, alg_name + ": Wrong total cost");
|
||||
|
||||
std::list<Node> list1(nsize), list2;
|
||||
std::vector<Node> vec1(nsize), vec2;
|
||||
alg.tourNodes(list1.begin());
|
||||
alg.tourNodes(vec1.begin());
|
||||
alg.tourNodes(std::front_inserter(list2));
|
||||
alg.tourNodes(std::back_inserter(vec2));
|
||||
check(checkTour(g, alg.tourNodes()), alg_name + ": Wrong node sequence");
|
||||
check(checkTour(g, list1), alg_name + ": Wrong node sequence");
|
||||
check(checkTour(g, vec1), alg_name + ": Wrong node sequence");
|
||||
check(checkTour(g, list2), alg_name + ": Wrong node sequence");
|
||||
check(checkTour(g, vec2), alg_name + ": Wrong node sequence");
|
||||
check(checkCost(g, vec1, constMap<Edge, int>(1), esize),
|
||||
alg_name + ": Wrong tour cost");
|
||||
|
||||
SimplePath<FullGraph> path;
|
||||
alg.tour(path);
|
||||
check(path.length() == esize, alg_name + ": Wrong tour");
|
||||
check(checkTourPath(g, path), alg_name + ": Wrong tour");
|
||||
check(checkCost(g, path, constMap<Edge, int>(1), esize),
|
||||
alg_name + ": Wrong tour cost");
|
||||
}
|
||||
}
|
||||
|
||||
// Tests a TSP algorithm on random graphs
|
||||
template <typename TSP>
|
||||
void tspTestRandom(const std::string &alg_name) {
|
||||
GRAPH_TYPEDEFS(FullGraph);
|
||||
|
||||
FullGraph g(20);
|
||||
FullGraph::NodeMap<dim2::Point<double> > pos(g);
|
||||
DoubleEdgeMap cost(g);
|
||||
|
||||
TSP alg(g, cost);
|
||||
Opt2Tsp<DoubleEdgeMap > opt2(g, cost);
|
||||
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
for (NodeIt u(g); u != INVALID; ++u) {
|
||||
pos[u] = dim2::Point<double>(rnd(), rnd());
|
||||
}
|
||||
for (NodeIt u(g); u != INVALID; ++u) {
|
||||
for (NodeIt v(g); v != INVALID; ++v) {
|
||||
if (u == v) continue;
|
||||
cost[g.edge(u, v)] = (pos[u] - pos[v]).normSquare();
|
||||
}
|
||||
}
|
||||
|
||||
check(alg.run() > 0, alg_name + ": Wrong total cost");
|
||||
|
||||
std::vector<Node> vec;
|
||||
alg.tourNodes(std::back_inserter(vec));
|
||||
check(checkTour(g, vec), alg_name + ": Wrong node sequence");
|
||||
check(checkCost(g, vec, cost, alg.tourCost()),
|
||||
alg_name + ": Wrong tour cost");
|
||||
|
||||
SimplePath<FullGraph> path;
|
||||
alg.tour(path);
|
||||
check(checkTourPath(g, path), alg_name + ": Wrong tour");
|
||||
check(checkCost(g, path, cost, alg.tourCost()),
|
||||
alg_name + ": Wrong tour cost");
|
||||
|
||||
check(!Tolerance<double>().less(alg.tourCost(), opt2.run(alg.tourNodes())),
|
||||
"2-opt improvement: Wrong total cost");
|
||||
check(checkTour(g, opt2.tourNodes()),
|
||||
"2-opt improvement: Wrong node sequence");
|
||||
check(checkCost(g, opt2.tourNodes(), cost, opt2.tourCost()),
|
||||
"2-opt improvement: Wrong tour cost");
|
||||
|
||||
check(!Tolerance<double>().less(alg.tourCost(), opt2.run(path)),
|
||||
"2-opt improvement: Wrong total cost");
|
||||
check(checkTour(g, opt2.tourNodes()),
|
||||
"2-opt improvement: Wrong node sequence");
|
||||
check(checkCost(g, opt2.tourNodes(), cost, opt2.tourCost()),
|
||||
"2-opt improvement: Wrong tour cost");
|
||||
}
|
||||
}
|
||||
|
||||
// Algorithm class for Nearest Insertion
|
||||
template <typename CM>
|
||||
class NearestInsertionTsp : public InsertionTsp<CM> {
|
||||
public:
|
||||
NearestInsertionTsp(const FullGraph &gr, const CM &cost)
|
||||
: InsertionTsp<CM>(gr, cost) {}
|
||||
typename CM::Value run() {
|
||||
return InsertionTsp<CM>::run(InsertionTsp<CM>::NEAREST);
|
||||
}
|
||||
};
|
||||
|
||||
// Algorithm class for Farthest Insertion
|
||||
template <typename CM>
|
||||
class FarthestInsertionTsp : public InsertionTsp<CM> {
|
||||
public:
|
||||
FarthestInsertionTsp(const FullGraph &gr, const CM &cost)
|
||||
: InsertionTsp<CM>(gr, cost) {}
|
||||
typename CM::Value run() {
|
||||
return InsertionTsp<CM>::run(InsertionTsp<CM>::FARTHEST);
|
||||
}
|
||||
};
|
||||
|
||||
// Algorithm class for Cheapest Insertion
|
||||
template <typename CM>
|
||||
class CheapestInsertionTsp : public InsertionTsp<CM> {
|
||||
public:
|
||||
CheapestInsertionTsp(const FullGraph &gr, const CM &cost)
|
||||
: InsertionTsp<CM>(gr, cost) {}
|
||||
typename CM::Value run() {
|
||||
return InsertionTsp<CM>::run(InsertionTsp<CM>::CHEAPEST);
|
||||
}
|
||||
};
|
||||
|
||||
// Algorithm class for Random Insertion
|
||||
template <typename CM>
|
||||
class RandomInsertionTsp : public InsertionTsp<CM> {
|
||||
public:
|
||||
RandomInsertionTsp(const FullGraph &gr, const CM &cost)
|
||||
: InsertionTsp<CM>(gr, cost) {}
|
||||
typename CM::Value run() {
|
||||
return InsertionTsp<CM>::run(InsertionTsp<CM>::RANDOM);
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
GRAPH_TYPEDEFS(FullGraph);
|
||||
|
||||
// metricCostTest();
|
||||
|
||||
tspTestSmall<NearestNeighborTsp<ConstMap<Edge, int> > >("Nearest Neighbor");
|
||||
tspTestSmall<GreedyTsp<ConstMap<Edge, int> > >("Greedy");
|
||||
tspTestSmall<NearestInsertionTsp<ConstMap<Edge, int> > >("Nearest Insertion");
|
||||
tspTestSmall<FarthestInsertionTsp<ConstMap<Edge, int> > >
|
||||
("Farthest Insertion");
|
||||
tspTestSmall<CheapestInsertionTsp<ConstMap<Edge, int> > >
|
||||
("Cheapest Insertion");
|
||||
tspTestSmall<RandomInsertionTsp<ConstMap<Edge, int> > >("Random Insertion");
|
||||
tspTestSmall<ChristofidesTsp<ConstMap<Edge, int> > >("Christofides");
|
||||
tspTestSmall<Opt2Tsp<ConstMap<Edge, int> > >("2-opt");
|
||||
|
||||
tspTestRandom<NearestNeighborTsp<DoubleEdgeMap > >("Nearest Neighbor");
|
||||
tspTestRandom<GreedyTsp<DoubleEdgeMap > >("Greedy");
|
||||
tspTestRandom<NearestInsertionTsp<DoubleEdgeMap > >("Nearest Insertion");
|
||||
tspTestRandom<FarthestInsertionTsp<DoubleEdgeMap > >("Farthest Insertion");
|
||||
tspTestRandom<CheapestInsertionTsp<DoubleEdgeMap > >("Cheapest Insertion");
|
||||
tspTestRandom<RandomInsertionTsp<DoubleEdgeMap > >("Random Insertion");
|
||||
tspTestRandom<ChristofidesTsp<DoubleEdgeMap > >("Christofides");
|
||||
tspTestRandom<Opt2Tsp<DoubleEdgeMap > >("2-opt");
|
||||
|
||||
return 0;
|
||||
}
|
||||
102
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/unionfind_test.cc
vendored
Normal file
102
blender-5.2.0/extern/quadriflow/3rd/lemon-1.3.1/test/unionfind_test.cc
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
/* -*- mode: C++; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* This file is a part of LEMON, a generic C++ optimization library.
|
||||
*
|
||||
* Copyright (C) 2003-2009
|
||||
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
||||
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
||||
*
|
||||
* Permission to use, modify and distribute this software is granted
|
||||
* provided that this copyright notice appears in all copies. For
|
||||
* precise terms see the accompanying LICENSE file.
|
||||
*
|
||||
* This software is provided "AS IS" with no warranty of any kind,
|
||||
* express or implied, and with no claim as to its suitability for any
|
||||
* purpose.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <lemon/list_graph.h>
|
||||
#include <lemon/maps.h>
|
||||
#include <lemon/unionfind.h>
|
||||
#include "test_tools.h"
|
||||
|
||||
using namespace lemon;
|
||||
using namespace std;
|
||||
|
||||
typedef UnionFindEnum<ListGraph::NodeMap<int> > UFE;
|
||||
|
||||
int main() {
|
||||
ListGraph g;
|
||||
ListGraph::NodeMap<int> base(g);
|
||||
UFE U(base);
|
||||
vector<ListGraph::Node> n;
|
||||
|
||||
for(int i=0;i<20;i++) n.push_back(g.addNode());
|
||||
|
||||
U.insert(n[1]);
|
||||
U.insert(n[2]);
|
||||
|
||||
check(U.join(n[1],n[2]) != -1, "Something is wrong with UnionFindEnum");
|
||||
|
||||
U.insert(n[3]);
|
||||
U.insert(n[4]);
|
||||
U.insert(n[5]);
|
||||
U.insert(n[6]);
|
||||
U.insert(n[7]);
|
||||
|
||||
|
||||
check(U.join(n[1],n[4]) != -1, "Something is wrong with UnionFindEnum");
|
||||
check(U.join(n[2],n[4]) == -1, "Something is wrong with UnionFindEnum");
|
||||
check(U.join(n[3],n[5]) != -1, "Something is wrong with UnionFindEnum");
|
||||
|
||||
|
||||
U.insert(n[8],U.find(n[5]));
|
||||
|
||||
|
||||
check(U.size(U.find(n[4])) == 3, "Something is wrong with UnionFindEnum");
|
||||
check(U.size(U.find(n[5])) == 3, "Something is wrong with UnionFindEnum");
|
||||
check(U.size(U.find(n[6])) == 1, "Something is wrong with UnionFindEnum");
|
||||
check(U.size(U.find(n[2])) == 3, "Something is wrong with UnionFindEnum");
|
||||
|
||||
|
||||
U.insert(n[9]);
|
||||
U.insert(n[10],U.find(n[9]));
|
||||
|
||||
|
||||
check(U.join(n[8],n[10]) != -1, "Something is wrong with UnionFindEnum");
|
||||
|
||||
|
||||
check(U.size(U.find(n[4])) == 3, "Something is wrong with UnionFindEnum");
|
||||
check(U.size(U.find(n[9])) == 5, "Something is wrong with UnionFindEnum");
|
||||
|
||||
check(U.size(U.find(n[8])) == 5, "Something is wrong with UnionFindEnum");
|
||||
|
||||
U.erase(n[9]);
|
||||
U.erase(n[1]);
|
||||
|
||||
check(U.size(U.find(n[10])) == 4, "Something is wrong with UnionFindEnum");
|
||||
check(U.size(U.find(n[2])) == 2, "Something is wrong with UnionFindEnum");
|
||||
|
||||
U.erase(n[6]);
|
||||
U.split(U.find(n[8]));
|
||||
|
||||
|
||||
check(U.size(U.find(n[4])) == 2, "Something is wrong with UnionFindEnum");
|
||||
check(U.size(U.find(n[3])) == 1, "Something is wrong with UnionFindEnum");
|
||||
check(U.size(U.find(n[2])) == 2, "Something is wrong with UnionFindEnum");
|
||||
|
||||
|
||||
check(U.join(n[3],n[4]) != -1, "Something is wrong with UnionFindEnum");
|
||||
check(U.join(n[2],n[4]) == -1, "Something is wrong with UnionFindEnum");
|
||||
|
||||
|
||||
check(U.size(U.find(n[4])) == 3, "Something is wrong with UnionFindEnum");
|
||||
check(U.size(U.find(n[3])) == 3, "Something is wrong with UnionFindEnum");
|
||||
check(U.size(U.find(n[2])) == 3, "Something is wrong with UnionFindEnum");
|
||||
|
||||
U.eraseClass(U.find(n[4]));
|
||||
U.eraseClass(U.find(n[7]));
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user