Generated on Mon Aug 25 11:35:33 2008 for Gecode by doxygen 1.5.6

tsp.cc

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: 2007-11-30 13:58:34 +0100 (Fri, 30 Nov 2007) $ by $Author: tack $
00011  *     $Revision: 5524 $
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 "examples/support.hh"
00039 #include "gecode/minimodel.hh"
00040 
00041 #include <algorithm>
00042 
00044 namespace {
00045 
00047   const int PA_n = 7;
00048   const int PA_d[PA_n*PA_n] = {
00049     0,205,677,581,461,878,345,
00050     205,0,882,427,390,1105,540,
00051     677,882,0,619,316,201,470,
00052     581,427,619,0,412,592,570,
00053     461,390,316,412,0,517,190,
00054     878,1105,201,592,517,0,691,
00055     345,540,470,570,190,691,0
00056   };
00057 
00059   const int PB_n = 10;
00060   const int PB_d[PB_n*PB_n] = {
00061     2,4,4,1,9,2,4,4,1,9,
00062     2,9,5,5,5,2,9,5,5,5,
00063     1,5,2,3,3,1,5,2,3,3,
00064     2,6,8,9,5,2,6,8,9,5,
00065     3,7,1,6,4,3,7,1,6,4,
00066     1,2,4,1,7,1,2,4,1,7,
00067     3,5,2,7,6,3,5,2,7,6,
00068     2,7,9,5,5,2,7,9,5,5,
00069     3,9,7,3,4,3,9,7,3,4,
00070     4,1,5,9,2,4,1,5,9,2
00071   };
00072 
00074   const int PC_n = 17;
00075   const int PC_d[PC_n*PC_n] = {
00076     0,3,5,48,48,8,8,5,5,3,3,0,3,5,8,8,5,
00077     3,0,3,48,48,8,8,5,5,0,0,3,0,3,8,8,5,
00078     5,3,0,72,72,48,48,24,24,3,3,5,3,0,48,48,24,
00079     48,48,74,0,0,6,6,12,12,48,48,48,48,74,6,6,12,
00080     48,48,74,0,0,6,6,12,12,48,48,48,48,74,6,6,12,
00081     8,8,50,6,6,0,0,8,8,8,8,8,8,50,0,0,8,
00082     8,8,50,6,6,0,0,8,8,8,8,8,8,50,0,0,8,
00083     5,5,26,12,12,8,8,0,0,5,5,5,5,26,8,8,0,
00084     5,5,26,12,12,8,8,0,0,5,5,5,5,26,8,8,0,
00085     3,0,3,48,48,8,8,5,5,0,0,3,0,3,8,8,5,
00086     3,0,3,48,48,8,8,5,5,0,0,3,0,3,8,8,5,
00087     0,3,5,48,48,8,8,5,5,3,3,0,3,5,8,8,5,
00088     3,0,3,48,48,8,8,5,5,0,0,3,0,3,8,8,5,
00089     5,3,0,72,72,48,48,24,24,3,3,5,3,0,48,48,24,
00090     8,8,50,6,6,0,0,8,8,8,8,8,8,50,0,0,8,
00091     8,8,50,6,6,0,0,8,8,8,8,8,8,50,0,0,8,
00092     5,5,26,12,12,8,8,0,0,5,5,5,5,26,8,8,0
00093   };
00094 
00096   const int PD_n = 34;
00097   const int PD_d[PD_n*PD_n] = {
00098     0,26,82,65,100,147,134,69,117,42,89,125,38,13,38,31,22,103,
00099     143,94,104,123,98,58,38,30,67,120,149,100,93,162,62,66,66,0,
00100     56,39,109,156,140,135,183,108,155,190,104,79,104,97,88,130,176,121,
00101     131,150,125,85,65,57,94,147,160,80,67,189,128,40,43,57,0,16,
00102     53,100,84,107,155,85,132,168,81,56,81,74,65,146,186,137,147,166,
00103     141,101,81,73,110,163,164,102,71,205,105,62,27,41,62,0,97,144,
00104     131,96,144,69,116,152,65,40,65,58,49,130,170,121,131,150,125,85,
00105     65,57,94,147,166,86,73,189,89,46,109,135,161,174,0,47,34,54,
00106     102,67,114,175,97,96,128,135,131,198,193,203,213,232,207,167,147,139,
00107     176,229,222,204,148,235,60,175,157,171,114,130,60,0,40,114,162,127,
00108     174,235,157,156,188,188,179,258,253,251,239,258,203,215,195,187,172,207,
00109     175,157,101,295,120,133,143,169,132,148,34,31,0,88,133,101,148,209,
00110     131,130,162,169,165,232,227,237,247,266,221,201,181,173,190,225,193,175,
00111     119,269,94,151,95,121,177,160,54,101,88,0,48,53,100,158,83,82,
00112     114,121,117,184,179,189,199,218,193,153,133,125,162,215,244,195,188,221,
00113     46,161,79,105,161,144,91,138,125,37,0,37,53,114,67,66,98,105,
00114     101,137,132,149,183,202,177,137,117,109,146,199,228,179,172,174,57,145,
00115     42,68,124,107,67,114,101,27,75,0,47,108,30,29,61,68,64,131,
00116     126,136,146,165,140,100,80,72,109,162,191,142,135,168,20,108,83,109,
00117     165,148,108,155,142,68,88,41,0,61,71,70,102,109,105,84,79,96,
00118     144,163,175,141,121,113,150,203,232,183,176,121,61,149,204,230,286,269,
00119     216,255,237,162,125,162,123,0,192,191,223,230,226,144,139,156,184,165,
00120     215,249,242,234,251,282,332,297,297,113,182,270,38,64,120,103,88,135,
00121     122,57,105,30,77,87,0,25,31,38,47,110,105,122,142,161,136,96,
00122     76,68,105,158,187,138,131,147,50,104,13,39,95,78,87,134,121,56,
00123     104,29,76,112,25,0,32,39,35,116,130,107,117,136,111,71,51,43,
00124     80,133,162,113,106,172,49,79,38,48,104,87,119,166,153,88,136,61,
00125     108,118,31,32,0,7,16,123,136,114,124,143,118,78,58,50,87,140,
00126     169,120,115,178,81,88,31,41,97,80,115,162,149,84,132,57,104,114,
00127     27,28,7,0,9,116,132,107,117,136,111,71,51,43,80,133,162,113,
00128     108,174,77,81,22,32,88,71,122,169,156,91,139,64,111,123,36,35,
00129     16,9,0,107,141,98,108,127,102,62,42,34,71,124,153,104,99,166,
00130     84,72,108,134,190,173,133,180,167,93,113,66,85,60,96,95,127,134,
00131     130,0,46,63,116,135,147,166,146,138,175,221,257,208,201,120,86,174,
00132     127,153,209,192,152,199,186,112,132,85,104,79,115,114,146,153,149,19,
00133     0,17,70,89,101,135,148,157,137,175,219,183,220,85,105,193,153,179,
00134     235,218,178,225,212,138,158,111,130,105,141,140,172,179,175,45,57,0,
00135     53,72,84,118,131,183,120,158,202,166,241,68,131,214,179,165,199,204,
00136     243,290,277,203,223,176,195,165,206,192,199,192,183,110,112,82,0,19,
00137     31,65,78,149,67,105,149,113,188,95,196,161,212,205,239,244,237,284,
00138     271,197,217,170,189,146,200,199,231,232,223,104,93,63,40,0,71,105,
00139     118,189,107,117,167,153,228,76,190,201,148,134,168,173,212,259,246,172,
00140     192,145,164,139,175,161,168,161,152,79,125,70,36,55,0,34,47,118,
00141     36,89,118,82,157,131,165,130,153,146,180,185,178,225,212,138,158,111,
00142     130,105,141,140,172,173,164,45,91,36,46,65,77,0,59,130,48,101,
00143     130,94,169,104,131,142,173,166,200,205,198,245,232,158,178,131,150,125,
00144     161,160,192,193,184,65,111,56,66,85,97,20,0,150,68,121,150,114,
00145     189,124,151,162,30,16,72,55,125,172,156,99,147,72,119,133,68,43,
00146     50,43,34,73,119,64,74,93,68,28,8,0,37,90,119,70,83,132,
00147     92,56,112,98,132,137,185,232,216,181,223,154,195,170,150,125,132,125,
00148     116,110,156,101,67,86,31,65,78,82,0,53,82,46,121,162,174,94,
00149     144,130,164,169,217,256,225,213,261,186,233,234,182,157,164,157,148,174,
00150     209,165,131,116,95,129,122,114,93,0,50,78,147,192,206,126,94,80,
00151     114,119,167,214,198,163,211,136,183,197,132,107,114,107,98,137,183,128,
00152     110,129,74,92,72,64,43,57,0,28,103,196,156,76,66,52,101,91,
00153     154,201,185,135,183,108,155,169,104,79,86,79,70,109,155,100,82,101,
00154     46,64,44,36,15,68,97,0,90,168,128,63,113,108,70,86,84,131,
00155     115,138,186,151,198,225,151,126,142,135,126,165,211,156,138,157,102,120,
00156     100,92,71,124,93,56,0,224,144,32,146,172,228,211,171,218,205,131,
00157     151,104,123,80,134,133,165,172,168,38,27,44,75,76,106,140,153,176,
00158     142,180,224,188,239,0,124,212,102,128,184,167,61,108,95,7,55,60,
00159     107,165,90,89,121,128,124,191,186,196,206,225,200,160,140,132,169,222,
00160     251,202,195,228,0,168,81,95,38,54,91,138,122,145,193,123,170,206,
00161     119,94,119,112,103,184,224,175,165,184,129,139,119,111,98,151,120,83,
00162     27,243,143,0
00163   };
00164 
00166   class Problem {
00167   private:
00168     const int  _n; 
00169     const int* _d; 
00170   public:
00172     Problem(const int n, const int* d);
00174     int size(void) const;
00176     int d(int i, int j) const;
00178     int max(void) const;
00179   };
00180 
00181   inline
00182   Problem::Problem(const int n, const int* d) 
00183     : _n(n), _d(d) {}
00184   inline int
00185   Problem::size(void) const {
00186     return _n;
00187   }
00188   inline int
00189   Problem::d(int i, int j) const {
00190     return _d[i*_n+j];
00191   }
00192   inline int
00193   Problem::max(void) const {
00194     int m=0;
00195     for (int i=_n*_n; i--; )
00196       m = std::max(m,_d[i]);
00197     return m*_n;
00198   }
00199 
00200   Problem PA(PA_n,PA_d);
00201   Problem PB(PB_n,PB_d);
00202   Problem PC(PC_n,PC_d);
00203   Problem PD(PD_n,PD_d);
00204 
00205   Problem ps[] = {PA,PB,PC,PD};
00206   const unsigned int ps_n = sizeof(ps) / sizeof(Problem);
00207 
00208 }
00209 
00219 class TSP : public Example {
00220 protected:
00222   Problem     p;
00224   IntVarArray succ;
00226   IntVar      cost;
00227 public:
00229   TSP(const SizeOptions& opt) 
00230     : p(ps[opt.size()]),
00231       succ(this, p.size(), 0, p.size()-1),
00232       cost(this, 0, p.max()) {
00233 
00234     // Cost of each edge
00235     IntVarArgs costs(p.size());
00236     // Distances
00237     IntArgs d(p.size());
00238 
00239     // Setup costs for edges
00240     for (int i=p.size(); i--; ) {
00241       int m=0;
00242       for (int j=p.size(); j--; ) {
00243         m = std::max(m,p.d(i,j));
00244         d[j]=p.d(i,j);
00245       }
00246       costs[i].init(this,0,m);
00247       // Propagate cost for chosen edge
00248       element(this, d, succ[i], costs[i]);
00249     }
00250 
00251     // Cost ist sume of all costs
00252     linear(this, costs, IRT_EQ, cost);
00253 
00254     // Enforce that the succesors yield a tour
00255     circuit(this, succ, opt.icl());
00256 
00257     // Just assume that the circle starts forwards
00258     rel(this, succ[0], IRT_LE, succ[1]);
00259 
00260     // First enumerate cost values, prefer those that maximize cost reduction
00261     branch(this, costs, INT_VAR_REGRET_MAX_MAX, INT_VAL_SPLIT_MIN);
00262 
00263     // Then fix the remaining successors
00264     branch(this, succ,  INT_VAR_MIN_MIN, INT_VAL_MIN);
00265   }
00267   void
00268   constrain(Space* s) {
00269     rel(this, cost, IRT_LE, static_cast<TSP*>(s)->cost.val());
00270   }
00272   TSP(bool share, TSP& s) : Example(share,s), p(s.p) {
00273     succ.update(this, share, s.succ);
00274     cost.update(this, share, s.cost);
00275   }
00277   virtual Space*
00278   copy(bool share) {
00279     return new TSP(share,*this);
00280   }
00282   virtual void
00283   print(std::ostream& os) {
00284     os << "\tTour: ";
00285     int i=0;
00286     do {
00287       os << i << " -> ";
00288       i=succ[i].val();
00289     } while (i != 0);
00290     os << 0 << std::endl;
00291     os << "\tCost: " << cost << std::endl;
00292   }
00293 };
00294 
00295 
00296 
00300 int
00301 main(int argc, char* argv[]) {
00302   SizeOptions opt("TSP");
00303   opt.solutions(0);
00304   opt.icl(ICL_DOM);
00305   opt.parse(argc,argv);
00306 
00307   if (opt.size() >= ps_n) {
00308     std::cerr << "Error: size must be between 0 and "
00309               << ps_n-1 << std::endl;
00310     return 1;
00311   }
00312 
00313   Example::run<TSP,BAB,SizeOptions>(opt);
00314   return 0;
00315 }
00316 
00317 // STATISTICS: example-any