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

nonogram.cpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Mikael Lagerkvist <lagerkvist@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Mikael Lagerkvist, 2005
00008  *
00009  *  Last modified:
00010  *     $Date: 2009-04-02 20:58:46 +0200 (Thu, 02 Apr 2009) $ by $Author: schulte $
00011  *     $Revision: 8649 $
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 using namespace Gecode;
00043 
00044 namespace {
00045 
00047   extern const int* specs[];
00049   extern const unsigned int n_examples;
00050 
00051 }
00052 
00067 class Nonogram : public Script {
00068 protected:
00070   const int* spec;
00072   BoolVarArray b;
00073 
00075   int width(void) const {
00076     return spec[0];
00077   }
00079   int height(void) const {
00080     return spec[1];
00081   }
00082 
00084   DFA line(int& spos) {
00085     REG r0(0), r1(1);
00086     REG border = *r0;
00087     REG between = +r0;
00088     int hints = spec[spos++];
00089     REG r = border + r1(spec[spos],spec[spos]);
00090     spos++;
00091     for (int i=hints-1; i--; spos++)
00092       r += between + r1(spec[spos],spec[spos]);
00093     return r + border;
00094   }
00095 
00096 
00097 public:
00099   Nonogram(const SizeOptions& opt)
00100     : spec(specs[opt.size()]), b(*this,width()*height(),0,1) {
00101     Matrix<BoolVarArray> m(b, width(), height());
00102 
00103     {
00104       int spos = 2;
00105       // Post constraints for columns
00106       for (int w=0; w<width(); w++)
00107         extensional(*this, m.col(w), line(spos));
00108       // Post constraints for rows
00109       for (int h=0; h<height(); h++)
00110         extensional(*this, m.row(h), line(spos));
00111     }
00112 
00113     // Number of hints for columns
00114     int cols = 0;
00115     // Number of hints for rows
00116     int rows = 0;
00117     // Compute number of hints
00118     {
00119       int spos = 2;
00120       for (int w=0; w<width(); w++) {
00121         int hint = spec[spos++];
00122         cols += hint; spos += hint;
00123       }
00124       for (int h=0; h<height(); h++) {
00125         int hint = spec[spos++];
00126         rows += hint; spos += hint;
00127       }
00128     }
00129 
00130     /*
00131      * The following branches either by columns or rows, depending on
00132      * whether there are more hints relative to the height or width
00133      * for columns or rows.
00134      *
00135      * This idea is due to Pascal Van Hentenryck and has been suggested
00136      * to us by Hakan Kjellerstrand.
00137      */
00138     if (rows*width() > cols*height()) {
00139       for (int w=0; w<width(); w++)
00140         branch(*this, m.col(w), INT_VAR_NONE, INT_VAL_MAX);
00141     } else {
00142       for (int h=0; h<height(); h++)
00143         branch(*this, m.row(h), INT_VAR_NONE, INT_VAL_MAX);
00144     }
00145   }
00146 
00148   Nonogram(bool share, Nonogram& s) : Script(share,s), spec(s.spec) {
00149     b.update(*this, share, s.b);
00150   }
00151 
00153   virtual Space*
00154   copy(bool share) {
00155     return new Nonogram(share,*this);
00156   }
00157 
00159   virtual void
00160   print(std::ostream& os) const {
00161     Matrix<BoolVarArray> m(b, width(), height());
00162     for (int h = 0; h < height(); ++h) {
00163       os << '\t';
00164       for (int w = 0; w < width(); ++w)
00165         os << ((m(w,h).val() == 1) ? '#' : ' ');
00166       os << std::endl;
00167     }
00168     os << std::endl;
00169   }
00170 };
00171 
00172 
00176 int
00177 main(int argc, char* argv[]) {
00178   SizeOptions opt("Nonogram");
00179   opt.size(8);
00180   opt.parse(argc,argv);
00181   if (opt.size() >= n_examples) {
00182     std::cerr << "Error: size must be between 0 and "
00183               << n_examples-1 << std::endl;
00184     return 1;
00185   }
00186   Script::run<Nonogram,DFS,SizeOptions>(opt);
00187   return 0;
00188 }
00189 
00190 namespace {
00191 
00203 
00204 const int heart[] =
00205   { 9, 9,
00206     // Column constraints.
00207     1, 3,
00208     2, 2, 3,
00209     2, 2, 2,
00210     2, 2, 2,
00211     2, 2, 2,
00212     2, 2, 2,
00213     2, 2, 2,
00214     2, 2, 3,
00215     1, 3,
00216     // Row constraints
00217     2, 2, 2,
00218     2, 4, 4,
00219     3, 1, 3, 1,
00220     3, 2, 1, 2,
00221     2, 1, 1,
00222     2, 2, 2,
00223     2, 2, 2,
00224     1, 3,
00225     1, 1
00226   };
00227 
00229 const int bear[] =
00230   { 13, 8,
00231     // Column constraints
00232     1, 2,
00233     2, 2, 1,
00234     2, 3, 2,
00235     1, 6,
00236     2, 1, 4,
00237     1, 3,
00238     1, 4,
00239     1, 4,
00240     1, 4,
00241     1, 5,
00242     1, 4,
00243     2, 1, 3,
00244     1, 2,
00245     // Row constraints
00246     1, 1,
00247     1, 2,
00248     2, 4, 4,
00249     1, 12,
00250     1, 8,
00251     1, 9,
00252     2, 3, 4,
00253     2, 2, 2
00254   };
00255 
00257 const int crocodile[] =
00258   { 15, 9,
00259     // Column constraints
00260     1, 3,
00261     1, 4,
00262     2, 2, 2,
00263     2, 3, 1,
00264     2, 2, 3,
00265     2, 3, 2,
00266     2, 2, 3,
00267     2, 4, 2,
00268     2, 3, 2,
00269     1, 6,
00270     2, 1, 3,
00271     2, 1, 3,
00272     2, 1, 4,
00273     1, 5,
00274     1, 5,
00275     // Row constraints
00276     1, 3,
00277     3, 2, 3, 2,
00278     2, 10, 3,
00279     1, 15,
00280     5, 1, 1, 1, 1, 6,
00281     2, 1, 7,
00282     2, 1, 4,
00283     2, 1, 4,
00284     1, 4
00285   };
00286 
00288 const int unknown[] =
00289   { 10, 10,
00290     // Column constraints
00291     1, 3,
00292     2, 2, 1,
00293     2, 2, 2,
00294     2, 2, 1,
00295     3, 1, 2, 1,
00296     2, 1, 1,
00297     3, 1, 4, 1,
00298     3, 1, 1, 2,
00299     2, 3, 1,
00300     1, 4,
00301     // Row constraints
00302     1, 3,
00303     2, 2, 1,
00304     2, 1, 1,
00305     2, 1, 4,
00306     4, 1, 1, 1, 1,
00307     4, 2, 1, 1, 1,
00308     3, 2, 1, 1,
00309     2, 1, 2,
00310     2, 2, 3,
00311     1, 3
00312   };
00313 
00315 const int pinwheel[] =
00316   { 6, 6,
00317     // Column constraints
00318     2, 1, 2,
00319     1, 1,
00320     1, 2,
00321     1, 2,
00322     1, 1,
00323     2, 2, 1,
00324     // Row constraints
00325     2, 2, 1,
00326     1, 1,
00327     1, 2,
00328     1, 2,
00329     1, 1,
00330     2, 1, 2
00331   };
00332 
00334 const int difficult[] =
00335   { 15, 15,
00336     // Column constraints
00337     1, 3,
00338     1, 2,
00339     1, 2,
00340     1, 1,
00341     1, 2,
00342     1, 3,
00343     1, 2,
00344     1, 4,
00345     1, 3,
00346     1, 4,
00347     2, 2, 1,
00348     2, 1, 1,
00349     2, 1, 1,
00350     2, 1, 1,
00351     1, 3,
00352     // Row constraints
00353     1, 3,
00354     2, 1, 1,
00355     2, 1, 1,
00356     2, 1, 1,
00357     2, 1, 2,
00358     1, 5,
00359     1, 1,
00360     1, 2,
00361     1, 1,
00362     1, 1,
00363     2, 1, 2,
00364     2, 1, 2,
00365     2, 2, 1,
00366     2, 2, 2,
00367     1, 3
00368   };
00369 
00371 const int non_unique[] =
00372   { 11, 15,
00373     // Column constraints
00374     1, 5,
00375     3, 1, 2, 4,
00376     3, 2, 1, 3,
00377     4, 2, 2, 1, 1,
00378     4, 1, 1, 1, 1,
00379     2, 1, 5,
00380     5, 2, 1, 1, 3, 2,
00381     5, 2, 1, 1, 1, 1,
00382     3, 1, 4, 1,
00383     2, 1, 1,
00384     1, 1,
00385     // Row constraints
00386     2, 2, 2,
00387     2, 2, 2,
00388     1, 4,
00389     2, 1, 1,
00390     2, 1, 1,
00391     4, 1, 1, 1, 1,
00392     2, 1, 1,
00393     2, 1, 4,
00394     3, 1, 1, 1,
00395     3, 1, 1, 4,
00396     2, 1, 3,
00397     2, 1, 2,
00398     1, 5,
00399     2, 2, 2,
00400     2, 3, 3
00401   };
00402 
00408   const int dragonfly[] =
00409     { 20, 20,
00410       // Column constraints.
00411       4, 1, 1, 1, 2,
00412       5, 3, 1, 2, 1, 1,
00413       5, 1, 4, 2, 1, 1,
00414       4, 1, 3, 2, 4,
00415       4, 1, 4, 6, 1,
00416       3, 1, 11, 1,
00417       4, 5, 1, 6, 2,
00418       1, 14,
00419       2, 7, 2,
00420       2, 7, 2,
00421       3, 6, 1, 1,
00422       2, 9, 2,
00423       4, 3, 1, 1, 1,
00424       3, 3, 1, 3,
00425       3, 2, 1, 3,
00426       3, 2, 1, 5,
00427       3, 3, 2, 2,
00428       3, 3, 3, 2,
00429       3, 2, 3, 2,
00430       2, 2, 6,
00431       // Row constraints
00432       2, 7, 1,
00433       3, 1, 1, 2,
00434       3, 2, 1, 2,
00435       3, 1, 2, 2,
00436       3, 4, 2, 3,
00437       3, 3, 1, 4,
00438       3, 3, 1, 3,
00439       3, 2, 1, 4,
00440       2, 2, 9,
00441       3, 2, 1, 5,
00442       2, 2, 7,
00443       1, 14,
00444       2, 8, 2,
00445       3, 6, 2, 2,
00446       4, 2, 8, 1, 3,
00447       4, 1, 5, 5, 2,
00448       5, 1, 3, 2, 4, 1,
00449       5, 3, 1, 2, 4, 1,
00450       5, 1, 1, 3, 1, 3,
00451       4, 2, 1, 1, 2
00452     };
00453 
00455   const int castle[]  = {
00456     60, 35,
00457     // Column constraints
00458     7, 2,3,1,5,1,7,1,
00459     7, 2,4,2,3,2,3,5,
00460     8, 2,6,3,1,1,5,1,5,
00461     10, 2,4,2,1,1,1,4,1,1,2,
00462     7, 2,8,2,1,5,2,5,
00463     7, 3,1,6,2,5,1,5,
00464     9, 3,3,3,1,1,6,1,1,1,
00465     9, 3,2,2,2,2,8,1,1,3,
00466     7, 1,4,4,3,7,1,1,
00467     7, 1,2,2,2,3,7,9,
00468     8, 1,2,3,1,1,5,2,2,
00469     7, 2,2,3,1,1,6,1,
00470     6, 1,3,1,5,4,1,
00471     8, 1,3,1,1,6,1,3,1,
00472     8, 3,3,4,5,1,4,2,1,
00473     6, 2,3,3,9,7,1,
00474     8, 2,3,2,2,1,1,3,5,
00475     8, 4,2,1,1,1,1,2,3,
00476     7, 4,2,2,1,4,3,2,
00477     4, 4,3,16,2,
00478     5, 1,2,5,7,1,      
00479     6, 4,3,2,2,7,1,      
00480     5, 2,3,1,10,1,      
00481     6, 2,4,2,1,4,1,      
00482     5, 1,6,7,3,1,      
00483     4, 3,11,3,1,      
00484     5, 7,1,11,2,1,      
00485     7, 2,2,2,2,2,2,2,      
00486     7, 3,1,1,1,1,2,1,      
00487     7, 2,2,2,2,1,1,1,      
00488     7, 1,1,1,1,2,1,2,      
00489     8, 2,2,2,2,1,1,1,1,      
00490     5, 4,1,1,2,2,      
00491     5, 5,2,17,2,1,      
00492     6, 9,2,3,1,4,2,      
00493     6, 9,4,2,1,1,1,      
00494     5, 5,4,2,1,4,      
00495     7, 11,1,2,1,4,1,2,      
00496     5, 3,4,2,4,4,      
00497     8, 2,1,4,1,2,1,5,2,      
00498     5, 8,4,1,1,2,      
00499     5, 1,1,3,2,3,      
00500     6, 1,3,1,8,1,6,      
00501     4, 2,1,7,14,      
00502     7, 1,2,4,4,1,2,3,      
00503     10, 1,1,4,2,1,1,1,1,1,4,      
00504     6, 3,5,3,1,1,4,      
00505     6, 2,4,2,2,1,2,      
00506     5, 4,2,3,8,4,      
00507     5, 4,15,2,2,4,      
00508     6, 4,1,10,2,1,2,      
00509     6, 2,12,6,1,2,4,      
00510     7, 3,1,3,1,3,3,4,      
00511     6, 3,1,2,3,4,1,      
00512     7, 5,2,2,2,3,3,3,      
00513     9, 1,2,2,2,2,4,1,1,3,      
00514     7, 2,1,4,2,7,1,1,      
00515     6, 5,2,2,3,6,3,      
00516     7, 3,3,2,2,3,2,3,      
00517     7, 4,1,2,1,1,2,1,
00518 
00519     // Row constraints
00520     4, 12,1,1,1,                                
00521     5, 8,6,3,1,3,                                
00522     6, 5,8,4,3,1,5,                                
00523     8, 7,3,4,1,3,5,1,7,                                
00524     13, 2,2,4,9,1,5,1,1,1,1,1,1,1,                                
00525     8, 4,5,10,2,1,8,7,1,                                
00526     7, 5,1,3,3,16,1,2,                                
00527     8, 8,5,1,2,4,9,1,3,                                
00528     12, 4,5,3,14,1,1,1,1,4,1,1,3,                                
00529     19, 3,3,2,2,2,4,1,1,1,1,1,1,1,1,3,1,1,3,2,                                
00530     11, 8,2,7,2,1,1,2,1,1,3,3,                                
00531     13, 1,5,9,12,2,1,1,3,1,1,2,2,1,                                
00532     17, 3,2,2,1,1,1,1,4,1,1,1,3,3,1,1,2,2,                                
00533     12, 5,2,2,2,2,1,5,2,1,1,2,5,                                
00534     12, 3,5,9,2,1,1,6,3,1,3,2,3,                                
00535     12, 1,4,1,1,1,4,1,5,5,3,3,3,                                
00536     10, 4,1,1,1,1,3,4,6,6,3,                                
00537     12, 3,1,3,1,1,3,3,1,1,4,6,1,                                
00538     11, 3,1,5,1,1,3,1,1,9,4,1,                                
00539     14, 2,1,1,7,1,4,1,1,1,1,1,1,3,5,                                
00540     11, 9,2,1,3,1,1,1,1,4,2,1,                                
00541     10, 1,14,1,1,2,2,2,10,1,2,                                
00542     10, 1,9,2,1,2,6,1,5,3,2,                                
00543     12, 1,9,9,1,2,2,3,1,1,4,3,1,                                
00544     10, 10,1,3,4,1,3,2,1,2,8,                                
00545     9, 9,1,3,5,1,1,1,2,7,                                
00546     12, 4,5,1,2,5,1,3,1,1,2,1,3,                                
00547     14, 1,1,1,1,2,6,2,3,2,1,1,2,3,1,                                
00548     11, 1,6,1,5,7,1,3,3,2,4,3,                                
00549     10, 1,2,1,2,9,1,5,2,6,2,                                
00550     8, 10,2,2,13,1,3,3,1,                                
00551     11, 2,2,1,6,2,3,3,2,2,2,1,                                
00552     12, 2,2,1,1,12,2,2,9,2,2,2,2,                                
00553     9, 5,1,2,4,1,5,11,2,2,                                
00554     3, 15,6,18,
00555   };
00556 
00562   const int p200[] =
00563     { 25, 25,
00564       // Column constraints
00565       4, 1,1,2,2,
00566       3, 5,5,7,
00567       4, 5,2,2,9,
00568       4, 3,2,3,9,
00569       5, 1,1,3,2,7,
00570       3, 3,1,5,
00571       5, 7,1,1,1,3,
00572       6, 1,2,1,1,2,1,
00573       3, 4,2,4,
00574       4, 1,2,2,2,
00575       3, 4,6,2,
00576       4, 1,2,2,1,
00577       4, 3,3,2,1,
00578       3, 4,1,15,
00579       6, 1,1,1,3,1,1,
00580       6, 2,1,1,2,2,3,
00581       4, 1,4,4,1,
00582       4, 1,4,3,2,
00583       4, 1,1,2,2,
00584       5, 7,2,3,1,1,
00585       5, 2,1,1,1,5,
00586       3, 1,2,5,
00587       4, 1,1,1,3,
00588       3, 4,2,1,
00589       1, 3,
00590       // Row constraints
00591       3, 2,2,3,
00592       5, 4,1,1,1,4,
00593       5, 4,1,2,1,1,
00594       7, 4,1,1,1,1,1,1,
00595       6, 2,1,1,2,3,5,
00596       6, 1,1,1,1,2,1,
00597       5, 3,1,5,1,2,
00598       6, 3,2,2,1,2,2,
00599       7, 2,1,4,1,1,1,1,
00600       6, 2,2,1,2,1,2,
00601       6, 1,1,1,3,2,3,
00602       5, 1,1,2,7,3,
00603       5, 1,2,2,1,5,
00604       5, 3,2,2,1,2,
00605       4, 3,2,1,2,
00606       3, 5,1,2,
00607       4, 2,2,1,2,
00608       4, 4,2,1,2,
00609       4, 6,2,3,2,
00610       4, 7,4,3,2,
00611       3, 7,4,4,
00612       3, 7,1,4,
00613       3, 6,1,4,
00614       3, 4,2,2,
00615       2, 2,1
00616     };
00617 
00618 
00619   const int *specs[] = {heart, bear, crocodile, unknown,
00620                         pinwheel, difficult, non_unique, dragonfly, 
00621                         castle, p200};
00622   const unsigned n_examples = sizeof(specs)/sizeof(int*);
00624 
00625 }
00626 
00627 // STATISTICS: example-any