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.