30  void applyR1(GraphT &
G, 
typename GraphT::NodeId NId) {
 
   31    using NodeId = 
typename GraphT::NodeId;
 
   32    using EdgeId = 
typename GraphT::EdgeId;
 
   33    using Vector = 
typename GraphT::Vector;
 
   34    using Matrix = 
typename GraphT::Matrix;
 
   35    using RawVector = 
typename GraphT::RawVector;
 
   37    assert(
G.getNodeDegree(NId) == 1 &&
 
   38           "R1 applied to node with degree != 1.");
 
   40    EdgeId EId = *
G.adjEdgeIds(NId).begin();
 
   41    NodeId MId = 
G.getEdgeOtherNodeId(EId, NId);
 
   43    const Matrix &ECosts = 
G.getEdgeCosts(EId);
 
   44    const Vector &XCosts = 
G.getNodeCosts(NId);
 
   45    RawVector YCosts = 
G.getNodeCosts(MId);
 
   48    if (NId == 
G.getEdgeNode1Id(EId)) {
 
   49      for (
unsigned j = 0; j < YCosts.getLength(); ++j) {
 
   50        PBQPNum Min = ECosts[0][j] + XCosts[0];
 
   51        for (
unsigned i = 1; i < XCosts.getLength(); ++i) {
 
   52          PBQPNum C = ECosts[i][j] + XCosts[i];
 
   59      for (
unsigned i = 0; i < YCosts.getLength(); ++i) {
 
   60        PBQPNum Min = ECosts[i][0] + XCosts[0];
 
   61        for (
unsigned j = 1; j < XCosts.getLength(); ++j) {
 
   62          PBQPNum C = ECosts[i][j] + XCosts[j];
 
   69    G.setNodeCosts(MId, YCosts);
 
   70    G.disconnectEdge(EId, MId);
 
 
   74  void applyR2(GraphT &
G, 
typename GraphT::NodeId NId) {
 
   75    using NodeId = 
typename GraphT::NodeId;
 
   76    using EdgeId = 
typename GraphT::EdgeId;
 
   77    using Vector = 
typename GraphT::Vector;
 
   78    using Matrix = 
typename GraphT::Matrix;
 
   79    using RawMatrix = 
typename GraphT::RawMatrix;
 
   81    assert(
G.getNodeDegree(NId) == 2 &&
 
   82           "R2 applied to node with degree != 2.");
 
   84    const Vector &XCosts = 
G.getNodeCosts(NId);
 
   86    typename GraphT::AdjEdgeItr AEItr = 
G.adjEdgeIds(NId).begin();
 
   87    EdgeId YXEId = *AEItr,
 
   90    NodeId YNId = 
G.getEdgeOtherNodeId(YXEId, NId),
 
   91           ZNId = 
G.getEdgeOtherNodeId(ZXEId, NId);
 
   93    bool FlipEdge1 = (
G.getEdgeNode1Id(YXEId) == NId),
 
   94         FlipEdge2 = (
G.getEdgeNode1Id(ZXEId) == NId);
 
   96    const Matrix *YXECosts = FlipEdge1 ?
 
   97      new Matrix(
G.getEdgeCosts(YXEId).transpose()) :
 
   98      &
G.getEdgeCosts(YXEId);
 
  100    const Matrix *ZXECosts = FlipEdge2 ?
 
  101      new Matrix(
G.getEdgeCosts(ZXEId).transpose()) :
 
  102      &
G.getEdgeCosts(ZXEId);
 
  108    RawMatrix Delta(YLen, ZLen);
 
  110    for (
unsigned i = 0; i < YLen; ++i) {
 
  111      for (
unsigned j = 0; j < ZLen; ++j) {
 
  112        PBQPNum Min = (*YXECosts)[i][0] + (*ZXECosts)[j][0] + XCosts[0];
 
  113        for (
unsigned k = 1; k < XLen; ++k) {
 
  114          PBQPNum C = (*YXECosts)[i][k] + (*ZXECosts)[j][k] + XCosts[k];
 
  129    EdgeId YZEId = 
G.findEdge(YNId, ZNId);
 
  131    if (YZEId == 
G.invalidEdgeId()) {
 
  132      YZEId = 
G.addEdge(YNId, ZNId, Delta);
 
  134      const Matrix &YZECosts = 
G.getEdgeCosts(YZEId);
 
  135      if (YNId == 
G.getEdgeNode1Id(YZEId)) {
 
  136        G.updateEdgeCosts(YZEId, Delta + YZECosts);
 
  138        G.updateEdgeCosts(YZEId, Delta.transpose() + YZECosts);
 
  142    G.disconnectEdge(YXEId, YNId);
 
  143    G.disconnectEdge(ZXEId, ZNId);