Main Page   Class Hierarchy   Compound List   File List   Contact   Download   Symbolic Constraints   Examples  

disjunctive.cc

00001 #include<scil/constraints/disjunctive.h>
00002 #include<scil/cons_map.h>
00003 
00004 #define infinity 1e+30
00005 
00006 class disjunctive::disjunctive_cut : public cons_obj {
00007  private:
00008   cons_obj* c;
00009   h_array<var,var>& VM;
00010   var v;
00011   bool de;
00012 
00013  public:
00014   disjunctive_cut(cons_obj* c_, h_array<var,var>& VM_, var v_, bool de_=false) 
00015     : cons_obj(c_->sense(), 0), VM(VM_), de(de_) {
00016     c=c_;
00017     v=v_;
00018   };
00019 
00020   void non_zero_entries(row& r) {
00021     row r1;
00022     c->non_zero_entries(r1);
00023 
00024     row_entry re;
00025     forall(re, r1) {
00026       if(VM[re.Var]!=nil)
00027         r+=re.coeff*VM[re.Var];
00028     };
00029     r-=c->rhs()*v;
00030     //cout<<r1.size()<<" size of row\n";
00031   };
00032 
00033   ~disjunctive_cut() {
00034     if(de) delete c;
00035   };
00036 };
00037 
00038 #ifdef ABACUS_COMPILER_GCC
00039 class my_subproblem : public subproblem {
00040 #else
00041 class my_subproblem : public Std_subproblem_ {
00042 #endif
00043 private:
00044   h_array<var,var>& V;
00045   var z;
00046   subproblem& S;
00047   subproblem& S1;
00048   double d;
00049 
00050 public:
00051   my_subproblem(h_array<var,var>& V_, var z_, subproblem& S_,
00052                 subproblem& S1_) :
00053 #ifdef ABACUS_COMPILER_GCC
00054     subproblem(&S_.GM), 
00055 #endif
00056     V(V_), z(z_), S(S_), S1(S1_) {
00057     d=S1.value(z);
00058   };
00059 
00060   double
00061   value(var v) {
00062     if(V[v]==nil) return 0;
00063     return S1.value(V[v])/d;
00064   };
00065 
00066   cons add_basic_constraint(cons_obj* c, Activation a = Static) {
00067     //cout<<"add modified constraint\n";
00068     return S1.add_basic_constraint(new disjunctive::disjunctive_cut(c, V, z, true));
00069   };
00070 
00071   bool my_separate() {
00072     sym_constraint* sc;
00073     bool b=false;
00074     forall_sym_constraints(sc, S) {
00075       disjunctive* d=dynamic_cast<disjunctive*>(sc);
00076       if(d==nil) {
00077         sym_constraint::status s=sc->separate(*this);
00078         if(s==sym_constraint::constraint_found) b=true;
00079       };
00080     };
00081     return b;
00082   };
00083 
00084   virtual
00085   ~my_subproblem() {
00086   };
00087 
00088   void before_delete() {
00089 #ifndef ABACUS_COMPILER_GCC
00090     fatherp=this;
00091 #endif
00092     //sym_constraints.clear();
00093   };
00094 };
00095 
00096 class separate_disj : public sym_constraint {
00097 private:
00098   h_array<var,var>& v1;
00099   h_array<var,var>& v2;
00100   var z1, z2;
00101   bool b1;
00102   //cons_map<var>& VM1;
00103   //cons_map<var>& VM2;
00104   cons b;
00105   list<cons>& A;
00106 
00107   h_array<var, double> D1;
00108   h_array<var, double> D2;
00109   cons_map<cons>& C1;
00110   cons_map<cons>& C2;
00111 
00112   subproblem& OS;
00113   h_array<var,bool>& IN;
00114   h_array<cons, double> Vv;
00115   int count;
00116 
00117 public:
00118 
00119   separate_disj(h_array<var,var>& v1_, h_array<var,var>& v2_, 
00120                 var z1_, var z2_,
00121                 //cons_map<var>& VM1_, cons_map<var>& VM2_, 
00122                 cons b_, 
00123                 list<cons>& A_, cons_map<cons>& C1_, cons_map<cons>& C2_,
00124                 subproblem& OS_, h_array<var, bool>& IN_)
00125     : v1(v1_), v2(v2_), z1(z1_), z2(z2_), // VM1(VM1_), VM2(VM2_), 
00126       b(b_), A(A_),
00127       C1(C1_), C2(C2_), OS(OS_), IN(IN_) {
00128     count=0;
00129   };
00130 
00131   status feasible(solution& S) {
00132     if(count<1000) return infeasible_solution;
00133     return feasible_solution;
00134   };
00135 
00136   status separate(subproblem& s) {
00137     count++;
00138     cout<<count<<" counter\n";
00139     if(count<=1) {
00140       solution sol;
00141       my_subproblem* SP=new my_subproblem(v1, z1, OS, s);
00142       b1=SP->my_separate();
00143       SP->before_delete();
00144       delete SP;
00145       SP=new my_subproblem(v2, z2, OS, s);
00146       bool b2=SP->my_separate();
00147       SP->before_delete();
00148       delete SP;
00149       b1=b1 || b2;
00150       
00151       if(b1)
00152         return constraint_found;
00153     } else b1=false;
00154 
00155     cout<<"SAVE SOLUTOIN\n";
00156     //V1v.clear();
00157     //V2v.clear();
00158     cons c;
00159     forall_basic_constraints(c, s) { // TODO improve: only some values need to be saved
00160       Vv[c]=s.value(c);
00161     };
00162 
00163     var v;
00164     forall_variables(v, OS) if(IN[v]) {
00165       D1[v]=s.red_cost(v1[v]);
00166       D2[v]=s.red_cost(v2[v]);
00167     };
00168 
00169     double d;
00170     forall(c, A) {
00171       d=s.value(C1[c]);
00172       if(d!=0) {
00173         row r1;
00174         c.cons_pointer()->non_zero_entries(r1);
00175         row_entry re;
00176         forall(re, r1) {
00177           D1[re.Var]+=re.coeff*d;
00178         };
00179       };
00180       d=s.value(C2[c]);
00181       if(d!=0) {
00182         row r1;
00183         c.cons_pointer()->non_zero_entries(r1);
00184         row_entry re;
00185         forall(re, r1) {
00186           D2[re.Var]+=re.coeff*d;
00187         };
00188       };
00189     };
00190 
00191     //forall_defined(c, VM2) {
00192     //  Vv[c]=s.value(c);
00193     //};
00194     //Vv[b]=s.value(b);
00195 
00196     count=1000;
00197     return fathom;
00198   };
00199 
00200   double value1(var v) {
00201     return D1[v];
00202   };
00203 
00204   double value2(var v) {
00205     return D2[v];
00206   };
00207 
00208   double value(cons c) {
00209     return Vv[c];
00210   };
00211 };
00212     
00213 disjunctive::status disjunctive::separate(subproblem& s) {
00214 
00215   // Compute a cut?
00216 
00217   if (s.found_constraint()) {
00218     return no_constraint_found;
00219   };
00220 
00221   cout<<"DISJUNCTIVE SEPARATION\n";
00222   
00223   status sta=no_constraint_found;
00224   list<cons_obj* > L;
00225 
00226   // Compute fractional variables
00227 
00228   list<var> FRAC;
00229   var v, w;
00230   double d;
00231   h_array<var,bool> IN;
00232   forall_variables(v, s) {
00233     d=s.value(v);
00234     if ((d>0.001) && (d<0.999)) 
00235       FRAC.append(v);
00236     if(d>0.001) IN[v]=true; else IN[v]=false;
00237   }
00238 
00239   int nk=0;     
00240   forall(v, FRAC) if((s.value(v)>0.2) && (s.value(v)<0.8) && (nk<10)) {
00241     nk++;
00242     cout<<nk<<"th round\n";
00243     // Create Initial Cut generating LP
00244 
00245     ILP_Problem P(Optsense_Min);
00246 #ifdef ABACUS_COMPILER_GCC
00247     P.set_silent();
00248 #endif
00249     P.add_variable(0,0,1,Vartype_Integer);
00250     h_array<var,var> v1;
00251     h_array<var,var> v2;
00252     var z1, z2, wo;
00253     list<cons> A;
00254     cons_map<cons> C1;
00255     cons_map<cons> C2;
00256 
00257     // Create Variables;
00258     z1=P.add_variable(0,0,1,Vartype_Float);
00259     z2=P.add_variable(0,0,1,Vartype_Float);
00260 
00261     forall_variables(w, s) {
00262       d=s.value(w);
00263       if (IN[w]) {
00264          v1[w]=P.add_variable(0,0,1,Vartype_Float);
00265          v2[w]=P.add_variable(0,0,1,Vartype_Float);
00266       } else {
00267         if (d<=0.01) {
00268           v1[w]=nil;
00269           v2[w]=nil;
00270         } else { // DOES NOT HAPPEN
00271           cout<<"HEIRERERTAERGARTHJFTAJSDFG\n";
00272           v1[w]=z1; //row(1);
00273           v2[w]=z2; //row(1);
00274         };
00275       };
00276     };
00277     wo=P.add_variable(1,0,100,Vartype_Float);
00278 
00279     // Create generic constraints
00280     cons b=P.add_basic_constraint(z1+z2==1);
00281     cons_map<var> VM1;
00282     cons_map<var> VM2;
00283 
00284     //forall(w, FRAC) {
00285     forall_variables(w, s) if(IN[w]) {
00286       VM1[w]=P.add_basic_constraint(v1[w]+v2[w]+wo>=s.value(w));
00287       VM2[w]=P.add_basic_constraint(v1[w]+v2[w]-wo<=s.value(w));
00288     };
00289 
00290     // Create constraints for constraints
00291     cons c;
00292     forall_basic_constraints(c, s) 
00293       //if((fabs(c.cons_pointer()->slack(s))<0.01) || 
00294       //         (c.cons_pointer()->Act==Static)) {
00295       if(true) {
00296       A.append(c);
00297       C1[c]=P.add_basic_constraint(new disjunctive_cut(c.cons_pointer(), v1, z1));
00298       C2[c]=P.add_basic_constraint(new disjunctive_cut(c.cons_pointer(), v2, z2));
00299     };
00300 
00301     cons u1=P.add_basic_constraint((row) v1[v]<=0);
00302     cons u2=P.add_basic_constraint((row) v2[v]>=z2);
00303     //forall(w, FRAC) {
00304     forall_variables(w, s) if(IN[w]) {
00305       P.add_basic_constraint((row) v2[w]<=z2);
00306       P.add_basic_constraint((row) v1[w]<=z1);
00307     };
00308 
00309     // Separate to strengthen
00310     separate_disj* sd=new separate_disj(v1,v2, z1, z2, //VM1, VM1, 
00311                                         b, A, C1, C2, s, IN);
00312     P.add_sym_constraint(sd);
00313 
00314     // Compute cut
00315     P.optimize();
00316 
00317     // Retrieve Cut
00318     row r; double d, d1, vi=0;
00319     //forall(w, FRAC) {
00320     forall_variables(w, s) {
00321       if(IN[w]) {
00322         d1=-sd->value(VM1[w])-sd->value(VM2[w]);
00323         /*
00324         d1=leda_min(sd->value1(w),sd->value2(w));
00325         if(w.var_pointer()==v.var_pointer()) 
00326           d1=leda_min(sd->value1(w)+sd->value(u1), sd->value2(w)+sd->value(u2));
00327         */
00328       } else {
00329         d1=leda_max(sd->value1(w),sd->value2(w));
00330       }
00331       /*
00332       if(fabs(d-d1)<0.001) { if(fabs(d)>0.001) cout<<"j"; } else {
00333         cout<<endl<<d<<" "<<sd->value(VM1[w])
00334             <<" "<<sd->value(VM2[w])<<"n"
00335             <<(w.var_pointer()==v.var_pointer())<<"\n";
00336         cout<<d1<<" "<<sd->value1(w)<<" "<<sd->value2(w)<<endl;
00337       }
00338       */
00339       if(d1!=0) {
00340         r+=d1*w;
00341         vi+=d1*s.value(w);
00342       }
00343     };
00344     if(true) { // TODO better criterion
00345       L.append(r >= sd->value(b));
00346       cout<<vi-sd->value(b)<<"Violation \n";
00347       if(vi-sd->value(b)>0) for(;;);
00348       sta=constraint_found;
00349     };
00350 
00351     delete sd;
00352   };
00353 
00354   cons_obj* c;
00355   forall(c, L) s.add_basic_constraint(c);
00356 
00357   return sta;
00358 };

Generated on Tue Nov 16 15:18:16 2004 for SCIL by doxygen1.2.16