src/work/marci/lp/expression.h
author alpar
Fri, 28 Jan 2005 08:53:48 +0000
changeset 1101 9286569c3749
parent 1097 c91e765266d7
child 1144 1cfabf245433
permissions -rw-r--r--
Wrap a long line
marci@1097
     1
// -*- c++ -*-
marci@1097
     2
#ifndef LEMON_EXPRESSION_H
marci@1097
     3
#define LEMON_EXPRESSION_H
marci@1097
     4
marci@1097
     5
#include <iostream>
marci@1097
     6
#include <map>
marci@1097
     7
marci@1097
     8
namespace lemon {
marci@1097
     9
marci@1097
    10
  /*! \brief Linear expression
marci@1097
    11
marci@1097
    12
    \c Expr<_Col,_Value> implements a class of linear expressions with the 
marci@1097
    13
    operations of addition and multiplication with scalar. 
marci@1097
    14
marci@1097
    15
    \author Marton Makai
marci@1097
    16
   */
marci@1097
    17
  template <typename _Col, typename _Value>
marci@1097
    18
  class Expr;
marci@1097
    19
marci@1097
    20
  template <typename _Col, typename _Value>
marci@1097
    21
  class Expr {
marci@1099
    22
//  protected:
marci@1099
    23
  public:
marci@1097
    24
    typedef 
marci@1097
    25
    typename std::map<_Col, _Value> Data; 
marci@1097
    26
    Data data;
marci@1097
    27
  public:
marci@1099
    28
    void simplify() {
marci@1099
    29
      for (typename Data::iterator i=data.begin(); 
marci@1099
    30
	   i!=data.end(); ++i) {
marci@1099
    31
	if ((*i).second==0) data.erase(i);
marci@1099
    32
      }
marci@1099
    33
    }
marci@1097
    34
    Expr() { }
marci@1097
    35
    Expr(_Col _col) { 
marci@1097
    36
      data.insert(std::make_pair(_col, 1));
marci@1097
    37
    }
marci@1097
    38
    Expr& operator*=(_Value _value) {
marci@1097
    39
      for (typename Data::iterator i=data.begin(); 
marci@1097
    40
	   i!=data.end(); ++i) {
marci@1097
    41
	(*i).second *= _value;
marci@1097
    42
      }
marci@1099
    43
      simplify();
marci@1097
    44
      return *this;
marci@1097
    45
    }
marci@1097
    46
    Expr& operator+=(const Expr<_Col, _Value>& expr) {
marci@1097
    47
      for (typename Data::const_iterator j=expr.data.begin(); 
marci@1097
    48
	   j!=expr.data.end(); ++j) {
marci@1097
    49
	typename Data::iterator i=data.find((*j).first);
marci@1097
    50
	if (i==data.end()) {
marci@1097
    51
	  data.insert(std::make_pair((*j).first, (*j).second));
marci@1097
    52
	} else {
marci@1097
    53
	  (*i).second+=(*j).second;
marci@1097
    54
	}
marci@1097
    55
      }
marci@1099
    56
      simplify();
marci@1099
    57
      return *this;
marci@1099
    58
    }
marci@1099
    59
    Expr& operator-=(const Expr<_Col, _Value>& expr) {
marci@1099
    60
      for (typename Data::const_iterator j=expr.data.begin(); 
marci@1099
    61
	   j!=expr.data.end(); ++j) {
marci@1099
    62
	typename Data::iterator i=data.find((*j).first);
marci@1099
    63
	if (i==data.end()) {
marci@1099
    64
	  data.insert(std::make_pair((*j).first, -(*j).second));
marci@1099
    65
	} else {
marci@1099
    66
	  (*i).second+=-(*j).second;
marci@1099
    67
	}
marci@1099
    68
      }
marci@1099
    69
      simplify();
marci@1097
    70
      return *this;
marci@1097
    71
    }
marci@1097
    72
    template <typename _C, typename _V> 
marci@1097
    73
    friend std::ostream& operator<<(std::ostream& os, 
marci@1097
    74
				    const Expr<_C, _V>& expr);
marci@1097
    75
  };
marci@1097
    76
marci@1097
    77
  template <typename _Col, typename _Value>
marci@1097
    78
  Expr<_Col, _Value> operator*(_Value _value, _Col _col) {
marci@1097
    79
    Expr<_Col, _Value> tmp(_col);
marci@1097
    80
    tmp*=_value;
marci@1099
    81
    tmp.simplify();
marci@1097
    82
    return tmp;
marci@1097
    83
  }
marci@1097
    84
marci@1097
    85
  template <typename _Col, typename _Value>
marci@1097
    86
  Expr<_Col, _Value> operator*(_Value _value, 
marci@1097
    87
			       const Expr<_Col, _Value>& expr) {
marci@1097
    88
    Expr<_Col, _Value> tmp(expr);
marci@1097
    89
    tmp*=_value;
marci@1099
    90
    tmp.simplify();
marci@1097
    91
    return tmp;
marci@1097
    92
  }
marci@1097
    93
marci@1097
    94
  template <typename _Col, typename _Value>
marci@1097
    95
  Expr<_Col, _Value> operator+(const Expr<_Col, _Value>& expr1, 
marci@1097
    96
			       const Expr<_Col, _Value>& expr2) {
marci@1097
    97
    Expr<_Col, _Value> tmp(expr1);
marci@1097
    98
    tmp+=expr2;
marci@1099
    99
    tmp.simplify();
marci@1099
   100
    return tmp;
marci@1099
   101
  }
marci@1099
   102
marci@1099
   103
  template <typename _Col, typename _Value>
marci@1099
   104
  Expr<_Col, _Value> operator-(const Expr<_Col, _Value>& expr1, 
marci@1099
   105
			       const Expr<_Col, _Value>& expr2) {
marci@1099
   106
    Expr<_Col, _Value> tmp(expr1);
marci@1099
   107
    tmp-=expr2;
marci@1099
   108
    tmp.simplify();
marci@1097
   109
    return tmp;
marci@1097
   110
  }
marci@1097
   111
marci@1097
   112
  template <typename _Col, typename _Value>
marci@1097
   113
  std::ostream& operator<<(std::ostream& os, 
marci@1097
   114
			   const Expr<_Col, _Value>& expr) {
marci@1097
   115
    for (typename Expr<_Col, _Value>::Data::const_iterator i=
marci@1097
   116
	   expr.data.begin(); 
marci@1097
   117
	 i!=expr.data.end(); ++i) {
marci@1097
   118
      os << (*i).second << "*" << (*i).first << " ";
marci@1097
   119
    }
marci@1097
   120
    return os;
marci@1097
   121
  }
marci@1097
   122
  
marci@1097
   123
} //namespace lemon
marci@1097
   124
marci@1097
   125
#endif //LEMON_EXPRESSION_H