demo/sat.cc
changeset 2420 07c4f9bcb4d5
child 2553 bfced05fa852
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/demo/sat.cc	Wed Apr 18 16:34:40 2007 +0000
     1.3 @@ -0,0 +1,115 @@
     1.4 +/* -*- C++ -*-
     1.5 + *
     1.6 + * This file is a part of LEMON, a generic C++ optimization library
     1.7 + *
     1.8 + * Copyright (C) 2003-2007
     1.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    1.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    1.11 + *
    1.12 + * Permission to use, modify and distribute this software is granted
    1.13 + * provided that this copyright notice appears in all copies. For
    1.14 + * precise terms see the accompanying LICENSE file.
    1.15 + *
    1.16 + * This software is provided "AS IS" with no warranty of any kind,
    1.17 + * express or implied, and with no claim as to its suitability for any
    1.18 + * purpose.
    1.19 + *
    1.20 + */
    1.21 +
    1.22 +/// \ingroup demos
    1.23 +/// \file
    1.24 +/// \brief Solver for SAT problems.
    1.25 +///
    1.26 +/// This demo progam solves the SAT problem, i.e. the boolean
    1.27 +/// satisfiability problem. The problem in general case is
    1.28 +/// NP-complete.
    1.29 +///
    1.30 +/// The program uses an integer linear program solver. A <tt>{0,
    1.31 +/// 1}</tt> variable is assigned to each boolean variable. The
    1.32 +/// disjunctions are converted to linear inequalities as each negation
    1.33 +/// is replaced with a substraction from one and each disjunction is
    1.34 +/// converted to addition. The generated linear expression should be
    1.35 +/// at least one.
    1.36 +///
    1.37 +/// \include sat.cc
    1.38 +
    1.39 +#include <iostream>
    1.40 +#include <fstream>
    1.41 +#include <sstream>
    1.42 +#include <string>
    1.43 +
    1.44 +#include <lemon/lp.h>
    1.45 +
    1.46 +using namespace std;
    1.47 +using namespace lemon;
    1.48 +
    1.49 +
    1.50 +int main(int argc, const char *argv[]) {
    1.51 +  if (argc != 2) {
    1.52 +    std::cerr << "The SAT solver demo" << std::endl << std::endl;
    1.53 +    std::cerr << "The  parameter should be a filename" << std::endl;
    1.54 +    std::cerr << "Each line of the file should contain a bool expression:" 
    1.55 +              << std::endl;
    1.56 +    std::cerr << "  [not] <variable> [or [not] <variable>]..." << std::endl;
    1.57 +    std::cerr << "The program prints a feasible solution if it exists" 
    1.58 +              << std::endl;
    1.59 +    return -1;
    1.60 +  }
    1.61 +  ifstream is(argv[1]);
    1.62 +
    1.63 +  Mip mip;
    1.64 +  mip.max();
    1.65 +  mip.obj(0);
    1.66 +
    1.67 +  string line;
    1.68 +  while (getline(is, line)) {
    1.69 +    istringstream ls(line);
    1.70 +
    1.71 +    Mip::Expr expr;
    1.72 +
    1.73 +
    1.74 +    string op;
    1.75 +    do {
    1.76 +      string var;
    1.77 +      bool neg = false;
    1.78 +
    1.79 +      ls >> var;
    1.80 +      if (var == "not") {
    1.81 +        neg = true;
    1.82 +        ls >> var;
    1.83 +      }
    1.84 +
    1.85 +      Mip::Col col = mip.colByName(var);
    1.86 +
    1.87 +      if (col == INVALID) {
    1.88 +        col = mip.addCol();
    1.89 +        mip.colName(col, var);
    1.90 +        mip.colLowerBound(col, 0);
    1.91 +        mip.colUpperBound(col, 1);
    1.92 +        mip.integer(col, true);        
    1.93 +      }
    1.94 +      
    1.95 +      expr += (neg ? 1 - col : col);
    1.96 +
    1.97 +    } while (ls >> op && op == "or");
    1.98 +    if (ls) {
    1.99 +      std::cerr << "Wrong bool expression" << std::endl;
   1.100 +      return -1;
   1.101 +    }
   1.102 +    mip.addRow(expr >= 1);
   1.103 +  }
   1.104 +
   1.105 +  mip.solve();
   1.106 +
   1.107 +  if (mip.mipStatus() == Mip::OPTIMAL) {
   1.108 +    for (Mip::ColIt it(mip); it != INVALID; ++it) {
   1.109 +      std::cout << mip.colName(it) << " = " 
   1.110 +                << (mip.primal(it) == 1 ? "true" : "false")
   1.111 +                << std::endl;
   1.112 +    }
   1.113 +  } else {
   1.114 +    std::cout << "There is no feasible solution." << std::endl;
   1.115 +  }
   1.116 +  
   1.117 +  return 0;
   1.118 +}