64 explicit VecIntPy(
int a_size = 0,
int a_value = 0)
65 :
m_vec(a_size, a_value)
71 VecIntPy(
const VecInt& a_vec)
78 VecIntPy(
const VecIntPy& a_vec)
85 const VecIntPy& operator=(
const VecIntPy& a_rhs)
95 int& operator[](
int a_idx)
99 a_idx = (int)
m_vec.size() + a_idx;
109 int operator[](
int a_idx)
const 113 a_idx = (int)
m_vec.size() + a_idx;
125 int size()
const {
return (
int)
m_vec.size(); }
129 bool empty()
const {
return m_vec.empty(); }
134 int index(
int a_value)
136 auto it = std::find(
m_vec.begin(),
m_vec.end(), a_value);
138 return (
int)(it -
m_vec.begin());
145 auto it = std::min_element(
m_vec.begin(),
m_vec.end());
155 int min(
int a_start,
int a_end)
const 157 auto it = std::min_element(
m_vec.begin() + a_start,
m_vec.begin() + a_end);
168 auto it = std::max_element(
m_vec.begin(),
m_vec.end());
178 int max(
int a_start,
int a_end)
const 180 auto it = std::max_element(
m_vec.begin() + a_start,
m_vec.begin() + a_end);
189 void push_back(
int a_value) {
m_vec.push_back(a_value); }
205 int back =
m_vec.back();
212 void append(
const VecIntPy& a_vec)
214 m_vec.insert(
m_vec.end(), a_vec.m_vec.begin(), a_vec.m_vec.end());
218 void clear() {
m_vec.clear(); }
225 void resize(
int a_size,
int a_default) {
m_vec.resize(a_size, a_default); }
229 void reserve(
int a_size) {
m_vec.reserve(a_size); }
235 void resize_to_count(
int a_size,
int a_start_at = 0)
237 m_vec.resize(a_size);
238 std::iota(
m_vec.begin(),
m_vec.end(), a_start_at);
242 void reverse() { std::reverse(
m_vec.begin(),
m_vec.end()); }
246 void rotate(
int a_frontIdx)
266 explicit VecInt2dPy(
int a_size = 0, VecIntPy a_value = VecIntPy())
267 :
m_vec(a_size, a_value)
273 VecInt2dPy(
const VecInt2dPy& a_vec)
283 for (
auto& vec : a_vec)
285 m_vec.push_back(VecIntPy(vec));
293 VecIntPy& operator[](
int a_idx)
297 a_idx = (int)
m_vec.size() + a_idx;
307 const VecIntPy& operator[](
int a_idx)
const 311 a_idx = (int)
m_vec.size() + a_idx;
319 void push_back(
const VecIntPy& a_value) {
m_vec.push_back(a_value); }
323 int size()
const {
return (
int)
m_vec.size(); }
327 bool empty()
const {
return m_vec.empty(); }
334 void resize(
int a_size,
const VecIntPy& a_vec = VecIntPy()) {
m_vec.resize(a_size, a_vec); }
337 std::vector<VecIntPy>
m_vec;
343 MeWeightMatcherImpl();
346 virtual VecInt MatchWeights(
const VecMeEdge& a_edges,
bool a_maxCardinality =
false)
override;
348 int slack(
int a_edge);
349 VecIntPy blossomLeaves(
int b);
350 void assignLabel(
int w,
int t,
int p);
351 int scanBlossom(
int v,
int w);
352 void addBlossom(
int base,
int k);
353 void expandBlossom(
int b,
bool endstage);
354 void augmentBlossom(
int b,
int v);
355 void augmentMatching(
int k);
356 void verifyOptimum(
bool maxcardinality);
361 const MeEdge& GetEdge(
int a_idx);
480 MeWeightMatcherImpl::MeWeightMatcherImpl()
487 void MeWeightMatcherImpl::Init(
const VecMeEdge& a_edges)
507 const int& i = edge.m_f0;
508 const int& j = edge.m_f1;
524 for (
int k = 0; k < (int)
m_edges.size(); ++k)
527 const int& i = edge.
m_f0;
528 const int& j = edge.
m_f1;
637 bool a_maxCardinality )
649 int BOGUS_SLACK = 0xdeadbeef;
658 printf(
"STAGE %d\n", t);
687 assignLabel(v, 1, -1);
691 bool augmented =
false;
701 printf(
"SUBSTAGE\n");
705 while (!
m_queue.empty() && !augmented)
710 printf(
"POP v=%d\n", v);
715 for (
int idx = 0; idx <
m_neighbEnd[v].size(); ++idx)
726 int kslack = BOGUS_SLACK;
727 bool valid_kslack =
false;
745 assignLabel(w, 2, p ^ 1);
752 int base = scanBlossom(v, w);
812 int deltaedge = NONE;
814 int deltablossom = NONE;
823 if (!a_maxCardinality)
831 int dslack = BOGUS_SLACK;
837 if (deltatype == -1 || dslack < delta)
855 if (deltatype == -1 || (dslack < delta))
868 (deltatype == -1 ||
m_dualVar[b] < delta))
919 printf(
"delta%d=%d\n", deltatype, delta);
926 else if (deltatype == 2)
930 auto& edge = GetEdge(deltaedge);
940 else if (deltatype == 3)
944 auto& edge = GetEdge(deltaedge);
949 else if (deltatype == 4)
952 expandBlossom(deltablossom,
false);
968 expandBlossom(b,
true);
975 verifyOptimum(a_maxCardinality);
997 int MeWeightMatcherImpl::slack(
int a_k)
1001 a_k = (int)
m_edges.size() + a_k;
1004 const MeEdge& edge = GetEdge(a_k);
1005 const int& i = edge.m_f0;
1006 const int& j = edge.m_f1;
1007 const int& wt = edge.m_weight;
1015 VecIntPy MeWeightMatcherImpl::blossomLeaves(
int a_b)
1020 results.push_back(a_b);
1026 printf(
"blossomLeaves(%d) - blossomchilds[b] = %s\n", a_b, TS_AS_STRING(results.ToVecInt()));
1032 VecIntPy newresults;
1033 for (
int idx = 0; idx < results.size(); ++idx)
1035 int elem = results[idx];
1038 newresults.push_back(elem);
1045 results = newresults;
1056 void MeWeightMatcherImpl::assignLabel(
int a_w,
int a_t,
int a_p)
1059 printf(
"assignLabel(%d,%d,%d)\n", a_w, a_t, a_p);
1069 VecIntPy bleaves = blossomLeaves(b);
1072 printf(
"PUSH %s\n", TS_AS_STRING(bleaves.ToVecInt()));
1081 int mateBase =
m_mate[base];
1083 assignLabel(
m_endPoint[mateBase], 1, mateBase ^ 1);
1093 int MeWeightMatcherImpl::scanBlossom(
int a_v,
int a_w)
1096 printf(
"scanBlossom(%d, %d)\n", a_v, a_w);
1101 while (a_v != -1 || a_w != -1)
1132 std::swap(a_v, a_w);
1136 for (
int idx = 0; idx < path.size(); ++idx)
1152 void MeWeightMatcherImpl::addBlossom(
int a_base,
int a_k)
1154 const MeEdge& edge = GetEdge(a_k);
1163 printf(
"addBlossom(%d,%d) (v=%d w=%d) -> %d\n", a_base, a_k, v, w, b);
1172 printf(
"blossomchilds[%d] cleared\n", b);
1194 endps.push_back(2 * a_k);
1217 VecIntPy bleaves = blossomLeaves(b);
1218 for (
int idx = 0; idx < bleaves.size(); ++idx)
1231 VecIntPy bestedgeto;
1233 for (
int idx = 0; idx < path.size(); ++idx)
1242 for (
int idx2 = 0; idx2 <
m_neighbEnd[v].size(); ++idx2)
1245 nblist.push_back(p / 2);
1247 nblists.resize(blossomLeaves(bv).size(), nblist);
1255 for (
int idx3 = 0; idx3 < nblists.size(); ++idx3)
1257 auto& nblist = nblists[idx3];
1258 for (
int idx4 = 0; idx4 < nblist.size(); ++idx4)
1260 int k = nblist[idx4];
1261 const MeEdge& edge = GetEdge(k);
1269 if (bj != b &&
m_label[bj] == 1 &&
1270 (bestedgeto[bj] == -1 || slack(k) < slack(bestedgeto[bj])))
1281 for (
int idx = 0; idx < bestedgeto.size(); ++idx)
1283 int k = bestedgeto[idx];
1292 for (
int idx = 0; idx < bk.size(); ++idx)
1301 printf(
"blossomchilds[%d]=%s\n", b, TS_AS_STRING(
m_blossomChildren[b].ToVecInt()));
1309 void MeWeightMatcherImpl::expandBlossom(
int a_b,
bool a_endStage)
1312 printf(
"expandBlossom(%d,%d) %s\n", a_b, a_endStage,
1324 else if (a_endStage &&
m_dualVar[s] == 0)
1327 expandBlossom(s, a_endStage);
1331 VecIntPy bleaves = blossomLeaves(s);
1332 for (
int idx2 = 0; idx2 < bleaves.size(); ++idx2)
1334 int v = bleaves[idx2];
1342 if (!a_endStage &&
m_label[a_b] == 2)
1401 VecIntPy bleaves = blossomLeaves(bv);
1404 for (
int idx2 = 0; idx2 < bleaves.size(); ++idx2)
1429 printf(
"clear blossomchilds[%d]\n", a_b);
1444 void MeWeightMatcherImpl::augmentBlossom(
int a_b,
int a_v)
1447 printf(
"augmentBlossom(%d,%d)\n", a_b, a_v);
1459 augmentBlossom(t, a_v);
1484 printf(
"augmentBlossom 1\n");
1494 printf(
"augmentBlossom 2\n");
1508 printf(
"rotate blossomchilds[%d]=%s\n", a_b, TS_AS_STRING(
m_blossomChildren[a_b].ToVecInt()));
1520 void MeWeightMatcherImpl::augmentMatching(
int a_k)
1522 const MeEdge& edge = GetEdge(a_k);
1526 printf(
"augmentMatching(%d) (v=%d w=%d)\n", a_k, v, w);
1527 printf(
"PAIR %d %d (k=%d)\n", v, w, a_k);
1529 VecInt2d vwkTemp = {{v, 2 * a_k + 1}, {w, 2 * a_k}};
1530 VecInt2dPy vwk(vwkTemp);
1531 for (
int idx = 0; idx < vwk.size(); ++idx)
1533 auto& sp = vwk[idx];
1549 augmentBlossom(bs, s);
1570 augmentBlossom(bt, j);
1578 printf(
"PAIR %d %d (k=%d)\n", s, t, p / 2);
1587 void MeWeightMatcherImpl::verifyOptimum(
bool a_maxCardinality)
1589 int vdualoffset = 0;
1590 if (a_maxCardinality)
1603 for (
int k = 0; k <
m_edges.size(); ++k)
1605 const MeEdge& edge = GetEdge(k);
1610 VecIntPy iblossoms(1, i);
1611 VecIntPy jblossoms(1, j);
1620 iblossoms.reverse();
1621 jblossoms.reverse();
1622 int ijmin = (int)std::min(iblossoms.size(), jblossoms.size());
1623 for (
int ij = 0; ij < ijmin; ++ij)
1625 int bi = iblossoms[ij];
1626 int bj = jblossoms[ij];
1635 mate_i = mate_i == -1 ? -1 : mate_i / 2;
1637 mate_j = mate_j == -1 ? -1 : mate_j / 2;
1638 if (mate_i == k || mate_j == k)
1657 for (
int ip = 1; ip < bendps.size(); ip += 2)
1670 void MeWeightMatcherImpl::checkDelta2()
1676 int bd = 0xdeadc0de;
1679 for (
int idx = 0; idx <
m_neighbEnd[v].size(); ++idx)
1687 if (bk == -1 || (pbd != NULL && d < *pbd))
1697 int sbev = slack(bev);
1698 if ((bev != -1 || bk != -1) && (bev == -1 || (pbd != NULL && *pbd != sbev)))
1700 printf(
"v=%d bk=%d bd=%s bestedge=%d slack=%d\n", v, bk, pbd ? TS_AS_STRING(*pbd) :
"NULL",
1703 XM_ASSERT((bk == -1 && bev == -1) || (bev != -1 && bd == sbev));
1711 void MeWeightMatcherImpl::checkDelta3()
1714 printf(
"checkDelta3\n");
1717 int bd = 0xbaadf00d;
1720 int tbd = 0xbaadf00d;
1726 VecIntPy bleaves = blossomLeaves(b);
1727 for (
int idx = 0; idx < bleaves.size(); ++idx)
1729 int v = bleaves[idx];
1730 for (
int idx2 = 0; idx2 <
m_neighbEnd[v].size(); ++idx2)
1738 if (bk == -1 || (pbd != NULL && d < *pbd))
1744 printf(
"changed bd b=%d,v=%d,p=%d,k=%d,bd=%d\n", b, v, p, k, bd);
1760 if (tbk == -1 || (ptbd != NULL && slack(
m_bestEdge[b]) < *ptbd))
1766 printf(
"changed tbd b=%d,tbk=%d,tbd=%d\n", b, tbk, tbd);
1775 printf(
"bk=%d tbk=%d bd=%s tbd=%s\n", bk, tbk, pbd ? TS_AS_STRING(*pbd) :
"NULL",
1776 ptbd ? TS_AS_STRING(*ptbd) :
"NULL");
1789 const MeEdge& MeWeightMatcherImpl::GetEdge(
int a_idx)
1793 a_idx = (int)
m_edges.size() + a_idx;
1811 BSHP<MeWeightMatcher> wm(
new MeWeightMatcherImpl);
1841 using namespace xms;
1846 #define TS_ASSERT_MATCH_WEIGHTS(a_expected, a_edges, a_cardinality) \ 1847 _TS_ASSERT_MATCH_WEIGHTS(__FILE__, __LINE__, a_expected, a_edges, a_cardinality) 1848 #define _TS_ASSERT_MATCH_WEIGHTS(a_file, a_line, a_expected, a_edges, a_cardinality) \ 1850 iMatchWeights(a_file, a_line, a_expected, a_edges, a_cardinality) 1860 void iMatchWeights(
const char* a_file,
1862 const VecInt& a_expected,
1864 bool a_useMaxCardinality =
false)
1867 for (
auto& edgeVec : a_edges)
1869 MeEdge edge(edgeVec[0], edgeVec[1], edgeVec[2]);
1870 edges.push_back(edge);
1873 MeWeightMatcherImpl weightMatcher;
1874 VecInt matchWeights = weightMatcher.MatchWeights(edges, a_useMaxCardinality);
1875 _TS_ASSERT_EQUALS(a_file, a_line, a_expected, matchWeights);
1888 VecInt vals = {1, 5, -1, 1, 2, 3, 4};
1889 VecIntPy values(vals);
1890 TS_ASSERT_EQUALS(4, values.back());
1891 TS_ASSERT_EQUALS(3, values[-2]);
1893 auto min = values.min();
1894 TS_ASSERT_EQUALS(-1, min);
1896 min = values.min(1, 3);
1897 TS_ASSERT_EQUALS(-1, min);
1899 auto max = values.max();
1900 TS_ASSERT_EQUALS(5, max);
1902 max = values.max(2, 6);
1903 TS_ASSERT_EQUALS(3, max);
1906 VecInt expected = {2, 3, 4, 1, 5, -1, 1};
1907 TS_ASSERT_EQUALS(expected, values.ToVecInt());
1909 auto index = values.index(1);
1910 TS_ASSERT_EQUALS(3, index);
1912 values.resize_to_count(7);
1913 expected = {0, 1, 2, 3, 4, 5, 6};
1914 TS_ASSERT_EQUALS(expected, values.ToVecInt());
1916 values.resize_to_count(4, 5);
1917 expected = {5, 6, 7, 8};
1918 TS_ASSERT_EQUALS(expected, values.ToVecInt());
1921 expected = {8, 7, 6, 5};
1922 TS_ASSERT_EQUALS(expected, values.ToVecInt());
1930 printf(
"test10_empty\n\n");
1940 printf(
"test11_singleedge\n\n");
1943 VecInt expected = {1, 0};
1952 printf(
"test12\n\n");
1954 VecInt2d edges = {{1, 2, 10}, {2, 3, 11}};
1955 VecInt expected = {-1, -1, 3, 2};
1964 printf(
"test13\n\n");
1966 VecInt2d edges = {{1, 2, 5}, {2, 3, 11}, {3, 4, 5}};
1967 VecInt expected = {-1, -1, 3, 2, -1};
1976 printf(
"test14_maxcard\n\n");
1978 VecInt2d edges = {{1, 2, 5}, {2, 3, 11}, {3, 4, 5}};
1979 VecInt expected = {-1, 2, 1, 4, 3};
1988 printf(
"test16_negative\n\n");
1990 VecInt2d edges = {{1, 2, 2}, {1, 3, -2}, {2, 3, 1}, {2, 4, -1}, {3, 4, -6}};
1991 VecInt expected = {-1, 2, 1, -1, -1};
1994 printf(
"test16_negative-true\n\n");
1996 expected = {-1, 3, 4, 1, 2};
2005 printf(
"test20_sblossom-1\n\n");
2007 VecInt2d edges = {{1, 2, 8}, {1, 3, 9}, {2, 3, 10}, {3, 4, 7}};
2008 VecInt expected = {-1, 2, 1, 4, 3};
2011 printf(
"test20_sblossom-2\n\n");
2013 edges = {{1, 2, 8}, {1, 3, 9}, {2, 3, 10}, {3, 4, 7}, {1, 6, 5}, {4, 5, 6}};
2014 expected = {-1, 6, 3, 2, 5, 4, 1};
2023 printf(
"test21_tblossom-1\n\n");
2025 VecInt2d edges = {{1, 2, 9}, {1, 3, 8}, {2, 3, 10}, {1, 4, 5}, {4, 5, 4}, {1, 6, 3}};
2026 VecInt expected = {-1, 6, 3, 2, 5, 4, 1};
2029 printf(
"test21_tblossom-2\n\n");
2031 edges = {{1, 2, 9}, {1, 3, 8}, {2, 3, 10}, {1, 4, 5}, {4, 5, 3}, {1, 6, 4}};
2032 expected = {-1, 6, 3, 2, 5, 4, 1};
2035 printf(
"test21_tblossom-3\n\n");
2037 edges = {{1, 2, 9}, {1, 3, 8}, {2, 3, 10}, {1, 4, 5}, {4, 5, 3}, {3, 6, 4}};
2038 expected = {-1, 2, 1, 6, 5, 4, 3};
2047 printf(
"test22_s_nest\n\n");
2049 VecInt2d edges = {{1, 2, 9}, {1, 3, 9}, {2, 3, 10}, {2, 4, 8}, {3, 5, 8}, {4, 5, 10}, {5, 6, 6}};
2050 VecInt expected = {-1, 3, 4, 1, 2, 6, 5};
2059 printf(
"test23_s_relabel_nest\n\n");
2061 VecInt2d edges = {{1, 2, 10}, {1, 7, 10}, {2, 3, 12}, {3, 4, 20}, {3, 5, 20},
2062 {4, 5, 25}, {5, 6, 10}, {6, 7, 10}, {7, 8, 8}};
2063 VecInt expected = {-1, 2, 1, 4, 3, 6, 5, 8, 7};
2072 printf(
"test24_s_nest_expand\n\n");
2074 VecInt2d edges = {{1, 2, 8}, {1, 3, 8}, {2, 3, 10}, {2, 4, 12}, {3, 5, 12},
2075 {4, 5, 14}, {4, 6, 12}, {5, 7, 12}, {6, 7, 14}, {7, 8, 12}};
2076 VecInt expected = {-1, 2, 1, 5, 6, 3, 4, 8, 7};
2085 printf(
"test25_s_t_expand\n\n");
2087 VecInt2d edges = {{1, 2, 23}, {1, 5, 22}, {1, 6, 15}, {2, 3, 25},
2088 {3, 4, 22}, {4, 5, 25}, {4, 8, 14}, {5, 7, 13}};
2089 VecInt expected = {-1, 6, 3, 2, 8, 7, 1, 5, 4};
2098 printf(
"test26_s_nest_t_expand\n\n");
2100 VecInt2d edges = {{1, 2, 19}, {1, 3, 20}, {1, 8, 8}, {2, 3, 25}, {2, 4, 18},
2101 {3, 5, 18}, {4, 5, 13}, {4, 7, 7}, {5, 6, 7}};
2102 VecInt expected = {-1, 8, 3, 2, 7, 6, 5, 4, 1};
2112 printf(
"test30_tnasty_expand\n\n");
2114 VecInt2d edges = {{1, 2, 45}, {1, 5, 45}, {2, 3, 50}, {3, 4, 45}, {4, 5, 50},
2115 {1, 6, 30}, {3, 9, 35}, {4, 8, 35}, {5, 7, 26}, {9, 10, 5}};
2116 VecInt expected = {-1, 6, 3, 2, 8, 7, 1, 5, 4, 10, 9};
2125 printf(
"test31_tnasty2_expand\n\n");
2127 VecInt2d edges = {{1, 2, 45}, {1, 5, 45}, {2, 3, 50}, {3, 4, 45}, {4, 5, 50},
2128 {1, 6, 30}, {3, 9, 35}, {4, 8, 26}, {5, 7, 40}, {9, 10, 5}};
2129 VecInt expected = {-1, 6, 3, 2, 8, 7, 1, 5, 4, 10, 9};
2139 printf(
"test32_t_expand_leastslack\n\n");
2141 VecInt2d edges = {{1, 2, 45}, {1, 5, 45}, {2, 3, 50}, {3, 4, 45}, {4, 5, 50},
2142 {1, 6, 30}, {3, 9, 35}, {4, 8, 28}, {5, 7, 26}, {9, 10, 5}};
2143 VecInt expected = {-1, 6, 3, 2, 8, 7, 1, 5, 4, 10, 9};
2153 printf(
"test33_nest_tnasty_expand\n\n");
2155 VecInt2d edges = {{1, 2, 45}, {1, 7, 45}, {2, 3, 50}, {3, 4, 45}, {4, 5, 95},
2156 {4, 6, 94}, {5, 6, 94}, {6, 7, 50}, {1, 8, 30}, {3, 11, 35},
2157 {5, 9, 36}, {7, 10, 26}, {11, 12, 5}};
2158 VecInt expected = {-1, 8, 3, 2, 6, 9, 4, 10, 1, 5, 7, 12, 11};
2167 printf(
"test34_nest_relabel_expand\n\n");
2169 VecInt2d edges = {{1, 2, 40}, {1, 3, 40}, {2, 3, 60}, {2, 4, 55}, {3, 5, 55}, {4, 5, 50},
2170 {1, 8, 15}, {5, 7, 30}, {7, 6, 10}, {8, 10, 10}, {4, 9, 30}};
2171 VecInt expected = {-1, 2, 1, 5, 9, 3, 7, 6, 10, 4, 8};
2181 printf(
"testSimpleTriangle\n\n");
2190 VecInt2d edges = { {0, 1, 15}, {1, 2, 10}, {2, 3, 15}, {3, 4, 10},
2191 {1, 5, 10}, {3, 7, 10}, {5, 6, 15}, {6, 7, 10},
2193 {0, 2, -10}, {2, 4, -10}, {4, 7, -10}, {7, 8, -10}, {8, 5, -10}, {5, 0, -10}};
2195 VecInt expected = {1, 0, 3, 2, -1, 6, 5, -1, -1};
2199 expected = {1, 0, 3, 2, 7, 6, 5, 4, -1};
2209 printf(
"testSimpleQuad\n\n");
2223 {0, 1, 15}, {1, 2, 10}, {2, 3, 15}, {3, 4, 10}, {4, 5, 15},
2224 {6, 7, 15}, {7, 8, 10}, {8, 9, 15}, {9, 10, 10}, {10, 11, 15},
2225 {12, 13, 15}, {13, 14, 10}, {14, 15, 15}, {15, 16, 10}, {16, 17, 15},
2226 {0, 2, -10}, {2, 4, -10}, {4, 5, -5}, {5, 11, -10}, {11, 17, -10},
2227 {17, 15, -10}, {15, 13, -10}, {12, 13, -5}, {12, 6, -10}, {6, 0, -10}
2231 VecInt expected = {1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, 17, 16};
2244 printf(
"testComplexQuad\n\n");
2260 {0, 1, 10}, {1, 2, 10}, {2, 3, 10}, {3, 4, 10},
2262 {0, 6, 10}, {2, 8, 10}, {4, 11, 10},
2264 {5, 6, 10}, {6, 7, 10}, {7, 8, 10}, {8, 9, 10}, {9, 10, 10}, {10, 11, 10},
2266 {5, 13, 10}, {7, 15, 10}, {9, 17, 10}, {10, 19, 10},
2268 {12, 13, 10}, {13, 14, 10}, {14, 15, 10}, {15, 16, 10}, {16, 17, 10},
2269 {17, 18, 10}, {18, 19, 10}, {19, 20, 10},
2271 {12, 22, 10}, {14, 24, 10}, {16, 26, 10}, {18, 29, 10}, {20, 30, 10},
2272 {21, 22, 10}, {22, 23, 10}, {23, 24, 10}, {24, 25, 10}, {25, 26, 10},
2273 {26, 27, 10}, {27, 28, 10}, {28, 29, 10}, {29, 30, 10}, {30, 31, 10},
2275 {0, 1, -5}, {1, 3, -10}, {3, 4, -5}, {4, 11, -5}, {11, 20, -15}, {20, 31, -10},
2276 {31, 28, -15}, {28, 27, -5}, {27, 25, -10}, {25, 23, -10}, {23, 21, -10}, {21, 12, -10},
2277 {12, 5, -10}, {5, 0, -10}
2280 VecInt expected = { 1, 0, 3, 2, 11, 6, 5, 8, 7, 10, 9, 4, 13, 12, 15, 14, 17, 16, 29, 20, 19, 22, 21, 24, 23, 26, 25, 28, 27, 18, 31, 30 };
#define TS_ASSERT_MATCH_WEIGHTS(a_expected, a_edges, a_cardinality)
Helper to run matcher tests.
std::vector< int > VecInt
void testSimpleQuad()
Test simple quad with three divisions on each side.
std::vector< bool > VecBool
static BSHP< MeWeightMatcher > New()
Create new weight matcher.
void test14_maxcard()
Test maximum cardinality.
void test21_tblossom()
Test create S-blossom, relabel as T-blossom, use for augmentation.
VecInt2dPy m_blossomChildren
void test32_t_expand_leastslack()
Test create blossom, relabel as T, expand such that a new least-slack S-to-free edge is produced...
void test25_s_t_expand()
Test create S-blossom, relabel as T, expand.
int m_weight
The weight assigned to the edge.
VecInt2dPy m_blossomBestEdges
int m_nVertex
Number of points in the mesh.
void testSimpleTriangle()
Test simple triangle with three divisions on each side.
void test34_nest_relabel_expand()
Test create nested S-blossom, relabel as S, expand recursively.
VecIntPy m_queue
Queue of newly discovered S-vertices.
void test11_singleedge()
Test single edge.
VecMeEdge m_edges
Edges are numbered 0 .. (nedge-1).
std::vector< VecInt > VecInt2d
void test12()
Test with two edges.
VecInt m_vec
The vector storage.
void test20_sblossom()
Test create S-blossom and use it for augmentation.
MeWeightMatcher()
Constructor.
VecIntPy m_unusedBlossoms
void test13()
Test with three edges.
void test33_nest_tnasty_expand()
Test create nested blossom, relabel as T in more than one way, expand outer blossom such that inner b...
void testPythonVectors()
Test VecIntPy class.
void test24_s_nest_expand()
Test create nested S-blossom, augment, expand recursively.
int m_nEdge
Number of edges in m_edges.
void test31_tnasty2_expand()
Test again but slightly different.
void test30_tnasty_expand()
Test create blossom, relabel as T in more than one way, expand, augment.
void test10_empty()
Test empty input graph.
int m_maxWeight
Maximum of weights in m_edges.
void test26_s_nest_t_expand()
Test create nested S-blossom, relabel as T, expand.
int m_f1
Index of one of the adjacent faces.
void testComplexQuad()
Test complex quad with three divisions on two opposite sides and.
void test23_s_relabel_nest()
Test create S-blossom, relabel as S, include in nested S-blossom.
int m_f0
Index of one of the adjacent faces.
VecInt2dPy m_blossomEndPts
std::vector< MeEdge > VecMeEdge
Vector of MeEdge.
void test22_s_nest()
Test create nested S-blossom, use for augmentation.
void test16_negative()
Test negative weights.
virtual ~MeWeightMatcher()
Destructor.