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
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
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
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
00103
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
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_),
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
00157
00158 cons c;
00159 forall_basic_constraints(c, s) {
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
00192
00193
00194
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
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
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
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
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 {
00271 cout<<"HEIRERERTAERGARTHJFTAJSDFG\n";
00272 v1[w]=z1;
00273 v2[w]=z2;
00274 };
00275 };
00276 };
00277 wo=P.add_variable(1,0,100,Vartype_Float);
00278
00279
00280 cons b=P.add_basic_constraint(z1+z2==1);
00281 cons_map<var> VM1;
00282 cons_map<var> VM2;
00283
00284
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
00291 cons c;
00292 forall_basic_constraints(c, s)
00293
00294
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
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
00310 separate_disj* sd=new separate_disj(v1,v2, z1, z2,
00311 b, A, C1, C2, s, IN);
00312 P.add_sym_constraint(sd);
00313
00314
00315 P.optimize();
00316
00317
00318 row r; double d, d1, vi=0;
00319
00320 forall_variables(w, s) {
00321 if(IN[w]) {
00322 d1=-sd->value(VM1[w])-sd->value(VM2[w]);
00323
00324
00325
00326
00327
00328 } else {
00329 d1=leda_max(sd->value1(w),sd->value2(w));
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339 if(d1!=0) {
00340 r+=d1*w;
00341 vi+=d1*s.value(w);
00342 }
00343 };
00344 if(true) {
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 };