Open
Graph Drawing
Framework

 v.2012.05
 

MaxCPlanar_Sub.h
Go to the documentation of this file.
00001 /*
00002  * $Revision: 2299 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2012-05-07 15:57:08 +0200 (Mon, 07 May 2012) $ 
00007  ***************************************************************/
00008  
00045 #ifndef OGDF_MAX_CPLANAR_SUB_H
00046 #define OGDF_MAX_CPLANAR_SUB_H
00047 
00048 #include <ogdf/internal/cluster/MaxCPlanar_Master.h>
00049 #include <ogdf/basic/ArrayBuffer.h>
00050 #include <ogdf/planarity/BoyerMyrvold.h>
00051 
00052 #include <abacus/sub.h>
00053 
00054 namespace ogdf {
00055 
00056 class Sub : public ABA_SUB {
00057     
00058 public:
00059 
00060     Sub(ABA_MASTER *master);
00061     Sub(ABA_MASTER *master, ABA_SUB *father, ABA_BRANCHRULE *branchRule, List<ABA_CONSTRAINT*>& criticalConstraints);
00062 
00063     virtual ~Sub();
00064     
00065     // Creation of a child-node in the Branch&Bound tree according to the
00066     // branching rule \a rule
00067     virtual ABA_SUB *generateSon(ABA_BRANCHRULE *rule);
00068     
00069     
00070 protected:
00071 
00072     
00073     // Checks if the current solution of the LP relaxation is also a feasible solution to the ILP,
00074     // i.e. Integer-feasible + satisfying all Kuratowski- and Cut-constraints.
00075     virtual bool feasible();
00076 
00077     virtual int makeFeasible() { return 0; }  // to trick ABA_SUB::solveLp...
00078 //  virtual int removeNonLiftableCons() { return 0; } // to trick ABA_SUB::solveLp into returning 2
00079     int repair();
00080     
00081     virtual int optimize() {
00082         Logger::slout() << "OPTIMIZE BEGIN\tNode=" << this->id() << "\n";
00083         int ret = ABA_SUB::optimize();
00084         Logger::slout() << "OPTIMIZE END\tNode=" << this->id() << " db=" << dualBound() << "\tReturn=" << (ret?"(error)":"(ok)") << "\n";
00085         return ret;
00086     }
00087     
00088     //functions for testing properties of the clustered graph
00089     
00092     bool checkCConnectivity(const GraphCopy& support);
00093     bool checkCConnectivityOld(const GraphCopy& support);
00094     
00097     inline node getRepresentative(node v, NodeArray<node> &parent)
00098     {
00099         while (v != parent[v])
00100             v = parent[v];
00101         return v;
00102     }
00103     
00104     // Todo: Think about putting this into extended_graph_alg.h to make it 
00105     // publically available
00106     int clusterBags(ClusterGraph &CG, cluster c);
00107     
00108 // using the below two functions iunstead (and instead of solveLp) we would get a more traditional situation
00109 //  virtual int separate() { 
00110 //      return separateRealO(0.001);
00111 //  }
00112 //  virtual int pricing()  {
00113 //      return pricingRealO(0.001);
00114 //  }
00115     
00121     int separateReal(double minViolate);
00122     int pricingReal(double minViolate);
00123 
00124     inline int separateRealO(double minViolate) {
00125         Logger::slout() << "\tSeparate (minViolate=" << minViolate << ")..";
00126         int r = separateReal(minViolate);
00127         Logger::slout() << "..done: " << r << "\n";
00128         return r;
00129     }
00130     inline int pricingRealO(double minViolate) {
00131         Logger::slout() << "\tPricing (minViolate=" << minViolate << ")..";
00132         int r = pricingReal(minViolate);
00133         master()->m_varsPrice += r;
00134         Logger::slout() << "..done: " << r << "\n";
00135         return r;
00136     }
00137     
00138     virtual int separate() {
00139         Logger::slout() << "\tReporting Separation: "<<((m_reportCreation>0)?m_reportCreation:0)<<"\n"; 
00140         return (m_reportCreation>0)?m_reportCreation:0;
00141     }
00142     virtual int pricing()  { 
00143         if(inOrigSolveLp) return 1;
00144         Logger::slout() << "\tReporting Prizing: "<<((m_reportCreation<0)?-m_reportCreation:0)<<"\n";
00145         return (m_reportCreation<0)?-m_reportCreation:0;
00146     }
00147     
00148     virtual int solveLp();
00149     
00150     // Implementation of virtual function improve() inherited from ABA::SUB.
00151     // Invokes the function heuristicImprovePrimalBound().
00152     // Tthis function belongs to the ABACUS framework. It is invoked after each separation-step.
00153     // Since the heuristic is rather time consuming and because it is not very advantageous
00154     // to run the heuristic even if additional constraints have been found, the heuristic 
00155     // is run "by hand" each time no further constraints coud be found, i.e. after having solved
00156     // the LP-relaxation optimally. 
00157     virtual int improve(double &primalValue);
00158     
00159     // Two functions inherited from ABACUS and overritten to manipulate the branching behaviour.
00160     virtual int selectBranchingVariableCandidates(ABA_BUFFER<int> &candidates);
00161     virtual int selectBranchingVariable(int &variable);
00162     
00164     inline int addPoolCons(ABA_BUFFER<ABA_CONSTRAINT *> &cons, ABA_STANDARDPOOL<ABA_CONSTRAINT, ABA_VARIABLE> *pool)
00165     {
00166         return (master()->useDefaultCutPool()) ? addCons(cons) : addCons(cons, pool);
00167     }//addPoolCons
00168     inline int separateCutPool(ABA_STANDARDPOOL<ABA_CONSTRAINT, ABA_VARIABLE> *pool, double minViolation)
00169     {
00170         return (master()->useDefaultCutPool()) ? 0 : constraintPoolSeparation(0, pool, minViolation);  
00171     }//separateCutPool
00172 
00173 private:
00174     
00175     Master* master() { return (Master*)master_; }
00176     
00177     // A flag indicating if constraints have been found in the current separation step.
00178     // Is used to check, if the primal heuristic should be run or not.
00179     bool m_constraintsFound;
00180     bool detectedInfeasibility;
00181     bool inOrigSolveLp;
00182     double realDualBound;
00183     
00184     // used for the steering in solveLp
00185     int m_reportCreation;
00186     bool m_sepFirst;
00187     List< ABA_CONSTRAINT* > criticalSinceBranching;
00188     ArrayBuffer<ABA_CONSTRAINT* > bufferedForCreation;
00189     int createVariablesForBufferedConstraints();
00190     
00191     void myAddVars(ABA_BUFFER<ABA_VARIABLE*>& b) {
00192         int num = b.number();
00193         ABA_BUFFER<bool> keep(master(),num);
00194         for(int i=num; i-->0;)
00195             keep.push(true);
00196         int r = addVars(b,0,&keep);
00197         OGDF_ASSERT( r==num )
00198     }
00199 
00200     
00201     // Computes the support graph for Kuratowski- constraints according to the current LP-solution.
00202     // Parameter \a low defines a lower threshold, i.e all edges having value at most \a low
00203     // are not added to the support graph.
00204     // Parameter \a high defines an upper threshold, i.e all edges having value at least \a high,
00205     // are added to the support graph.
00206     // Edges having LP-value k that lies between \a low and \a high are added to the support graph
00207     // randomly with a probability of k.
00208     void kuratowskiSupportGraph(
00209         GraphCopy &support,
00210         double low,
00211         double high);
00212     
00213     // Computes the support graph for Connectivity- constraints according to the current LP-solution.
00214     void connectivitySupportGraph(
00215         GraphCopy &support,
00216         EdgeArray<double> &weight);
00217     
00218     // Computes the integer solution induced Graph.
00219     void intSolutionInducedGraph(GraphCopy &support);
00220     
00221     // Computes and returns the value of the lefthand side of the Kuratowski constraint
00222     // induced by \a it and given support graph \a gc.
00223     double subdivisionLefthandSide(
00224         SListConstIterator<KuratowskiWrapper> it,
00225         GraphCopy *gc);
00226     
00227     // Updates the best known solution according to integer solution of this subproblem.
00228     void updateSolution();
00229     
00230     
00231     // The following four functions are used by the primal heuristic.
00232      
00233     int getArrayIndex(double lpValue);
00234     
00235     void childClusterSpanningTree(
00236         GraphCopy &GC,
00237         List<edgeValue> &clusterEdges,
00238         List<nodePair> &MSTEdges);
00239     
00240     void clusterSpanningTree(
00241         ClusterGraph &C,
00242         cluster c,
00243         ClusterArray<List<nodePair> > &treeEdges,
00244         ClusterArray<List<edgeValue> > &clusterEdges);
00245     
00246     // Tries to improve the best primal solution by means of the current fractional LP-solution.
00247     double heuristicImprovePrimalBound(
00248         List<nodePair> &originalEdges,
00249         List<nodePair> &connectionEdges,
00250         List<edge> &deletedEdges);
00251         
00253     inline int addCutCons(ABA_BUFFER<ABA_CONSTRAINT *> cons)
00254     {
00255         return addPoolCons(cons, ((Master*)master_)->getCutConnPool());
00256     }
00258     inline int addKuraCons(ABA_BUFFER<ABA_CONSTRAINT *> cons)
00259     {
00260         return addPoolCons(cons, ((Master*)master_)->getCutKuraPool());
00261     }
00262     
00263     //tries to regenerate connectivity cuts
00264     inline int separateConnPool(double minViolation)
00265     {
00266         return separateCutPool(((Master*)master_)->getCutConnPool(),minViolation);
00267     }
00268     //tries to regenerate kuratowski cuts
00269     inline int separateKuraPool(double minViolation)
00270     {
00271         return separateCutPool(((Master*)master_)->getCutKuraPool(),minViolation);
00272     }   
00273     /*  
00274     void minimumSpanningTree(
00275         GraphCopy &GC,
00276         List<nodePair> &clusterEdges,
00277         List<nodePair> &MSTEdges);
00278     
00279     void recursiveMinimumSpanningTree(
00280         ClusterGraph &C,
00281         cluster c,
00282         ClusterArray<List<nodePair> > &treeEdges,
00283         List<nodePair> &edgesByIncLPValue,
00284         List<node> &clusterNodes);
00285         
00286     double heuristicImprovePrimalBoundDet(
00287         List<nodePair> &origEdges,
00288         List<nodePair> &conEdges,
00289         List<nodePair> &delEdges);
00290         */
00291         
00292 };
00293 
00294 }//end namespace
00295 
00296 #endif