00001 #ifndef SCIL_CPP
00002 #define SCIL_CPP
00003
00004 #include <iostream.h>
00005 #include <scil/scil.h>
00006 #include <scil/subproblem.h>
00007 #include <scil/sym_constraint.h>
00008 #include <cplex.h>
00009
00010 #include <ctype.h>
00011 #include <stdlib.h>
00012
00013 using namespace SCIL;
00014 using namespace LEDA;
00015
00016 #define CPLEX_CONST const
00017
00018 struct ILP_Problem_Data {
00019 CPXENVptr m_pCPXEnv;
00020 CPXLPptr m_pCPXLP;
00021 Optsense m_OptSense;
00022 int m_NumVars;
00023 int m_NumCons;
00024 int m_Status;
00025 int m_GotSolution;
00026 double* m_pSolution;
00027 double* XSOL;
00028
00029 void* cbdata;
00030 int wherefrom;
00031
00032 bool rootcall;
00033
00034 LEDA::list<sym_constraint*> SL;
00035 primal_heuristic* primal_heur;
00036 LEDA::array<var> ItoV;
00037 solution heur_sol;
00038 double heur_obj;
00039 };
00040
00041 struct Variable_Data {
00042 ILP_Problem* m_pILP;
00043 int Index;
00044 };
00045
00046 struct Basic_Constraint_Data {
00047 ILP_Problem* m_pILP;
00048 int Index;
00049 };
00050
00051
00052
00053
00054
00055 <<<<<<< scil.c
00056 void dumpmatrix(ILP_Problem& IP) {
00057
00058
00059
00060
00061
00062
00063 int numrows, numcols;
00064 int rowcnt, colcnt;
00065
00066
00067 numrows = CPXgetnumrows(((ILP_Problem_Data*) IP.DATA)->m_pCPXEnv, ((ILP_Problem_Data*) IP.DATA)->m_pCPXLP);
00068 numcols = CPXgetnumcols(((ILP_Problem_Data*) IP.DATA)->m_pCPXEnv, ((ILP_Problem_Data*) IP.DATA)->m_pCPXLP);
00069
00070 cout << "Matrix has " << numrows << " rows and " << numcols << " columns" << endl;
00071
00072 double coef;
00073
00074 for (rowcnt = 0; rowcnt < numrows; rowcnt++) {
00075 for (colcnt = 0; colcnt < numcols; colcnt++) {
00076 CPXgetcoef (((ILP_Problem_Data*) IP.DATA)->m_pCPXEnv, ((ILP_Problem_Data*) IP.DATA)->m_pCPXLP, rowcnt, colcnt, &coef);
00077 cout << coef << " ";
00078 }
00079 cout << endl;
00080 }
00081
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 subproblem* GlobalS=NULL;
00095
00096 int scil_row_size_without_constant(const row& r) {
00097 int o=0;
00098 if(r.NZ.head().Var==NULL) o=1;
00099 return r.NZ.size()-o;
00100 }
00101
00102 double scil_row_const_part(const row& r) {
00103 if(r.NZ.head().Var==NULL) return r.NZ.head().Coeff;
00104 return 0;
00105 };
00106 =======
00107 subproblem* GlobalS=NULL;
00108
00109 int scil_row_size_without_constant(const row& r) {
00110 int o=0;
00111 if(r.NZ.head().Var==nil) o=1;
00112 return r.NZ.size()-o;
00113 }
00114
00115 double scil_row_const_part(const row& r) {
00116 if(r.NZ.head().Var==nil) return r.NZ.head().Coeff;
00117 return 0;
00118 };
00119 >>>>>>> 1.3
00120
00121 static int CPXPUBLIC
00122 mycutcallback (CPLEX_CONST cpxenv* env,
00123 void *cbdata,
00124 int wherefrom,
00125 void *cbhandle,
00126 int *useraction_p)
00127 {
00128 cout<<"Separation\n";
00129
00130 int i;
00131 double d;
00132 CPXgetcallbackinfo(env, cbdata, wherefrom,
00133 CPX_CALLBACK_INFO_NODE_COUNT, &i);
00134
00135 cout<<i<<" nodes ";
00136
00137 CPXgetcallbackinfo(env, cbdata, wherefrom,
00138 CPX_CALLBACK_INFO_NODES_LEFT, &i);
00139
00140 cout<<i<<" left ";
00141
00142 CPXgetcallbacknodeobjval(env, cbdata, wherefrom, &d);
00143
00144 cout<<d<<" curnode ";
00145
00146 CPXgetcallbackinfo(env, cbdata, wherefrom,
00147 CPX_CALLBACK_INFO_BEST_INTEGER, &d);
00148
00149 cout<<d<<" bestsol ";
00150
00151 CPXgetcallbackinfo(env, cbdata, wherefrom,
00152 CPX_CALLBACK_INFO_BEST_REMAINING, &d);
00153
00154 cout<<d<<" nodeleft\n";
00155
00156 ILP_Problem* IP=static_cast<ILP_Problem *>(cbhandle);
00157
00158 <<<<<<< scil.c
00159
00160
00161
00162 CPXgetcallbacknodex(env, cbdata, wherefrom,
00163 ((ILP_Problem_Data*) IP->DATA)->XSOL, 0,
00164 ((ILP_Problem_Data*) IP->DATA)->m_NumVars-1);
00165 =======
00166
00167 int status = CPXgetcallbacknodex(env, cbdata, wherefrom,
00168 ((ILP_Problem_Data*) IP->DATA)->XSOL, 0,
00169 ((ILP_Problem_Data*) IP->DATA)->m_NumVars-1);
00170 >>>>>>> 1.3
00171
00172 int nc=0;
00173
00174 <<<<<<< scil.c
00175 GlobalS->ILP=IP;
00176
00177
00178
00179 ((ILP_Problem_Data*) IP->DATA)->wherefrom=wherefrom;
00180 ((ILP_Problem_Data*) IP->DATA)->cbdata=cbdata;
00181
00182 =======
00183 GlobalS->ILP=IP;
00184 >>>>>>> 1.3
00185
00186 sym_constraint* s;
00187 sym_constraint::status rs;
00188 <<<<<<< scil.c
00189 forall (s, ((ILP_Problem_Data*) IP->DATA)->SL)
00190 if(nc!=-1) {
00191
00192 rs=s->separate(*GlobalS);
00193
00194 if (rs == sym_constraint::constraint_found) nc++;
00195 if (rs == sym_constraint::fathom) nc=-1;
00196 };
00197 =======
00198 forall (s, ((ILP_Problem_Data*) IP->DATA)->SL)
00199 if(nc!=-1) {
00200 rs=s->separate(*GlobalS);
00201 if (rs == sym_constraint::constraint_found) nc++;
00202 if (rs == sym_constraint::fathom) nc=-1;
00203 };
00204 >>>>>>> 1.3
00205
00206 if(nc==0) {
00207 *useraction_p = CPX_CALLBACK_DEFAULT;
00208 cout<<"NO CUTS\n";
00209 } else {
00210 *useraction_p = CPX_CALLBACK_SET;
00211 cout<<nc<<" CUTS\n";
00212 }
00213
00214 return 0;
00215 }
00216
00217 static int CPXPUBLIC
00218 myheurcallback (CPLEX_CONST cpxenv* env,
00219 void *cbdata,
00220 int wherefrom,
00221 void *cbhandle,
00222 double *objval_p,
00223 double *x,
00224 int *checkfeas_p,
00225 int *useraction_p)
00226 {
00227 ILP_Problem* IP=static_cast<ILP_Problem *>(cbhandle);
00228
00229 <<<<<<< scil.c
00230
00231 CPXgetcallbacknodex(env, cbdata, wherefrom, ((ILP_Problem_Data*) IP->DATA)->XSOL, 0, ((ILP_Problem_Data*) IP->DATA)->m_NumVars-1);
00232 =======
00233
00234 int status = CPXgetcallbacknodex(env, cbdata, wherefrom, ((ILP_Problem_Data*) IP->DATA)->XSOL, 0, ((ILP_Problem_Data*) IP->DATA)->m_NumVars-1);
00235 >>>>>>> 1.3
00236
00237 GlobalS->ILP=IP;
00238
00239 if(((ILP_Problem_Data*) IP->DATA)->primal_heur!=0) {
00240 ((ILP_Problem_Data*) IP->DATA)->primal_heur->heuristic(*GlobalS);
00241 };
00242
00243 for(int i=0; i<IP->number_of_variables(); i++) x[i]=0;
00244
00245 double obj=0;
00246 solution::item i;
00247 forall_items(i, ((ILP_Problem_Data*) IP->DATA)->heur_sol) {
00248 x[((ILP_Problem_Data*) IP->DATA)->heur_sol.key(i).getIndex()]=
00249 ((ILP_Problem_Data*) IP->DATA)->heur_sol.value(((ILP_Problem_Data*) IP->DATA)->heur_sol.key(i));
00250 obj+=((ILP_Problem_Data*) IP->DATA)->heur_sol.key(i).obj()*((ILP_Problem_Data*) IP->DATA)->heur_sol.value(((ILP_Problem_Data*) IP->DATA)->heur_sol.key(i));
00251 }
00252
00253 cout<<obj<<" Heuristic Solution\n";
00254 *objval_p=obj;
00255
00256 *checkfeas_p = 1;
00257
00258 *useraction_p = CPX_CALLBACK_SET;
00259
00260 return 0;
00261 };
00262
00263
00264 <<<<<<< scil.c
00265 ILP_Problem::ILP_Problem(Optsense sense) {
00266 DATA=new ILP_Problem_Data;
00267
00268 if(GlobalS==NULL)
00269 GlobalS=new subproblem(this);
00270 =======
00271 ILP_Problem::ILP_Problem(Optsense sense) {
00272 DATA=new ILP_Problem_Data;
00273 >>>>>>> 1.3
00274
00275 <<<<<<< scil.c
00276 ((ILP_Problem_Data*) DATA)->ItoV.resize(1000);
00277 =======
00278 if(GlobalS==NULL)
00279 GlobalS=new subproblem(this);
00280
00281 ((ILP_Problem_Data*) DATA)->ItoV.resize(1000);
00282 >>>>>>> 1.3
00283
00284 ((ILP_Problem_Data*) DATA)->m_pCPXEnv = NULL;
00285 ((ILP_Problem_Data*) DATA)->m_pCPXLP = NULL;
00286
00287 ((ILP_Problem_Data*) DATA)->m_NumVars=0;
00288
00289 ((ILP_Problem_Data*) DATA)->m_pSolution=0;
00290
00291 ((ILP_Problem_Data*) DATA)->primal_heur=0;
00292
00293 ((ILP_Problem_Data*) DATA)->m_OptSense = sense;
00294
00295 <<<<<<< scil.c
00296 ((ILP_Problem_Data*) DATA)->m_GotSolution = 0;
00297
00298 ((ILP_Problem_Data*) DATA)->m_pCPXEnv = CPXopenCPLEX(&((ILP_Problem_Data*) DATA)->m_Status);
00299 =======
00300 ((ILP_Problem_Data*) DATA)->m_GotSolution = 0;
00301 >>>>>>> 1.3
00302
00303 <<<<<<< scil.c
00304
00305 =======
00306 ((ILP_Problem_Data*) DATA)->m_pCPXEnv = CPXopenCPLEX(&((ILP_Problem_Data*) DATA)->m_Status);
00307 >>>>>>> 1.3
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 ((ILP_Problem_Data*) DATA)->m_pCPXLP = CPXcreateprob(((ILP_Problem_Data*) DATA)->m_pCPXEnv, &((ILP_Problem_Data*) DATA)->m_Status, "scil_lp");
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 if (sense == Optsense_Max) {
00331 CPXchgobjsen(((ILP_Problem_Data*) DATA)->m_pCPXEnv, ((ILP_Problem_Data*) DATA)->m_pCPXLP, CPX_MAX);
00332 }
00333
00334
00335
00336 CPXsetintparam (((ILP_Problem_Data*) DATA)->m_pCPXEnv, CPX_PARAM_REDUCE, CPX_OFF);
00337
00338
00339 CPXsetcutcallbackfunc (((ILP_Problem_Data*) DATA)->m_pCPXEnv, mycutcallback, this);
00340
00341 CPXsetheuristiccallbackfunc (((ILP_Problem_Data*) DATA)->m_pCPXEnv, myheurcallback, this);
00342 }
00343
00344 ILP_Problem::~ILP_Problem() {
00345
00346 if (((ILP_Problem_Data*) DATA)->m_pCPXLP != NULL) {
00347 CPXfreeprob(((ILP_Problem_Data*) DATA)->m_pCPXEnv, &((ILP_Problem_Data*) DATA)->m_pCPXLP);
00348
00349
00350
00351
00352
00353
00354
00355
00356 }
00357
00358 if (((ILP_Problem_Data*) DATA)->m_pCPXEnv != NULL) {
00359
00360 CPXcloseCPLEX(&((ILP_Problem_Data*) DATA)->m_pCPXEnv);
00361
00362
00363
00364
00365
00366
00367
00368
00369 }
00370 delete (ILP_Problem_Data*) DATA;
00371 }
00372
00373 var ILP_Problem::add_variable(double obj, double lBound, double uBound,
00374 Vartype t, Activation a) {
00375
00376 var_obj* v = new var_obj(obj, lBound, uBound, t);
00377 return add_variable(v, a);
00378 }
00379
00380 var ILP_Problem::add_variable(var_obj* v, Activation a) {
00381
00382 char type = CPX_CONTINUOUS;
00383
00384 if ((((ILP_Problem_Data*) DATA)->m_pCPXEnv == NULL) || (((ILP_Problem_Data*) DATA)->m_pCPXLP == NULL)) {
00385 cout << "Error in ILP_Problem::add_variable:" << endl;
00386 cout << "CPLEX Environment not properly initialized." << endl;
00387 }
00388
00389 if (v->type() == Vartype_Integer) {
00390 if ((v->lower_bound() == 0) && (v->upper_bound() == 1)) {
00391 type = CPX_BINARY;
00392 } else {
00393 type = CPX_INTEGER;
00394 }
00395 }
00396
00397
00398 <<<<<<< scil.c
00399
00400
00401
00402
00403 CPXnewcols(((ILP_Problem_Data*) DATA)->m_pCPXEnv, ((ILP_Problem_Data*) DATA)->m_pCPXLP, 1, &(v->objVal), &(v->lBound),
00404 &(v->uBound), &type, NULL);
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 ((Variable_Data*) v->DATA)->Index = CPXgetnumcols(((ILP_Problem_Data*) DATA)->m_pCPXEnv, ((ILP_Problem_Data*) DATA)->m_pCPXLP) - 1;
00424
00425 if(v->getIndex()>=((ILP_Problem_Data*) DATA)->ItoV.high())
00426 ((ILP_Problem_Data*) DATA)->ItoV.resize(2*((ILP_Problem_Data*) DATA)->ItoV.high());
00427
00428 ((ILP_Problem_Data*) DATA)->ItoV[v->getIndex()]=v;
00429
00430
00431 ((Variable_Data*) v->DATA)->m_pILP = this;
00432 ((ILP_Problem_Data*) DATA)->m_NumVars++;
00433 return v;
00434 }
00435
00436 cons ILP_Problem::add_basic_constraint(cons_sense s, double rhs,
00437 Activation a) {
00438 cons_obj* c = new cons_obj(s, rhs);
00439 return add_basic_constraint(c, a);
00440 }
00441
00442 cons ILP_Problem::add_basic_constraint (cons_obj* rc,
00443 Activation a) {
00444
00445 if ((((ILP_Problem_Data*) DATA)->m_pCPXEnv == NULL) || (((ILP_Problem_Data*) DATA)->m_pCPXLP == NULL)) {
00446 cout << "Error in ILP_Problem::add_basic_constraint:" << endl;
00447 cout << "CPLEX Environment not properly initialized." << endl;
00448 }
00449
00450 int rmatbeg;
00451 int *rmatind;
00452 double *rmatval;
00453 double rhs;
00454 char sense;
00455
00456 rhs = rc->rhs();
00457
00458 if (rc->sense() == Equal ) { sense = 'E'; }
00459 if (rc->sense() == Less ) { sense = 'L'; }
00460 if (rc->sense() == Greater) { sense = 'G'; }
00461
00462 rmatbeg = 0;
00463
00464 double d;
00465 <<<<<<< scil.c
00466
00467 row r;
00468 rc->non_zero_entries(r);
00469
00470
00471
00472 r.normalize();
00473
00474
00475
00476 d=-scil_row_const_part(r);
00477
00478
00479
00480 rmatind=new int[scil_row_size_without_constant(r)];
00481 rmatval=new double[scil_row_size_without_constant(r)];
00482 int nzcnt=0;
00483 row_entry re;
00484 forall(re, r) if(re.Var!=NULL) {
00485 rmatind[nzcnt] = re.Var.getIndex();
00486 rmatval[nzcnt] = re.Coeff;
00487 nzcnt++;
00488 }
00489 =======
00490
00491 row r;
00492 rc->non_zero_entries(r);
00493 r.normalize();
00494 d=scil_row_const_part(r);
00495
00496 rmatind=new int[scil_row_size_without_constant(r)];
00497 rmatval=new double[scil_row_size_without_constant(r)];
00498 int nzcnt=0;
00499 row_entry re;
00500 forall(re, r) if(re.Var!=nil) {
00501 rmatind[nzcnt] = re.Var.getIndex();
00502 rmatval[nzcnt] = re.Coeff;
00503 nzcnt++;
00504 }
00505 >>>>>>> 1.3
00506 rhs+=d;
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 CPXaddrows (((ILP_Problem_Data*) DATA)->m_pCPXEnv,
00521 ((ILP_Problem_Data*) DATA)->m_pCPXLP, 0, 1, nzcnt,
00522 &rhs, &sense, &rmatbeg, rmatind, rmatval, NULL, NULL);
00523
00524 delete rmatind;
00525 delete rmatval;
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538 ((Basic_Constraint_Data*) rc->DATA)->Index =
00539 CPXgetnumrows(((ILP_Problem_Data*) DATA)->m_pCPXEnv, ((ILP_Problem_Data*) DATA)->m_pCPXLP) - 1;
00540
00541
00542 ((Basic_Constraint_Data*) rc->DATA)->m_pILP = this;
00543 return rc;
00544 }
00545
00546 cons ILP_Problem::add_basic_constraint_sub (cons_obj* rc,
00547 Activation a) {
00548 <<<<<<< scil.c
00549
00550 if(((ILP_Problem_Data*) DATA)->rootcall==true) {
00551 =======
00552
00553 if(((ILP_Problem_Data*) DATA)->rootcall==true) {
00554 >>>>>>> 1.3
00555
00556 return add_basic_constraint(rc,a);
00557 };
00558
00559
00560 int rmatbeg;
00561 int *rmatind;
00562 double *rmatval;
00563 double rhs;
00564 char sense;
00565
00566 rhs = rc->rhs();
00567
00568 if (rc->sense() == Equal ) { sense = 'E'; }
00569 if (rc->sense() == Less ) { sense = 'L'; }
00570 if (rc->sense() == Greater) { sense = 'G'; }
00571
00572 rmatbeg = 0;
00573
00574 double d;
00575 <<<<<<< scil.c
00576
00577 row r;
00578 rc->non_zero_entries(r);
00579 r.normalize();
00580 d=scil_row_const_part(r);
00581
00582 rmatind=new int[scil_row_size_without_constant(r)];
00583 rmatval=new double[scil_row_size_without_constant(r)];
00584
00585 int nzcnt=0;
00586 row_entry re;
00587 forall(re, r) if(re.Var!=NULL) {
00588
00589 rmatind[nzcnt] = re.Var.getIndex();
00590 rmatval[nzcnt] = re.Coeff;
00591 nzcnt++;
00592 }
00593 =======
00594
00595 row r;
00596 rc->non_zero_entries(r);
00597 r.normalize();
00598 d=scil_row_const_part(r);
00599
00600 rmatind=new int[scil_row_size_without_constant(r)];
00601 rmatval=new double[scil_row_size_without_constant(r)];
00602 int nzcnt=0;
00603 row_entry re;
00604 forall(re, r) if(re.Var!=nil) {
00605 rmatind[nzcnt] = re.Var.getIndex();
00606 rmatval[nzcnt] = re.Coeff;
00607 nzcnt++;
00608 }
00609 >>>>>>> 1.3
00610 rhs+=d;
00611
00612 <<<<<<< scil.c
00613
00614 =======
00615 CPXcutcallbackadd (((ILP_Problem_Data*) DATA)->m_pCPXEnv,
00616 ((ILP_Problem_Data*) DATA)->cbdata, ((ILP_Problem_Data*) DATA)->wherefrom,
00617 nzcnt, rhs, sense, rmatind, rmatval);
00618 >>>>>>> 1.3
00619
00620 CPXcutcallbackadd (((ILP_Problem_Data*) DATA)->m_pCPXEnv,
00621 ((ILP_Problem_Data*) DATA)->cbdata, ((ILP_Problem_Data*) DATA)->wherefrom,
00622 nzcnt, rhs, sense, rmatind, rmatval);
00623
00624
00625 delete rmatind;
00626 delete rmatval;
00627
00628
00629
00630 ((Basic_Constraint_Data*) rc->DATA)->Index = CPXgetnumrows(((ILP_Problem_Data*) DATA)->m_pCPXEnv, ((ILP_Problem_Data*) DATA)->m_pCPXLP) - 1;
00631
00632
00633 <<<<<<< scil.c
00634 ((Basic_Constraint_Data*) rc->DATA)->m_pILP = this;
00635
00636 =======
00637 ((Basic_Constraint_Data*) rc->DATA)->m_pILP = this;
00638 >>>>>>> 1.3
00639 return rc;
00640 }
00641
00642
00643 void ILP_Problem::optimize() {
00644 cout<< "Init sym constraints\n";
00645
00646 ((ILP_Problem_Data*) DATA)->rootcall=true;
00647
00648 GlobalS->ILP=this;
00649
00650 sym_constraint* s;
00651 forall (s, ((ILP_Problem_Data*) DATA)->SL) {
00652 s->init(*GlobalS);
00653 }
00654
00655 ((ILP_Problem_Data*) DATA)->rootcall=false;
00656 cout << "Optimizing problem" << endl;
00657
00658 ((ILP_Problem_Data*) DATA)->XSOL=new double[((ILP_Problem_Data*) DATA)->m_NumVars];
00659
00660 CPXmipopt (((ILP_Problem_Data*) DATA)->m_pCPXEnv, ((ILP_Problem_Data*) DATA)->m_pCPXLP);
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671 <<<<<<< scil.c
00672 int numcols = CPXgetnumcols(((ILP_Problem_Data*) DATA)->m_pCPXEnv, ((ILP_Problem_Data*) DATA)->m_pCPXLP);
00673 =======
00674 int numcols = CPXgetnumcols(((ILP_Problem_Data*) DATA)->m_pCPXEnv, ((ILP_Problem_Data*) DATA)->m_pCPXLP);
00675 int lpstat;
00676 >>>>>>> 1.3
00677 double objval;
00678
00679 if (((ILP_Problem_Data*) DATA)->m_pSolution) { delete ((ILP_Problem_Data*) DATA)->m_pSolution; }
00680
00681 ((ILP_Problem_Data*) DATA)->m_pSolution = new double[numcols];
00682
00683 cout << "Retrieving solution" << endl;
00684 CPXgetmipx (((ILP_Problem_Data*) DATA)->m_pCPXEnv,
00685 ((ILP_Problem_Data*) DATA)->m_pCPXLP,
00686 ((ILP_Problem_Data*) DATA)->m_pSolution, 0,
00687 numcols-1);
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698 CPXgetmipobjval (((ILP_Problem_Data*) DATA)->m_pCPXEnv, ((ILP_Problem_Data*) DATA)->m_pCPXLP, &objval);
00699
00700 ((ILP_Problem_Data*) DATA)->m_GotSolution = 1;
00701 cout << "Solution status: " << CPXgetstat(((ILP_Problem_Data*) DATA)->m_pCPXEnv, ((ILP_Problem_Data*) DATA)->m_pCPXLP) << endl << "Objective value: " << objval << endl;
00702 }
00703
00704 double ILP_Problem::get_solution (const var& v) {
00705 if (!((ILP_Problem_Data*) DATA)->m_GotSolution) { return 0; }
00706
00707
00708
00709
00710 <<<<<<< scil.c
00711 if(v==NULL) return 1;
00712 return ((ILP_Problem_Data*) DATA)->m_pSolution[v.getIndex()];
00713 =======
00714 if(v==nil) return 1;
00715 return ((ILP_Problem_Data*) DATA)->m_pSolution[v.getIndex()];
00716 >>>>>>> 1.3
00717 }
00718
00719 double ILP_Problem::get_solution(const row& r) {
00720 row_entry re;
00721 double d=0;
00722 forall(re, r) {
00723 d+=re.Coeff*get_solution(re.Var);
00724 };
00725 return d;
00726 };
00727
00728 <<<<<<< scil.c
00729
00730 double subproblem::value (const var& v) {
00731 if(v==NULL) return 1;
00732 =======
00733
00734 double subproblem::value (const var& v) {
00735 if(v==nil) return 1;
00736 >>>>>>> 1.3
00737
00738 return ((ILP_Problem_Data*) ILP->DATA)->XSOL[v.getIndex()];
00739 }
00740
00741 double subproblem::value(const row& r) {
00742 row_entry re;
00743 double d=0;
00744 forall(re, r) {
00745 d+=re.Coeff*value(re.Var);
00746 };
00747 return d;
00748 };
00749
00750 <<<<<<< scil.c
00751 int ILP_Problem::number_of_variables() {
00752 return ((ILP_Problem_Data*) DATA)->m_NumVars;
00753 };
00754
00755 =======
00756 int ILP_Problem::number_of_variables() {
00757 return ((ILP_Problem_Data*) DATA)->m_NumVars;
00758 };
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803 >>>>>>> 1.3
00804
00805
00806
00807
00808
00809
00810
00811
00812 bool var::operator== (const var& v) const {
00813 if ((m_pVarObj == NULL) || (v.m_pVarObj == NULL)) {
00814 return m_pVarObj == v.m_pVarObj;
00815 }
00816 return (((Variable_Data*) m_pVarObj->DATA)->Index == ((Variable_Data*) v.m_pVarObj->DATA)->Index)
00817 && (((Variable_Data*) m_pVarObj->DATA)->m_pILP == ((Variable_Data*) v.m_pVarObj->DATA)->m_pILP);
00818 }
00819
00820 row var::operator+ (const row& r) const {
00821 return row(*this)+r;
00822 }
00823
00824 row var::operator- (const row& r) const {
00825 return row(*this)-r;
00826 }
00827
00828 row var::operator* (double d) const {
00829 return row(*this)*d;
00830 }
00831
00832 bool var::operator!= (const var& v) const {
00833 return !operator==(v);
00834 }
00835
00836 bool var::operator< (const var& v) const {
00837 if (m_pVarObj == NULL) {
00838 return v.m_pVarObj != NULL;
00839 }
00840 if (v.m_pVarObj == NULL) {
00841 return false;
00842 }
00843 return ((Variable_Data*) m_pVarObj->DATA)->Index < ((Variable_Data*) v.m_pVarObj->DATA)->Index;
00844 }
00845
00846 bool var::operator> (const var& v) const {
00847 if (v.m_pVarObj == NULL) {
00848 return m_pVarObj != NULL;
00849 }
00850 if (m_pVarObj == NULL) {
00851 return false;
00852 }
00853 return ((Variable_Data*) m_pVarObj->DATA)->Index > ((Variable_Data*) v.m_pVarObj->DATA)->Index;
00854 }
00855
00856 bool var::operator<= (const var& v) const {
00857 if (m_pVarObj == NULL) {
00858 return true;
00859 }
00860 if (v.m_pVarObj == NULL) {
00861 return false;
00862 }
00863 return ((Variable_Data*) m_pVarObj->DATA)->Index <= ((Variable_Data*) v.m_pVarObj->DATA)->Index;
00864 }
00865
00866 bool var::operator>= (const var& v) const {
00867 if (v.m_pVarObj == NULL) {
00868 return true;
00869 }
00870 if (m_pVarObj == NULL) {
00871 return false;
00872 }
00873 return ((Variable_Data*) m_pVarObj->DATA)->Index >= ((Variable_Data*) v.m_pVarObj->DATA)->Index;
00874 }
00875
00876 int SCIL::compare(const var& t1, const var& t2) {
00877 if (t1<t2) return -1;
00878 if (t1>t2) return 1;
00879 return 0;
00880 }
00881
00882 row SCIL::operator* (double d, var v) {
00883 return row(v)*d;
00884 }
00885
00886
00887
00888
00889
00890 row_entry::row_entry(var v, double d) {
00891 Var = v;
00892 Coeff = d;
00893 }
00894
00895 int SCIL::compare(const row_entry& t1, const row_entry& t2) {
00896 return compare(t1.Var, t2.Var);
00897 }
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911 row row::operator* (double d) const {
00912 row_entry it;
00913 list<row_entry> newNZ;
00914
00915 forall(it, NZ) {
00916 newNZ.append(row_entry(it.Var, d*it.Coeff));
00917 }
00918
00919
00920 return row(newNZ);
00921 }
00922
00923 int row::size() {
00924 return NZ.size();
00925 };
00926
00927 row SCIL::operator* (double d, row r) {
00928 return r*d;
00929 }
00930
00931 row row::operator+ (double d) const {
00932 return operator+(row(d));
00933 }
00934
00935
00936
00937
00938
00939
00940
00941 row row::operator+ (const var& v) const {
00942 return operator+(row(v));
00943 }
00944
00945 row row::operator+ (const row& r) const {
00946 list<row_entry> newNZ;
00947 list_item item = r.first_item();
00948 row_entry re;
00949 double d;
00950
00951 forall(re, NZ) {
00952 d = 0;
00953 <<<<<<< scil.c
00954 while ((item != NULL) && (!(r.NZ[item].Var > re.Var))) {
00955 if (r.NZ[item].Var != re.Var) {
00956
00957 newNZ.append(r.NZ[item]);
00958 =======
00959 while ((item != NULL) && (!(r.NZ[item].Var > re.Var))) {
00960 if (r.NZ[item].Var != re.Var) {
00961 newNZ.append(r.NZ[item]);
00962 >>>>>>> 1.3
00963 } else {
00964 d = r.NZ[item].Coeff;
00965 }
00966 item = r.NZ.succ(item);
00967 }
00968 <<<<<<< scil.c
00969
00970 newNZ.append(row_entry(re.Var, re.Coeff + d));
00971 =======
00972 newNZ.append(row_entry(re.Var, re.Coeff + d));
00973 >>>>>>> 1.3
00974 }
00975
00976 while (item != NULL) {
00977 newNZ.append(r.NZ[item]);
00978 item = r.NZ.succ(item);
00979 }
00980 return row(newNZ);
00981 }
00982
00983 row row::operator- (const row& r) const {
00984 return operator+((-1)*r);
00985 }
00986
00987 void row::normalize() {
00988 int count, len;
00989 NZ.sort();
00990 list_item li;
00991 count = 1;
00992 forall_items (li, NZ) {
00993 while ((count < NZ.length()) &&
00994 (NZ[li].Var == NZ[NZ.succ(li)].Var)) {
00995 NZ[li].Coeff += NZ[NZ.succ(li)].Coeff;
00996 len = NZ.length();
00997 NZ.del_item(NZ.succ(li));
00998 if (len == NZ.length()) {
00999 cout << "row::normalize error: list does not shrink - this should never happen" << endl;
01000 NZ[NZ.succ(li)].Var = NULL;
01001 }
01002 }
01003 count++;
01004 }
01005
01006
01007
01008
01009
01010 }
01011
01012 cons_obj* row::operator== (const row& r1) const {
01013 row r2=(*this)-r1;
01014
01015 return new row_constraint(r2, Equal);
01016 }
01017
01018 cons_obj* row::operator<= (const row& r1) const {
01019 row r2=(*this)-r1;
01020
01021 return new row_constraint(r2, Less);
01022 }
01023
01024 cons_obj* row::operator>= (const row& r1) const {
01025 row r2=(*this)-r1;
01026
01027 return new row_constraint(r2, Greater);
01028 }
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050 ostream& SCIL::operator<<(ostream& o,const row& r) {
01051 list_item li;
01052
01053 li = r.first_item();
01054 while (li) {
01055 o << r.inf(li);
01056 li = r.next_item(li);
01057 if (li) { o << ","; }
01058 }
01059 return o<<"\n";
01060 }
01061
01062 int SCIL::Hash(var v) {
01063 return LEDA::Hash(v.m_pVarObj);
01064 }
01065
01066 int SCIL::ID_Number(const var & v) {
01067 return LEDA::ID_Number(v.m_pVarObj);
01068 }
01069
01070 row& row::operator+= (const row& r) {
01071 row_entry st;
01072 forall(st, r.NZ) {
01073 NZ.append(st);
01074 }
01075 return *this;
01076 }
01077
01078 <<<<<<< scil.c
01079 row& row::operator+= (const row_entry& re) {
01080 NZ.append(re);
01081 return *this;
01082 }
01083
01084
01085 row::row(double d) {
01086
01087 NZ.append(row_entry(NULL, d));
01088 }
01089
01090 row::row(var v) {
01091 NZ.append(row_entry(v,1));
01092 }
01093
01094 row::row(list<row_entry>& L) {
01095 NZ=L;
01096
01097
01098
01099
01100
01101 }
01102
01103 =======
01104 row& row::operator+= (const row_entry& re) {
01105 NZ.append(re);
01106 return *this;
01107 }
01108
01109
01110 row::row(double d) {
01111
01112 NZ.append(row_entry(nil, d));
01113 }
01114
01115 row::row(var v) {
01116 NZ.append(row_entry(v,1));
01117 }
01118
01119 row::row(list<row_entry>& L) {
01120 NZ=L;
01121 }
01122
01123 >>>>>>> 1.3
01124 row& row::operator-= (const row& r) {
01125 row_entry st;
01126 <<<<<<< scil.c
01127 forall(st, r.NZ) {
01128 NZ.append(row_entry(st.Var, -st.Coeff));
01129
01130 =======
01131 forall(st, r.NZ) {
01132 NZ.append(row_entry(st.Var, -st.Coeff));
01133 >>>>>>> 1.3
01134 }
01135 return *this;
01136 }
01137
01138 var subproblem::add_continous_variable(double d1, double d2, double d3, Activation) {
01139 cout<<"ERROR\n";
01140 return NULL;
01141 };
01142
01143 var subproblem::add_integer_variable(double, int, int, Activation) {
01144 cout<<"ERROR\n";
01145 return NULL;
01146 };
01147
01148 var subproblem::add_binary_variable(double, Activation) {
01149 cout<<"ERROR\n";
01150 return NULL;
01151 };
01152
01153 var subproblem::add_variable(var_obj*, Activation) {
01154 cout<<"ERROR\n";
01155 return NULL;
01156 };
01157
01158 var subproblem::add_variable(double, double, double, Vartype, Activation) {
01159 cout<<"ERROR\n";
01160 return NULL;
01161 };
01162
01163 cons subproblem::add_basic_constraint(cons_sense c, double r, Activation a) {
01164 return ILP->add_basic_constraint_sub(new cons_obj(c,r), a);
01165 };
01166
01167
01168 cons subproblem::add_basic_constraint(cons_obj* c, Activation a) {
01169 return ILP->add_basic_constraint_sub(c, a);
01170 };
01171
01172 double subproblem::get_solution(const var& v) {
01173 return ILP->get_solution(v);
01174 };
01175
01176 double subproblem::get_solution(const row& r) {
01177 return ILP->get_solution(r);
01178 };
01179
01180 void subproblem::add_sym_constraint(sym_constraint* sc) {
01181 ILP->add_sym_constraint(sc);
01182 };
01183
01184 subproblem::~subproblem() {
01185 };
01186
01187 double subproblem::value(cons) {
01188 cout<<"ERROR\n";
01189 return 0;
01190 };
01191
01192 bool subproblem::found_constraint() {
01193 cout<<"ERROR\n";
01194 return false;
01195 };
01196
01197 double subproblem::get_obj_value() {
01198 cout<<"ERROR\n";
01199 return 0;
01200 };
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241 void subproblem::save_solution(solution& s) {
01242 <<<<<<< scil.c
01243 ILP->save_solution(s);
01244 };
01245
01246 cons_obj::cons_obj() {
01247 DATA=new Basic_Constraint_Data;
01248 ((Basic_Constraint_Data*) DATA)->Index=-1;
01249 ((Basic_Constraint_Data*) DATA)->m_pILP=NULL;
01250 };
01251
01252 cons_obj::cons_obj(cons_sense s, double rhs) {
01253 DATA=new Basic_Constraint_Data;
01254 m_rhs = rhs;
01255 m_sense = s;
01256 ((Basic_Constraint_Data*) DATA)->Index=-1;
01257 ((Basic_Constraint_Data*) DATA)->m_pILP=NULL;
01258 };
01259
01260 cons_obj::~cons_obj() {
01261 delete (Basic_Constraint_Data*) DATA;
01262 }
01263
01264 void ILP_Problem::add_sym_constraint(sym_constraint* c) {
01265 ((ILP_Problem_Data*) DATA)->SL.append(c);
01266 };
01267
01268 void ILP_Problem::save_solution(solution& s) {
01269 ((ILP_Problem_Data*) DATA)->heur_sol=s;
01270 ((ILP_Problem_Data*) DATA)->heur_obj=1;
01271 };
01272
01273
01274 var_obj::var_obj() {
01275 DATA=new Variable_Data;
01276 ((Variable_Data*) DATA)->Index = -1;
01277 ((Variable_Data*) DATA)->m_pILP = NULL;
01278 objVal = 0;
01279 lBound = 0;
01280 uBound = 0;
01281 vt = Vartype_Integer;
01282 }
01283
01284 var_obj::var_obj(double obj, double lBound_, double uBound_, Vartype vt_) {
01285 DATA=new Variable_Data;
01286 ((Variable_Data*) DATA)->Index = -1;
01287 ((Variable_Data*) DATA)->m_pILP = NULL;
01288 objVal = obj;
01289 lBound = lBound_;
01290 uBound = uBound_;
01291 vt = vt_;
01292 }
01293
01294 var_obj::~var_obj() {
01295 delete (Variable_Data*) DATA;
01296 };
01297
01298 double var_obj::obj() const {
01299 return objVal;
01300 };
01301
01302 double var_obj::lower_bound() const {
01303 return lBound;
01304 };
01305
01306 double var_obj::upper_bound() const {
01307 return uBound;
01308 };
01309
01310 Vartype var_obj::type() const {
01311 return vt;
01312 };
01313
01314 int var_obj::getIndex() const {
01315 return ((Variable_Data*) DATA)->Index;
01316 }
01317
01318 void solution::save_solution(subproblem& s) {
01319 var v;
01320 sp=&s;
01321 forall_variables(v, s) {
01322 if(s.value(v)!=0) {
01323 S[v]=s.value(v);
01324 }
01325 }
01326 };
01327
01328 subproblem* solution::originating_subproblem() {
01329 return sp;
01330 };
01331
01332 void solution::round_to_integer(var v) {
01333 S[v]=floor(S[v]+0.5);
01334 };
01335
01336 double solution::value(var v) {
01337 return S[v];
01338 };
01339
01340 double solution::value(row& r) {
01341 row_entry re;
01342 double d=0;
01343 forall(re, r) d+=re.Coeff*value(re.Var);
01344 return d;
01345 };
01346
01347 subproblem::subproblem(ILP_Problem*) {};
01348
01349 LEDA::list_item row::first_item() const {
01350 return NZ.first();
01351 }
01352
01353 LEDA::list_item row::next_item(const LEDA::list_item item) const {
01354 return NZ.succ(item);
01355 }
01356
01357 row_entry row::inf(const LEDA::list_item item) const {
01358 return NZ.inf(item);
01359 }
01360
01361 row_constraint::row_constraint (row& r, cons_sense s) :
01362 NZV(r.size()), NZC(r.size()) {
01363
01364 row_entry re;
01365 int idx = 0;
01366
01367 forall (re, r.NZ) {
01368 NZV[idx] = re.Var;
01369 NZC[idx] = re.Coeff;
01370 idx++;
01371
01372 }
01373
01374 set_sense(s);
01375 set_rhs(0);
01376 }
01377
01378 double row_constraint::rhs() {
01379 if (NZV[0] == NULL) return -NZC[0];
01380 return 0;
01381 }
01382
01383 void row_constraint::non_zero_entries(row& r)
01384 {
01385 for(int i=0; i<=NZC.high(); i++) {
01386
01387 r+=row_entry(NZV[i],NZC[i]);
01388 }
01389 }
01390
01391 row_constraint::~row_constraint() {
01392 };
01393
01394 ostream& SCIL::operator<<(ostream& o,const row_entry& re) {
01395 return o<<"("<<re.Var<<","<<re.Coeff<<")";
01396 }
01397
01398 istream& SCIL::operator>>(istream& i,const row_entry&) { return i; };
01399
01400 ostream& SCIL::operator<<(ostream& o,const column_entry&) { return o; };
01401
01402 istream& SCIL::operator>>(istream& i,const column_entry&) { return i; };
01403
01404
01405
01406 subproblem::var_item subproblem::first_variable_item() {
01407 cout<<"ERROR\n";
01408 return 0;
01409 };
01410
01411 subproblem::var_item subproblem::next_variable_item(var_item) {
01412 cout<<"ERROR\n";
01413 return 0;
01414 };
01415
01416 var subproblem::get_variable(var_item) {
01417 cout<<"ERROR\n";
01418 return NULL;
01419 };
01420
01421 subproblem::sc_item subproblem::first_sym_constraint_item() {
01422 cout<<"ERROR\n";
01423 return 0;
01424 };
01425
01426 subproblem::sc_item subproblem::next_sym_constraint_item(sc_item) {
01427 cout<<"ERROR\n";
01428 return 0;
01429 };
01430
01431 sym_constraint* subproblem::get_sym_constraint(sc_item) {
01432 cout<<"ERROR\n";
01433 return NULL;
01434 };
01435
01436 double cons_obj::slack(subproblem& s) {
01437 row r;
01438 non_zero_entries(r);
01439 row_entry re;
01440 double d=rhs();
01441 forall(re,r) {
01442 d-=re.Coeff*s.value(re.Var);
01443 };
01444 if(sense()==Equal) return fabs(d);
01445 if(sense()==Less) return -d;
01446 return d;
01447 =======
01448 ILP->save_solution(s);
01449 };
01450
01451 cons_obj::cons_obj() {
01452 DATA=new Basic_Constraint_Data;
01453 ((Basic_Constraint_Data*) DATA)->Index=-1;
01454 ((Basic_Constraint_Data*) DATA)->m_pILP=NULL;
01455 };
01456
01457 cons_obj::cons_obj(cons_sense s, double rhs) {
01458 DATA=new Basic_Constraint_Data;
01459 m_rhs = rhs;
01460 m_sense = s;
01461 ((Basic_Constraint_Data*) DATA)->Index=-1;
01462 ((Basic_Constraint_Data*) DATA)->m_pILP=NULL;
01463 };
01464
01465 cons_obj::~cons_obj() {
01466 delete (Basic_Constraint_Data*) DATA;
01467 }
01468
01469 void ILP_Problem::add_sym_constraint(sym_constraint* c) {
01470 ((ILP_Problem_Data*) DATA)->SL.append(c);
01471 };
01472
01473 void ILP_Problem::save_solution(solution& s) {
01474 ((ILP_Problem_Data*) DATA)->heur_sol=s;
01475 ((ILP_Problem_Data*) DATA)->heur_obj=1;
01476 };
01477
01478
01479 var_obj::var_obj() {
01480 DATA=new Variable_Data;
01481 ((Variable_Data*) DATA)->Index = -1;
01482 ((Variable_Data*) DATA)->m_pILP = NULL;
01483 objVal = 0;
01484 lBound = 0;
01485 uBound = 0;
01486 vt = Vartype_Integer;
01487 }
01488
01489 var_obj::var_obj(double obj, double lBound, double uBound, Vartype vt_) {
01490 DATA=new Variable_Data;
01491 ((Variable_Data*) DATA)->Index = -1;
01492 ((Variable_Data*) DATA)->m_pILP = NULL;
01493 objVal = obj;
01494 lBound = lBound;
01495 uBound = uBound;
01496 vt = vt_;
01497 }
01498
01499 var_obj::~var_obj() {
01500 delete (Variable_Data*) DATA;
01501 };
01502
01503 double var_obj::obj() const {
01504 return objVal;
01505 };
01506
01507 double var_obj::lower_bound() const {
01508 return lBound;
01509 };
01510
01511 double var_obj::upper_bound() const {
01512 return uBound;
01513 };
01514
01515 Vartype var_obj::type() const {
01516 return vt;
01517 };
01518
01519 int var_obj::getIndex() const {
01520 return ((Variable_Data*) DATA)->Index;
01521 }
01522
01523 void solution::save_solution(subproblem& s) {
01524 var v;
01525 sp=&s;
01526 forall_variables(v, s) {
01527 if(s.value(v)!=0) {
01528 S[v]=s.value(v);
01529 }
01530 }
01531 };
01532
01533 subproblem* solution::originating_subproblem() {
01534 return sp;
01535 };
01536
01537 void solution::round_to_integer(var v) {
01538 S[v]=floor(S[v]+0.5);
01539 };
01540
01541 double solution::value(var v) {
01542 return S[v];
01543 };
01544
01545 double solution::value(row& r) {
01546 row_entry re;
01547 double d=0;
01548 forall(re, r) d+=re.Coeff*value(re.Var);
01549 return d;
01550 };
01551
01552 subproblem::subproblem(ILP_Problem*) {};
01553
01554 LEDA::list_item row::first_item() const {
01555 return NZ.first();
01556 }
01557
01558 LEDA::list_item row::next_item(const LEDA::list_item item) const {
01559 return NZ.succ(item);
01560 }
01561
01562 row_entry row::inf(const LEDA::list_item item) const {
01563 return NZ.inf(item);
01564 }
01565
01566 row_constraint::row_constraint (row& r, cons_sense s) :
01567 NZV(r.size()), NZC(r.size()) {
01568
01569 row_entry re;
01570 int idx = 0;
01571
01572 forall (re, r.NZ) {
01573 NZV[idx] = re.Var;
01574 NZC[idx] = re.Coeff;
01575 idx++;
01576 }
01577 set_sense(s);
01578 set_rhs(0);
01579 }
01580
01581 double row_constraint::rhs() {
01582 if (NZV[0] == nil) return -NZC[0];
01583 return 0;
01584 }
01585
01586 void row_constraint::non_zero_entries(row& r)
01587 {
01588 for(int i=0; i<=NZC.high(); i++) {
01589 if(NZV[i]!=nil) r+=row_entry(NZV[i],NZC[i]);
01590 }
01591 }
01592
01593 row_constraint::~row_constraint() {
01594 };
01595
01596 ostream& SCIL::operator<<(ostream& o,const row_entry& re) {
01597 return o<<"("<<re.Var<<","<<re.Coeff<<")";
01598 }
01599
01600 istream& SCIL::operator>>(istream& i,const row_entry&) { return i; };
01601
01602 ostream& SCIL::operator<<(ostream& o,const column_entry&) { return o; };
01603
01604 istream& SCIL::operator>>(istream& i,const column_entry&) { return i; };
01605
01606
01607
01608 subproblem::var_item subproblem::first_variable_item() {
01609 };
01610
01611 subproblem::var_item subproblem::next_variable_item(var_item) {
01612 };
01613
01614 var subproblem::get_variable(var_item) {
01615 };
01616
01617 subproblem::sc_item subproblem::first_sym_constraint_item() {
01618 };
01619
01620 subproblem::sc_item subproblem::next_sym_constraint_item(sc_item) {
01621 };
01622
01623 sym_constraint* subproblem::get_sym_constraint(sc_item) {
01624 };
01625
01626 double cons_obj::slack(subproblem& s) {
01627 row r;
01628 non_zero_entries(r);
01629 row_entry re;
01630 double d=rhs();
01631 forall(re,r) {
01632 d-=re.Coeff*s.value(re.Var);
01633 };
01634 if(sense()==Equal) return fabs(d);
01635 if(sense()==Less) return -d;
01636 return d;
01637 >>>>>>> 1.3
01638 };
01639
01640 #endif // SCIL_CPP