00001 #line 2 "tpp.lw"
00002 #include<LEDA/graph.h>
00003 #include<scil/scil.h>
00004 #include<scil/constraints/tour.h>
00005
00006 using namespace SCIL;
00007 using namespace LEDA;
00008 using namespace std;
00009
00010 //#include"cp_cuts.h"
00011
00012 /*
00013 class rrt : public cp_sym_constraint {
00014 private:
00015 var**** V;
00016 int n;
00017
00018 public:
00019 rrt(int n_, var**** V_) {
00020 V=V_;
00021 n=n_;
00022 }
00023
00024 virtual
00025 void infer(infer_status& is) {
00026 // cout<<"trying to infer\n";
00027
00028 list<var> dummy; // TODO use it!
00029 var one_fixed_i, one_fixed_o;
00030
00031 int nv[n];
00032 list<var> nvn[n];
00033
00034 for(int i=0; i<n; i++) { // Test for Tours
00035 for(int j=0; j<n; j++) nv[j]=0;
00036 for(int l=0; l<2*n-3; l++) { // For every time step but last
00037 int lb_tci=0, ub_tci=0, lb_tco=0, ub_tco=0;
00038 int lb_nci, ub_nci, lb_nco, ub_nco;
00039 for(int j=0; j<n; j++) {
00040 lb_nci=0; ub_nci=0; lb_nco=0; ub_nco=0;
00041
00042 // count node degrees
00043 for(int k=0; k<n; k++) {
00044 lb_nci+=is.lower_bound(V[i][k][j][l]);
00045 ub_nci+=is.upper_bound(V[i][k][j][l]);
00046 if(lb_nci+lb_tco>1) {
00047 dummy.append(V[i][k][j][l]);
00048 dummy.append(one_fixed_i);
00049 is.unsolvable(dummy);
00050 dummy.clear();
00051 return;
00052 };
00053 if(is.one_fixed(V[i][k][j][l])) {
00054 one_fixed_i=V[i][k][j][l];
00055 nv[j]++;
00056 nvn[j].append(V[i][k][j][l]);
00057 };
00058 lb_nco+=is.lower_bound(V[i][j][k][l+1]);
00059 ub_nco+=is.upper_bound(V[i][j][k][l+1]);
00060 if(lb_nco+lb_tco>1) {
00061 dummy.append(V[i][j][k][l+1]);
00062 dummy.append(one_fixed_o);
00063 is.unsolvable(dummy);
00064 dummy.clear();
00065 return;
00066 };
00067 if(is.one_fixed(V[i][j][k][l+1])) one_fixed_o=V[i][j][k][l+1];
00068 }
00069
00070 if(lb_nci==1) {
00071 // if one incoming is fixed to one:
00072 // fix all other incoming in column to 0
00073 // fix all outgoing edges of other nodes to 0
00074 dummy.append(one_fixed_i);
00075 for(int j1=0; j1<n; j1++)
00076 for(int k=0; k<n; k++) {
00077 if(!is.fixed(V[i][k][j1][l])) {
00078 is.fix(V[i][k][j1][l], 0, dummy);
00079 };
00080 if((j1!=j) && (!is.fixed(V[i][j1][k][l+1]))) {
00081 is.fix(V[i][j1][k][l+1], 0, dummy);
00082 };
00083 }
00084
00085 if((ub_nco<=1) && (lb_nco==0)) {
00086 var unfixed;
00087 for(int k=0; k<n; k++)
00088 if(is.fixed(V[i][j][k][l+1])) {
00089 dummy.append(V[i][j][k][l+1]);
00090 } else {
00091 unfixed=V[i][j][k][l+1];
00092 }
00093 if(ub_nco==0) {
00094 is.unsolvable(dummy);
00095 return;
00096 }
00097 is.fix(unfixed, 1, dummy);
00098 ub_nco=1; lb_nco=1;
00099 };
00100
00101 dummy.clear();
00102 };
00103
00104 if(lb_nco==1) {
00105 // analog above
00106 dummy.append(one_fixed_o);
00107 for(int j1=0; j1<n; j1++)
00108 for(int k=0; k<n; k++) {
00109 if(!is.fixed(V[i][j1][k][l+1])) {
00110 is.fix(V[i][j1][k][l+1], 0, dummy);
00111 };
00112 if((j1!=j) && (!is.fixed(V[i][k][j1][l]))) {
00113 is.fix(V[i][k][j1][l],0, dummy);
00114 }
00115 }
00116
00117 if((ub_nci<=1) && (lb_nci==0)) {
00118 var unfixed;
00119 for(int k=0; k<n; k++)
00120 if(is.fixed(V[i][k][j][l])) {
00121 dummy.append(V[i][k][j][l]);
00122 } else {
00123 unfixed=V[i][k][j][l];
00124 }
00125 if(ub_nci==0) {
00126 is.unsolvable(dummy);
00127 return;
00128 }
00129 is.fix(unfixed, 1, dummy);
00130 lb_nci=1; ub_nci=1;
00131 };
00132 dummy.clear();
00133 };
00134
00135 if((lb_nci==1) && (ub_nco==1) && (lb_nco==0)) {
00136 // if one incoming edge and only one outgoing edge left: fix it
00137 var unfixed;
00138 dummy.append(one_fixed_i);
00139 for(int k=0; k<n; k++)
00140 if(!is.fixed(V[i][j][k][l+1])) {
00141 unfixed=V[i][j][k][l+1];
00142 } else dummy.append(V[i][j][k][l+1]);
00143
00144 is.fix(unfixed, 1, dummy);
00145 dummy.clear();
00146 };
00147 if((lb_nco==1) && (ub_nci==1) && (lb_nci==0)) {
00148 // as above
00149 var unfixed;
00150 dummy.append(one_fixed_o);
00151 for(int k=0; k<n; k++)
00152 if(!is.fixed(V[i][k][j][l])) {
00153 unfixed=V[i][k][j][l];
00154 } else dummy.append(V[i][k][j][l]);
00155 is.fix(unfixed, 1, dummy);
00156 dummy.clear();
00157 };
00158
00159 if((ub_nci==0) && (ub_nco!=0)) {
00160 // if indegree is 0 outdegree is 0
00161 for(int k=0; k<n; k++) {
00162 dummy.append(V[i][k][j][l]);
00163 };
00164 for(int k=0; k<n; k++) if(!is.fixed(V[i][j][k][l+1])) {
00165 is.fix(V[i][j][k][l+1], 0, dummy);
00166 };
00167 dummy.clear();
00168 };
00169
00170 if((ub_nco==0) && (ub_nci!=0)) {
00171 // if outdegree is 0 indegree is 0
00172 for(int k=0; k<n; k++) {
00173 dummy.append(V[i][j][k][l+1]);
00174 };
00175 for(int k=0; k<n; k++) if(!is.fixed(V[i][k][j][l])) {
00176 is.fix(V[i][k][j][l], 0, dummy);
00177 };
00178 dummy.clear();
00179 };
00180
00181
00182
00183 // add to total degrees
00184 lb_tci+=lb_nci;
00185 ub_tci+=ub_nci;
00186 lb_tco+=lb_nco;
00187 ub_tco+=ub_nco;
00188 };
00189
00190 // infer on total degrees
00191 if(ub_tci==0) {
00192 is.unsolvable(dummy);
00193 cout<<"not implemented jet 1\n";
00194 return;
00195 };
00196 if (ub_tco==0) {
00197 is.unsolvable(dummy);
00198 cout<<"not implemented jet 2\n";
00199 return;
00200 }
00201 if((ub_tci==1) && (lb_tci==0)) {
00202 // only one in column left
00203 cout<<"one in column left\n";
00204 var unfixed;
00205 for(int j=0; j<n; j++)
00206 for(int k=0; k<n; k++)
00207 if(is.fixed(V[i][k][j][l])) {
00208 dummy.append(V[i][k][j][l]);
00209 } else unfixed=V[i][k][j][l];
00210
00211 is.fix(unfixed, 1, dummy);
00212 dummy.clear();
00213 };
00214
00215 if((ub_tco==1) && (lb_tco==0)) {
00216 // only one in column left
00217 var unfixed;
00218 for(int j=0; j<n; j++)
00219 for(int k=0; k<n; k++)
00220 if(is.fixed(V[i][j][k][l+1])) {
00221 dummy.append(V[i][j][k][l+1]);
00222 } else unfixed=V[i][j][k][l+1];
00223 is.fix(unfixed, 1, dummy);
00224 };
00225 }
00226 for(int j=0; j<n; j++) {
00227 if((i!=j) && (nv[j]>1)) {
00228 var v;
00229 forall(v, nvn[j]) dummy.append(v);
00230 is.unsolvable(dummy);
00231 dummy.clear();
00232 return;
00233 }
00234 if((i==j) && (nv[j]>n-1)) {
00235 var v;
00236 forall(v, nvn[j]) dummy.append(v);
00237 is.unsolvable(dummy);
00238 return;
00239 }
00240 }
00241 };
00242 };
00243 };
00244 */
00245
00246 int main() {
00247
00248 int n, U;
00249
00250 ifstream is("data.txt");
00251
00252 is>>n;
00253 is>>U;
00254 cout<<n<<" cities\n";
00255 cout<<U<<" succesive\n";
00256
00257 int D[n][n];
00258
00259 for(int i=0; i<n; i++) {
00260 for(int j=0; j<n; j++) {
00261 is>>D[i][j];
00262 cout<<D[i][j]<<" ";
00263 }
00264 cout<<endl;
00265 }
00266
00267 ILP_Problem IP(Optsense_Min);
00268
00269 //cp_cuts* CPC=new cp_cuts;
00270 cons c;
00271
00272 var**** V;
00273 V=new var***[n];
00274 for(int i=0; i<n; i++) {
00275 V[i]=new var**[n];
00276 for(int j=0; j<n; j++) {
00277 V[i][j]=new var*[n];
00278 for(int k=0; k<n; k++) {
00279 V[i][j][k]=new var[2*n-2];
00280 }
00281 }
00282 };
00283
00284 int jj, kk;
00285 for(int i=0; i<n; i++) {
00286 for(int j=0; j<n; j++) {
00287 for(int k=0; k<n; k++) {
00288 for(int l=0; l<2*n-2; l++) {
00289 jj=1; if((l==0) && (i!=j)) jj=0; // If l=0, start from home
00290 if((k==j) && (i!=j)) jj=0; // No edges from j to j for i
00291 kk=0; if(l==2*n-3) {
00292 kk=D[k][i];
00293 }
00294 V[i][j][k][l]=IP.add_variable(D[j][k]+kk,0,jj,Vartype_Integer);
00295 }
00296 }
00297 }
00298 }
00299
00300 // is home of i = sum j drives to i
00301 for(int i=0; i<n; i++) {
00302 for(int l=0; l<2*n-2; l++) {
00303 row r;
00304 for(int j=0; j<n; j++) {
00305 for(int k=0; k<n; k++) if(k!=i) {
00306 r+=(row) V[k][j][i][l];
00307 }
00308 r-=(row) V[i][j][i][l];
00309 }
00310 c=IP.add_basic_constraint(r==0);
00311 //CPC->add_sym_constraint(new cp_basic_constraint(c));
00312 }
00313 };
00314
00315 // i visits k exactly once
00316 for(int i=0; i<n; i++) {
00317 for(int k=0; k<n; k++) if(k!=i) {
00318 row r;
00319 for(int j=0; j<n; j++) {
00320 for(int l=0; l<2*n-2; l++) {
00321 r+=(row) V[i][j][k][l];
00322 }
00323 }
00324 c=IP.add_basic_constraint(r==1);
00325 //CPC->add_sym_constraint(new cp_basic_constraint(c));
00326 }
00327 }
00328
00329 // inflow = outflow
00330 for(int i=0; i<n; i++) {
00331 for(int j=0; j<n; j++) {
00332 for(int l=1; l<2*n-2; l++) {
00333 row r;
00334 for(int k=0; k<n; k++) {
00335 r+=(row) V[i][j][k][l];
00336 };
00337 for(int k=0; k<n; k++) {
00338 r-=(row) V[i][k][j][l-1];
00339 };
00340 c=IP.add_basic_constraint(r==0);
00341 //CPC->add_sym_constraint(new cp_basic_constraint(c));
00342 }
00343 }
00344 }
00345
00346 // every flow is one
00347 for(int i=0; i<n; i++) {
00348 row r;
00349 for(int j=0; j<n; j++) {
00350 for(int k=0; k<n; k++) {
00351 r+=(row) V[i][j][k][0];
00352 }
00353 }
00354 c=IP.add_basic_constraint(r==1);
00355 //CPC->add_sym_constraint(new cp_basic_constraint(c));
00356 };
00357 // in the first U+1 steps everyone leaves home
00358 for(int i=0; i<n; i++) {
00359 row r;
00360 for(int j=0; j<n; j++) if(j!=i) {
00361 for(int l=0; l<U+1; l++) {
00362 r+=(row) V[i][i][j][l];
00363 }
00364 };
00365 c=IP.add_basic_constraint(r>=1);
00366 //CPC->add_sym_constraint(new cp_basic_constraint(c));
00367 };
00368 /*
00369 // in every interval of length 2U everyone leaves home and everyone comes home
00370 for(int l=1; l<2*n-2-2*U+1; l++) {
00371 for(int i=0; i<n; i++) {
00372 row R, R1;
00373 for(int l1=0; l1<2*U; l1++) {
00374 for(int k=0; k<n; k++) if(k!=i) {
00375 R+=(row) V[i][i][k][l+l1];
00376 R1+=(row) V[i][k][i][l+l1];
00377 }
00378 }
00379 c=IP.add_basic__constraint(R>=1);
00380 //CPC->add_sym_constraint(new cp_basic_constraint(c));
00381 c=IP.add_basic__constraint(R1>=1);
00382 //CPC->add_sym_constraint(new cp_basic_constraint(c));
00383 };
00384 }
00385 // in every interval of length U+1 at least n/2 leave home
00386 for(int l=0; l<2*n-2-U; l++) {
00387 row r;
00388 for(int i=0; i<n; i++) {
00389 for(int j=0; j<n; j++) if(j!=l) {
00390 for(int l1=0; l1<U+1; l1++) {
00391 r+=(row) V[i][i][j][l+l1];
00392 }
00393 }
00394 }
00395 IP.add_basic__constraint(r>=n/2);
00396 //CPC->add_sym_constraint(new cp_basic_constraint(c));
00397 };
00398 */
00399 // in every interval of length U+1, at least one edge home and one edge away.
00400 // TODO does not work
00401 /*
00402 for(int i=0; i<n; i++) {
00403 for(int l=0; l<2*n-2-U-1; l++) {
00404 row r1, r2;
00405 for(int j=0; j<n; j++) {
00406 for(int l1=l; l1<l+U+1; l1++) {
00407 if(l1!=2*n-2)
00408 r1+=(row) V[i][i][j][l1];
00409 if(j!=i) {
00410 for(int k=0; k<n; k++) {
00411 r2+=(row) V[i][j][k][l1];
00412 }
00413 }
00414 }
00415 }
00416 c=IP.add_basic__constraint(r1>=1);
00417 //CPC->add_sym_constraint(new cp_basic_constraint(c));
00418 c=IP.add_basic__constraint(r2>=1);
00419 //CPC->add_sym_constraint(new cp_basic_constraint(c));
00420 }
00421 };
00422 */
00423 /*
00424 for(int i=0; i<n; i++) {
00425 for(int l=0; l<2*n-2-U; l++) {
00426 row r;
00427 for(int j=0; j<n; j++) if(j!=i) {
00428 for(int l1=l; l1<l+U+1; l1++) {
00429 if(l1!=2*n-2) {
00430 r+=(row) V[i][i][j][l1];
00431 r+=(row) V[i][j][i][l1];
00432 }
00433 }
00434 }
00435 c=IP.add_basic__constraint(r>=1);
00436 //CPC->add_sym_constraint(new cp_basic_constraint(c));
00437 }
00438 };
00439 */
00440
00441 // some clieqes
00442 for(int i=0; i<n; i++) {
00443 for(int l=0; l<2*n-4; l++) {
00444 for(int j=0; j<n; j++) if(j!=i) {
00445 row r;
00446 r+=(row) V[i][i][i][l+1];
00447 for(int k=0; k<n; k++) if(k!=j) {
00448 r+=(row) V[i][k][j][l];
00449 if(k!=i) r+=(row) V[i][j][k][l];
00450 if(k!=i) r+=(row) V[i][k][j][l+2];
00451 r+=(row) V[i][j][k][l+2];
00452 };
00453 c=IP.add_basic_constraint(r<=1);
00454 //CPC->add_sym_constraint(new cp_basic_constraint(c));
00455 };
00456 };
00457 };
00458
00459 /*
00460 for(int i=0; i<n; i++) {
00461 for(int l=0; l<2*n-3; l++) {
00462 for(int j=0; j<n; j++) if(j!=i) {
00463 for(int k=0; k<n; k++) if((k!=i) && (k!=j)) {
00464 row r;
00465 r+=V[i][j][k][l];
00466 r+=V[i][j][k][l+1];
00467 r+=V[i][k][j][l];
00468 r+=V[i][k][j][l+1];
00469 for(int k1=0; k1<n; k1++) if((k1!=k) && (k1!=j)) {
00470 for(int j1=0; j1<n; j1++) if((j1!=k) && (j1!=j)) {
00471 r+=V[i][j1][k1][l];
00472 }
00473 }
00474 c=IP.add_basic__constraint(r<=1);
00475 //CPC->add_sym_constraint(new cp_basic_constraint(c));
00476 }
00477 }
00478 }
00479 };
00480 */
00481 /*
00482 for(int i=0; i<n; i++) {
00483 for(int l=1; l<2*n-2-U-2; l++) {
00484 row r;
00485 for(int l1=0; l1<U+1; l1++) {
00486 r+=V[i][i][i][l+l1];
00487 for(int j=0; j<n; j++) if(j!=i) {
00488 for(int k=0; k<n; k++) if(k!=i) {
00489 r+V[i][j][k][l+l1];
00490 }
00491 }
00492 }
00493 for(int j=0; j<n; j++) if(j!=i) {
00494 r-=V[i][j][i][l+U+1];
00495 r-=V[i][i][j][l+U+1];
00496 r-=V[i][j][i][l-1];
00497 r-=V[i][i][j][l-1];
00498 };
00499 IP.add_basic__constraint(r<=U-2);
00500 }
00501 };
00502 */
00503 // Symmetry elimination.
00504 c=IP.add_basic_constraint(((row) V[0][0][0][0])-V[0][0][0][2*n-3]<=0);
00505 //CPC->add_sym_constraint(new cp_basic_constraint(c));
00506 /*
00507 for(int i=0; i<n; i++) {
00508 for(int l=0; l<2*n-3; l++) {
00509 for(int j=0; j<n; j++) if(j!=i) {
00510 for(int k=0; k<n; k++) if((k!=i) && (k!=j)) {
00511 for(int m=0; m<n; m++) if((m!=i) && (m!=j) && (m!=k)) {
00512 row r;
00513 r+=V[i][j][k][l];
00514 r+=V[i][j][k][l+1];
00515 r+=V[i][k][j][l];
00516 r+=V[i][k][j][l+1];
00517 r+=V[i][m][i][l];
00518 r+=V[i][i][m][l+1];
00519 c=IP.add_basic__constraint(r<=1);
00520 //CPC->add_sym_constraint(new cp_basic_constraint(c));
00521 }
00522 }
00523 }
00524 }
00525 };
00526 */
00527
00528 // Entweger von j nach k oder von k nach j, nicht beides
00529 /*
00530 for(int i=0; i<n; i++) {
00531 for(int j=0; j<n; j++) if(j!=i) {
00532 for(int k=0; k<n; k++) if((k!=i) && (k!=j)) {
00533 row r;
00534 for(int l=0; l<2*n-2; l++) {
00535 r+=V[i][j][k][l];
00536 r+=V[i][k][j][l];
00537 }
00538 c=IP.add_basic__constraint(r<=1);
00539 //CPC->add_sym_constraint(new cp_basic_constraint(c));
00540 }
00541 }
00542 }
00543 */
00544 /* TODO durcheinander
00545 for(int l=1; l<2*n-1-(n/2-1); l++) {
00546 row r;
00547 for(int i=0; i<n; i++) {
00548 for(int j=0; j<n; j++) if(j!=i) {
00549 for(int l1=l; l1<l+n/2-1; l1++) {
00550 r+=V[i][i][j][l1];
00551 }
00552 }
00553 }
00554 IP.add_basic__constraint(r>=1);
00555 }
00556 */
00557 /*
00558 graph G;
00559 node N[n];
00560 edge E[n][n];
00561 for(int i=0; i<n; i++) {
00562 N[i]=G.new_node();
00563 }
00564 for(int i=0; i<n; i++) for(int j=i+1; j<n; j++) {
00565 E[i][j]=G.new_edge(N[i],N[j]);
00566 };
00567
00568 var_map<edge> VM[n];
00569 for(int i=0; i<n; i++) {
00570 for(int j=0; j<n; j++) {
00571 for(int k=j+1; k<n; k++) {
00572 var v=IP.add_variable(0,0,2*n,Vartype_Integer);
00573 VM[i][E[j][k]]=v;
00574 row r;
00575 for(int l=0; l<2*n-2; l++) {
00576 r+=V[i][j][k][l];
00577 r+=V[i][k][j][l];
00578 }
00579 if(j==i) {
00580 for(int m=0; m<n; m++) {
00581 r+=V[i][m][k][2*n-3];
00582 }
00583 }
00584 if(k==i) {
00585 for(int m=0; m<n; m++) {
00586 r+=V[i][m][j][2*n-3];
00587 };
00588 };
00589 IP.add_basic__constraint(r==v);
00590 };
00591 };
00592 IP.add_sym_constraint(new TOUR(G, VM[i]));
00593 };
00594 */
00595
00596 // at least one over every cut
00597
00598 int pw2[n];
00599 pw2[0]=1;
00600 for(int i=1; i<n; i++) pw2[i]=2*pw2[i-1];
00601 for(int i=0; i<n; i++) {
00602 cout<<i<<" Start\n";
00603 for(int j=1; j<pw2[n-1]; j++) {
00604 int k=0;
00605 for(int l=0; l<n; l++) if((j & pw2[l])==pw2[l]) k++;
00606 if((k>1) && (k<n-1)) {
00607 row r;
00608 for(int j1=0; j1<n; j1++) if((j & pw2[j1])==0) {
00609 for(int k1=0; k1<n; k1++) if((j & pw2[k1])==pw2[k1]) {
00610 for(int l1=0; l1<2*n-2; l1++) {
00611 r+=(row) V[i][j1][k1][l1];
00612 }
00613 }
00614 }
00615 c=IP.add_basic_constraint(r >=1);
00616 //CPC->add_sym_constraint(new cp_basic_constraint(c));
00617 }
00618 }
00619 }
00620
00621 //CPC->add_sym_constraint(new rrt(n, V));
00622
00623 //IP.add_sym_constraint(CPC);
00624
00625 IP.optimize();
00626
00627 cout<<"Binaries\n";
00628 for(int i=0; i<n*n*n*(2*n-2); i++) {
00629 cout<<" x"<<i;
00630 if(i%10==0) cout<<endl;
00631 }
00632 cout<<"\nEnd\n";
00633
00634
00635 for(int i=0; i<n; i++) {
00636 cout<<endl<<i<<": ";
00637 for(int l=0; l<2*n-2; l++) {
00638 for(int j=0; j<n; j++) {
00639 double dd=0;
00640 for(int k=0; k<n; k++) {
00641
00642 if(IP.get_solution(V[i][k][j][l])>0.01)
00643 dd+=IP.get_solution(V[i][k][j][l]);
00644 //cout<<l<<" "<<j<<" "<<k<<" "<<IP.get_solution(V[i][j][k][l])<<endl;
00645 }
00646 if(dd>0.01) cout<<l<<" "<<j<<" "<<dd<<endl;
00647 }
00648 }
00649 }
00650
00651 cout<<endl;
00652 }
1.2.16