$title cutting planes for Oil Pipeline Design Problem $include oilbase.inc $gdxIn net $load n k kk port regnode arc p cap dist pipecost cap1 pipecost1 $gdxIn dsh $load siter dsh Scalar numcuts number of cuts to be added /0/; $if not exist bchout_i.gdx $exit $gdxIn bchout_i $load b Set soltree(n,n) acrs in the solution desc(n,n) descendants of a node level levels in the tree / 1*50 / unvisit(n) nodes that have yet been visited visit(n) nodes that have been visited from(level,n) nodes to traverse from at each level to(level,n) nodes to be traversed to at each level notreenode(n) node no in soltuino tree Scalar maxlevel maximum level in the tree / 0 / i for index; $eolCom // soltree(arc) = round(b.l(arc)); notreenode(regnode) = sum(soltree(regnode,n), 1) = 0; from('1',port) = yes; // We start traversing with the port node unvisit(n) = not notreenode(n); // All nodes are currently unvisited visit(n) = notreenode(n); // No node has been visited loop(level$card(unvisit), // loop through each level until every node has been visited maxlevel = maxlevel+1; unvisit(n)$from(level,n) = no; // mark the 'from' nodes to be visited visit(n)$from(level,n) = yes; to(level,unvisit) = sum((from(level,n),soltree(unvisit,n)), yes); // identify the 'to' nodes at this level from(level+1,n)$to(level,n) = yes; // move one layer down ); abort$card(unvisit) 'level set too small'; * Travel the tree from the leaves to the root for (i=maxlevel downto 1, loop(from(level,n)$(ord(level) = i), desc(n,n) = yes; loop((to(level,m),soltree(m,n)), desc(n,nn)$desc(m,nn) = yes); ) ); * Add nodes outside the tree to descendants so that all arcs from this node stay * in the decendant set Set ndesc(n) nunion(n); loop(n$notreenode(n), visit(nn) = no; visit(nn)$arc(n,nn) = yes; loop(nn$(not notreenode(nn)), ndesc(m) = no; ndesc(m)$desc(nn,m) = yes; nunion(m) = visit(m) + ndesc(m); desc(nn,n) = card(nunion) = card(ndesc); ) ); * We need the optimal solution oilbase.optcr=0; oilbase.solvelink=%solveLink.callModule%; option limrow=0, limcol=0, solprint=off, mip=%mipsolver%; Scalar dup indicator for duplicated node set / 0 / Parameter lb(n) the rhs lower bound for each cut; loop(nn$(not notreenode(nn)), dup = 0; nw(n) = no; nw(n)$desc(nn,n) = yes; i = card(nw); if(card(nw)<17, // if the node block is of proper size, check for duplication loop(ss$((ord(ss)