demo/sat-2.cc
author kpeter
Thu, 27 Sep 2007 13:04:06 +0000
changeset 2476 059dcdda37c5
child 2553 bfced05fa852
permissions -rw-r--r--
Bug fixes in the documentation (mainly bad references).
deba@2420
     1
/* -*- C++ -*-
deba@2420
     2
 *
deba@2420
     3
 * This file is a part of LEMON, a generic C++ optimization library
deba@2420
     4
 *
deba@2420
     5
 * Copyright (C) 2003-2007
deba@2420
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@2420
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@2420
     8
 *
deba@2420
     9
 * Permission to use, modify and distribute this software is granted
deba@2420
    10
 * provided that this copyright notice appears in all copies. For
deba@2420
    11
 * precise terms see the accompanying LICENSE file.
deba@2420
    12
 *
deba@2420
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@2420
    14
 * express or implied, and with no claim as to its suitability for any
deba@2420
    15
 * purpose.
deba@2420
    16
 *
deba@2420
    17
 */
deba@2420
    18
deba@2420
    19
/// \ingroup demos
deba@2420
    20
/// \file
deba@2420
    21
/// \brief Solver for SAT-2 problems.
deba@2420
    22
///
deba@2420
    23
/// This demo progam solves the SAT-2 problem, i.e. the boolean
deba@2420
    24
/// satisfiability problem where each disjuction consists at most 2
deba@2420
    25
/// terms.
deba@2420
    26
///
deba@2420
    27
/// The program generates a graph from the boolean expression. Two
deba@2420
    28
/// nodes are assigned to each boolean variable, an <tt>x</tt> and a
deba@2420
    29
/// <tt>not x</tt> nodes. If there is an <tt>x or y</tt> disjunction
deba@2420
    30
/// in the formula, then the <tt>not x => y</tt> and the <tt>not y =>
deba@2420
    31
/// x</tt> edges are added to the graph. If there is a single
deba@2420
    32
/// <tt>x</tt> term disjunction in the formula then the <tt>not x
deba@2420
    33
/// =>x</tt> edge is added to the graph.
deba@2420
    34
///
deba@2420
    35
/// The boolean formula could be satified if and only if the
deba@2420
    36
/// <tt>x</tt> and <tt>not x</tt> nodes are in different strongly connected
deba@2420
    37
/// components. A feasible solution could be get from the current
deba@2420
    38
/// component numbering.
deba@2420
    39
///
deba@2420
    40
/// \include sat-2.cc
deba@2420
    41
deba@2420
    42
#include <iostream>
deba@2420
    43
#include <fstream>
deba@2420
    44
#include <sstream>
deba@2420
    45
#include <string>
deba@2420
    46
#include <map>
deba@2420
    47
deba@2420
    48
#include <lemon/smart_graph.h>
deba@2420
    49
#include <lemon/topology.h>
deba@2420
    50
deba@2420
    51
using namespace std;
deba@2420
    52
using namespace lemon;
deba@2420
    53
deba@2420
    54
deba@2420
    55
