Generated on Mon Jul 6 18:09:02 2009 for Gecode by doxygen 1.5.9

tsp.cpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2007
00008  *
00009  *  Last modified:
00010  *     $Date: 2009-05-14 00:24:31 +0200 (Thu, 14 May 2009) $ by $Author: tack $
00011  *     $Revision: 9095 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 #include <gecode/driver.hh>
00039 #include <gecode/int.hh>
00040 #include <gecode/minimodel.hh>
00041 
00042 #include <algorithm>
00043 
00044 using namespace Gecode;
00045 
00047 namespace {
00048 
00050   const int PA_n = 7;
00051   const int PA_d[PA_n*PA_n] = {
00052     0,205,677,581,461,878,345,
00053     205,0,882,427,390,1105,540,
00054     677,882,0,619,316,201,470,
00055     581,427,619,0,412,592,570,
00056     461,390,316,412,0,517,190,
00057     878,1105,201,592,517,0,691,
00058     345,540,470,570,190,691,0
00059   };
00060 
00062   const int PB_n = 10;
00063   const int PB_d[PB_n*PB_n] = {
00064     2,4,4,1,9,2,4,4,1,9,
00065     2,9,5,5,5,2,9,5,5,5,
00066     1,5,2,3,3,1,5,2,3,3,
00067     2,6,8,9,5,2,6,8,9,5,
00068     3,7,1,6,4,3,7,1,6,4,
00069     1,2,4,1,7,1,2,4,1,7,
00070     3,5,2,7,6,3,5,2,7,6,
00071     2,7,9,5,5,2,7,9,5,5,
00072     3,9,7,3,4,3,9,7,3,4,
00073     4,1,5,9,2,4,1,5,9,2
00074   };
00075 
00077   const int PC_n = 17;
00078   const int PC_d[PC_n*PC_n] = {
00079     0,3,5,48,48,8,8,5,5,3,3,0,3,5,8,8,5,
00080     3,0,3,48,48,8,8,5,5,0,0,3,0,3,8,8,5,
00081     5,3,0,72,72,48,48,24,24,3,3,5,3,0,48,48,24,
00082     48,48,74,0,0,6,6,12,12,48,48,48,48,74,6,6,12,
00083     48,48,74,0,0,6,6,12,12,48,48,48,48,74,6,6,12,
00084     8,8,50,6,6,0,0,8,8,8,8,8,8,50,0,0,8,
00085     8,8,50,6,6,0,0,8,8,8,8,8,8,50,0,0,8,
00086     5,5,26,12,12,8,8,0,0,5,5,5,5,26,8,8,0,
00087     5,5,26,12,12,8,8,0,0,5,5,5,5,26,8,8,0,
00088     3,0,3,48,48,8,8,5,5,0,0,3,0,3,8,8,5,
00089     3,0,3,48,48,8,8,5,5,0,0,3,0,3,8,8,5,
00090     0,3,5,48,48,8,8,5,5,3,3,0,3,5,8,8,5,
00091     3,0,3,48,48,8,8,5,5,0,0,3,0,3,8,8,5,
00092     5,3,0,72,72,48,48,24,24,3,3,5,3,0,48,48,24,
00093     8,8,50,6,6,0,0,8,8,8,8,8,8,50,0,0,8,
00094     8,8,50,6,6,0,0,8,8,8,8,8,8,50,0,0,8,
00095     5,5,26,12,12,8,8,0,0,5,5,5,5,26,8,8,0
00096   };
00097 
00099   const int PD_n = 34;
00100   const int PD_d[PD_n*PD_n] = {
00101     0,26,82,65,100,147,134,69,117,42,89,125,38,13,38,31,22,103,
00102     143,94,104,123,98,58,38,30,67,120,149,100,93,162,62,66,66,0,
00103     56,39,109,156,140,135,183,108,155,190,104,79,104,97,88,130,176,121,
00104     131,150,125,85,65,57,94,147,160,80,67,189,128,40,43,57,0,16,
00105     53,100,84,107,155,85,132,168,81,56,81,74,65,146,186,137,147,166,
00106     141,101,81,73,110,163,164,102,71,205,105,62,27,41,62,0,97,144,
00107     131,96,144,69,116,152,65,40,65,58,49,130,170,121,131,150,125,85,
00108     65,57,94,147,166,86,73,189,89,46,109,135,161,174,0,47,34,54,
00109     102,67,114,175,97,96,128,135,131,198,193,203,213,232,207,167,147,139,
00110     176,229,222,204,148,235,60,175,157,171,114,130,60,0,40,114,162,127,
00111     174,235,157,156,188,188,179,258,253,251,239,258,203,215,195,187,172,207,
00112     175,157,101,295,120,133,143,169,132,148,34,31,0,88,133,101,148,209,
00113     131,130,162,169,165,232,227,237,247,266,221,201,181,173,190,225,193,175,
00114     119,269,94,151,95,121,177,160,54,101,88,0,48,53,100,158,83,82,
00115     114,121,117,184,179,189,199,218,193,153,133,125,162,215,244,195,188,221,
00116     46,161,79,105,161,144,91,138,125,37,0,37,53,114,67,66,98,105,
00117     101,137,132,149,183,202,177,137,117,109,146,199,228,179,172,174,57,145,
00118     42,68,124,107,67,114,101,27,75,0,47,108,30,29,61,68,64,131,
00119     126,136,146,165,140,100,80,72,109,162,191,142,135,168,20,108,83,109,
00120     165,148,108,155,142,68,88,41,0,61,71,70,102,109,105,84,79,96,
00121     144,163,175,141,121,113,150,203,232,183,176,121,61,149,204,230,286,269,
00122     216,255,237,162,125,162,123,0,192,191,223,230,226,144,139,156,184,165,
00123     215,249,242,234,251,282,332,297,297,113,182,270,38,64,120,103,88,135,
00124     122,57,105,30,77,87,0,25,31,38,47,110,105,122,142,161,136,96,
00125     76,68,105,158,187,138,131,147,50,104,13,39,95,78,87,134,121,56,
00126     104,29,76,112,25,0,32,39,35,116,130,107,117,136,111,71,51,43,
00127     80,133,162,113,106,172,49,79,38,48,104,87,119,166,153,88,136,61,
00128     108,118,31,32,0,7,16,123,136,114,124,143,118,78,58,50,87,140,
00129     169,120,115,178,81,88,31,41,97,80,115,162,149,84,132,57,104,114,
00130     27,28,7,0,9,116,132,107,117,136,111,71,51,43,80,133,162,113,
00131     108,174,77,81,22,32,88,71,122,169,156,91,139,64,111,123,36,35,
00132     16,9,0,107,141,98,108,127,102,62,42,34,71,124,153,104,99,166,
00133     84,72,108,134,190,173,133,180,167,93,113,66,85,60,96,95,127,134,
00134     130,0,46,63,116,135,147,166,146,138,175,221,257,208,201,120,86,174,
00135     127,153,209,192,152,199,186,112,132,85,104,79,115,114,146,153,149,19,
00136     0,17,70,89,101,135,148,157,137,175,219,183,220,85,105,193,153,179,
00137     235,218,178,225,212,138,158,111,130,105,141,140,172,179,175,45,57,0,
00138     53,72,84,118,131,183,120,158,202,166,241,68,131,214,179,165,199,204,
00139     243,290,277,203,223,176,195,165,206,192,199,192,183,110,112,82,0,19,
00140     31,65,78,149,67,105,149,113,188,95,196,161,212,205,239,244,237,284,
00141     271,197,217,170,189,146,200,199,231,232,223,104,93,63,40,0,71,105,
00142     118,189,107,117,167,153,228,76,190,201,148,134,168,173,212,259,246,172,
00143     192,145,164,139,175,161,168,161,152,79,125,70,36,55,0,34,47,118,
00144     36,89,118,82,157,131,165,130,153,146,180,185,178,225,212,138,158,111,
00145     130,105,141,140,172,173,164,45,91,36,46,65,77,0,59,130,48,101,
00146     130,94,169,104,131,142,173,166,200,205,198,245,232,158,178,131,150,125,
00147     161,160,192,193,184,65,111,56,66,85,97,20,0,150,68,121,150,114,
00148     189,124,151,162,30,16,72,55,125,172,156,99,147,72,119,133,68,43,
00149     50,43,34,73,119,64,74,93,68,28,8,0,37,90,119,70,83,132,
00150     92,56,112,98,132,137,185,232,216,181,223,154,195,170,150,125,132,125,
00151     116,110,156,101,67,86,31,65,78,82,0,53,82,46,121,162,174,94,
00152     144,130,164,169,217,256,225,213,261,186,233,234,182,157,164,157,148,174,
00153     209,165,131,116,95,129,122,114,93,0,50,78,147,192,206,126,94,80,
00154     114,119,167,214,198,163,211,136,183,197,132,107,114,107,98,137,183,128,
00155     110,129,74,92,72,64,43,57,0,28,103,196,156,76,66,52,101,91,
00156     154,201,185,135,183,108,155,169,104,79,86,79,70,109,155,100,82,101,
00157     46,64,44,36,15,68,97,0,90,168,128,63,113,108,70,86,84,131,
00158     115,138,186,151,198,225,151,126,142,135,126,165,211,156,138,157,102,120,
00159     100,92,71,124,93,56,0,224,144,32,146,172,228,211,171,218,205,131,
00160     151,104,123,80,134,133,165,172,168,38,27,44,75,76,106,140,153,176,
00161     142,180,224,188,239,0,124,212,102,128,184,167,61,108,95,7,55,60,
00162     107,165,90,89,121,128,124,191,186,196,206,225,200,160,140,132,169,222,
00163     251,202,195,228,0,168,81,95,38,54,91,138,122,145,193,123,170,206,
00164     119,94,119,112,103,184,224,175,165,184,129,139,119,111,98,151,120,83,
00165     27,243,143,0
00166   };
00167 
00169   class Problem {
00170   private:
00171     const int  _n; 
00172     const int* _d; 
00173   public:
00175     Problem(const int n, const int* d);
00177     int size(void) const;
00179     int d(int i, int j) const;
00181     int max(void) const;
00182   };
00183 
00184   inline
00185   Problem::Problem(const int n, const int* d)
00186     : _n(n), _d(d) {}
00187   inline int
00188   Problem::size(void) const {
00189     return _n;
00190   }
00191   inline int
00192   Problem::d(int i, int j) const {
00193     return _d[i*_n+j];
00194   }
00195   inline int
00196   Problem::max(void) const {
00197     int m=0;
00198     for (int i=_n*_n; i--; )
00199       m = std::max(m,_d[i]);
00200     return m*_n;
00201   }
00202 
00203   Problem PA(PA_n,PA_d);
00204   Problem PB(PB_n,PB_d);
00205   Problem PC(PC_n,PC_d);
00206   Problem PD(PD_n,PD_d);
00207 
00208   Problem ps[] = {PA,PB,PC,PD};
00209   const unsigned int ps_n = sizeof(ps) / sizeof(Problem);
00210 
00211 }
00212 
00222 class TSP : public MinimizeScript {
00223 protected:
00225   Problem     p;
00227   IntVarArray succ;
00229   IntVar      total;
00230 public:
00232   TSP(const SizeOptions& opt)
00233     : p(ps[opt.size()]),
00234       succ(*this, p.size(), 0, p.size()-1),
00235       total(*this, 0, p.max()) {
00236 
00237     // Cost of each edge
00238     IntVarArgs costs(p.size());
00239     // Distances
00240     IntArgs d(p.size());
00241 
00242     // Setup costs for edges
00243     for (int i=p.size(); i--; ) {
00244       int m=0;
00245       for (int j=p.size(); j--; ) {
00246         m = std::max(m,p.d(i,j));
00247         d[j]=p.d(i,j);
00248       }
00249       costs[i].init(*this,0,m);
00250       // Propagate cost for chosen edge
00251       element(*this, d, succ[i], costs[i]);
00252     }
00253 
00254     // Cost ist sume of all costs
00255     linear(*this, costs, IRT_EQ, total);
00256 
00257     // Enforce that the succesors yield a tour
00258     circuit(*this, succ, opt.icl());
00259 
00260     // Just assume that the circle starts forwards
00261     rel(*this, succ[0], IRT_LE, succ[1]);
00262 
00263     // First enumerate cost values, prefer those that maximize cost reduction
00264     branch(*this, costs, INT_VAR_REGRET_MAX_MAX, INT_VAL_SPLIT_MIN);
00265 
00266     // Then fix the remaining successors
00267     branch(*this, succ,  INT_VAR_MIN_MIN, INT_VAL_MIN);
00268   }
00270   virtual IntVar cost(void) const {
00271     return total;
00272   }
00274   TSP(bool share, TSP& s) : MinimizeScript(share,s), p(s.p) {
00275     succ.update(*this, share, s.succ);
00276     total.update(*this, share, s.total);
00277   }
00279   virtual Space*
00280   copy(bool share) {
00281     return new TSP(share,*this);
00282   }
00284   virtual void
00285   print(std::ostream& os) const {
00286     bool assigned = true;
00287     for (int i=0; i<succ.size(); i++) {
00288       if (!succ[i].assigned()) {
00289         assigned = false;
00290         break;
00291       }
00292     }
00293     if (assigned) {
00294       os << "\tTour: ";
00295       int i=0;
00296       do {
00297         os << i << " -> ";
00298         i=succ[i].val();
00299       } while (i != 0);
00300       os << 0 << std::endl;
00301       os << "\tCost: " << total << std::endl;
00302     } else {
00303       os << "\tTour: " << std::endl;
00304       for (int i=0; i<succ.size(); i++) {
00305         os << "\t" << i << " -> " << succ[i] << std::endl;
00306       }
00307       os << "\tCost: " << total << std::endl;
00308     }
00309   }
00310 };
00311 
00312 
00313 
00317 int
00318 main(int argc, char* argv[]) {
00319   SizeOptions opt("TSP");
00320   opt.solutions(0);
00321   opt.icl(ICL_DOM);
00322   opt.parse(argc,argv);
00323 
00324   if (opt.size() >= ps_n) {
00325     std::cerr << "Error: size must be between 0 and "
00326               << ps_n-1 << std::endl;
00327     return 1;
00328   }
00329 
00330   MinimizeScript::run<TSP,BAB,SizeOptions>(opt);
00331   return 0;
00332 }
00333 
00334 // STATISTICS: example-any