int main(int argc, const char *argv[]) {
deba@2420
    56
  if (argc != 2) {
deba@2420
    57
    std::cerr << "The SAT-2 solver demo" << std::endl << std::endl;
deba@2420
    58
    std::cerr << "The  parameter should be a filename" << std::endl;
deba@2420
    59
    std::cerr << "Each line of the file should contain a bool expression:" 
deba@2420
    60
              << std::endl;
deba@2420
    61
    std::cerr << "  [not] <variable> [or [not] <variable>]" << std::endl;
deba@2420
    62
    std::cerr << "The program prints a feasible solution if it exists" 
deba@2420
    63
              << std::endl;
deba@2420
    64
    return -1;
deba@2420
    65
  }
deba@2420
    66
  ifstream is(argv[1]);
deba@2420
    67
deba@2420
    68
  SmartGraph graph;
deba@2420
    69
  map<string, pair<SmartGraph::Node, SmartGraph::Node> > var;
deba@2420
    70
deba@2420
    71
  string line;
deba@2420
    72
  while (getline(is, line)) {
deba@2420
    73
    istringstream ls(line);
deba@2420
    74
    string var1, var2, op;
deba@2420
    75
    bool neg1 = false, neg2 = false;
deba@2420
    76
deba@2420
    77
    ls >> var1;
deba@2420
    78
    if (var1 == "not") {
deba@2420
    79
      neg1 = true;
deba@2420
    80
      ls >> var1;
deba@2420
    81
    }
deba@2420
    82
    if (ls >> op) {
deba@2420
    83
      if (op != "or") {
deba@2420
    84
        cerr << "Wrong bool expression" << std::endl;
deba@2420
    85
        return -1;
deba@2420
    86
      } else {
deba@2420
    87
        ls >> var2;
deba@2420
    88
        if (var2 == "not") {
deba@2420
    89
          neg2 = true;
deba@2420
    90
          ls >> var2;
deba@2420
    91
        }
deba@2420
    92
      }
deba@2420
    93
      if (ls >> op) {
deba@2420
    94
        cerr << "Wrong bool expression" << std::endl;
deba@2420
    95
        return -1;
deba@2420
    96
      }
deba@2420
    97
deba@2420
    98
      map<string, pair<SmartGraph::Node, SmartGraph::Node> >::iterator it1;
deba@2420
    99
      map<string, pair<SmartGraph::Node, SmartGraph::Node> >::iterator it2;    
deba@2420
   100
      it1 = var.find(var1);
deba@2420
   101
      if (it1 == var.end()) {
deba@2420
   102
        SmartGraph::Node node = graph.addNode();
deba@2420
   103
        SmartGraph::Node negNode = graph.addNode();
deba@2420
   104
        it1 = var.insert(make_pair(var1, make_pair(node, negNode))).first;
deba@2420
   105
      }
deba@2420
   106
deba@2420
   107
      it2 = var.find(var2);
deba@2420
   108
      if (it2 == var.end()) {
deba@2420
   109
        SmartGraph::Node node = graph.addNode();
deba@2420
   110
        SmartGraph::Node negNode = graph.addNode();
deba@2420
   111
        it2 = var.insert(make_pair(var2, make_pair(node, negNode))).first;
deba@2420
   112
      }
deba@2420
   113
deba@2420
   114
      graph.addEdge(neg1 ? it1->second.first : it1->second.second, 
deba@2420
   115
                    neg2 ? it2->second.second : it2->second.first);
deba@2420
   116
deba@2420
   117
      graph.addEdge(neg2 ? it2->second.first : it2->second.second, 
deba@2420
   118
                    neg1 ? it1->second.second : it1->second.first);
deba@2420
   119
    } else {
deba@2420
   120
deba@2420
   121
      map<string, pair<SmartGraph::Node, SmartGraph::Node> >::iterator it1;
deba@2420
   122
      it1 = var.find(var1);
deba@2420
   123
      if (it1 == var.end()) {
deba@2420
   124
        SmartGraph::Node node = graph.addNode();
deba@2420
   125
        SmartGraph::Node negNode = graph.addNode();
deba@2420
   126
        it1 = var.insert(make_pair(var1, make_pair(node, negNode))).first;
deba@2420
   127
      }
deba@2420
   128
      graph.addEdge(neg1 ? it1->second.first : it1->second.second, 
deba@2420
   129
                    neg1 ? it1->second.second : it1->second.first);
deba@2420
   130
      
deba@2420
   131
    }
deba@2420
   132
    
deba@2420
   133
  }
deba@2420
   134
  
deba@2420
   135
  SmartGraph::NodeMap<int> comp(graph);
deba@2420
   136
deba@2420
   137
  stronglyConnectedComponents(graph, comp); 
deba@2420
   138
deba@2420
   139
  for (map<string, pair<SmartGraph::Node, SmartGraph::Node> >::iterator
deba@2420
   140
         it = var.begin(); it != var.end(); ++it) {
deba@2420
   141
    if (comp[it->second.first] == comp[it->second.second]) {
deba@2420
   142
      std::cout << "There is no feasible solution." << std::endl;
deba@2420
   143
      return 0;
deba@2420
   144
    }
deba@2420
   145
  }
deba@2420
   146
deba@2420
   147
  for (map<string, pair<SmartGraph::Node, SmartGraph::Node> >::iterator
deba@2420
   148
         it = var.begin(); it != var.end(); ++it) {
deba@2420
   149
    if (comp[it->second.first] < comp[it->second.second]) {
deba@2420
   150
      std::cout << it->first << " = false " << std::endl;
deba@2420
   151
    } else {
deba@2420
   152
      std::cout << it->first << " = true " << std::endl;
deba@2420
   153
    }
deba@2420
   154
  }
deba@2420
   155
  
deba@2420
   156
  return 0;
deba@2420
   157
}