lemon/bits/lp_id.h
author deba
Thu, 01 Mar 2007 16:47:49 +0000
changeset 2382 678bea23ed75
child 2386 81b47fc5c444
permissions -rw-r--r--
2-approximation of Steiner-tree problem
deba@2363
     1
/* -*- C++ -*-
deba@2363
     2
 *
deba@2363
     3
 * This file is a part of LEMON, a generic C++ optimization library
deba@2363
     4
 *
deba@2363
     5
 * Copyright (C) 2003-2006
deba@2363
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@2363
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@2363
     8
 *
deba@2363
     9
 * Permission to use, modify and distribute this software is granted
deba@2363
    10
 * provided that this copyright notice appears in all copies. For
deba@2363
    11
 * precise terms see the accompanying LICENSE file.
deba@2363
    12
 *
deba@2363
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@2363
    14
 * express or implied, and with no claim as to its suitability for any
deba@2363
    15
 * purpose.
deba@2363
    16
 *
deba@2363
    17
 */
deba@2363
    18
deba@2363
    19
#ifndef LEMON_BITS_LP_SOLVER_ID_H
deba@2363
    20
#define LEMON_BITS_LP_SOLVER_ID_H
deba@2363
    21
deba@2363
    22
namespace lemon {
deba@2363
    23
  
deba@2363
    24
  namespace _lp_bits {
deba@2363
    25
deba@2363
    26
    struct LpIdImpl {
deba@2363
    27
      std::vector<int> index;
deba@2363
    28
      std::vector<int> cross;
deba@2363
    29
      int first_index;
deba@2363
    30
      int first_free;      
deba@2363
    31
    };
deba@2363
    32
deba@2363
    33
    class LpId {
deba@2363
    34
    public:
deba@2363
    35
      
deba@2363
    36
      class IdHandler {
deba@2363
    37
      public:
deba@2363
    38
        virtual ~IdHandler() {}
deba@2363
    39
        virtual int addId(LpIdImpl&) = 0;
deba@2363
    40
        virtual void eraseId(LpIdImpl&, int xn) = 0;
deba@2363
    41
      };
deba@2363
    42
      
deba@2363
    43
      LpId(int min_index = 0) {
deba@2363
    44
        id_handler = 0;
deba@2363
    45
        impl.first_free = -1;
deba@2363
    46
        impl.first_index = min_index;
deba@2363
    47
        impl.cross.resize(impl.first_index);
deba@2363
    48
      }
deba@2363
    49
deba@2363
    50
      void setIdHandler(IdHandler& ih) {
deba@2363
    51
        id_handler = &ih;
deba@2363
    52
      }
deba@2363
    53
      
deba@2363
    54
      int fixId(int fn) const {return impl.cross[fn];}
deba@2363
    55
      int floatingId(int xn) const {return impl.index[xn];}
deba@2363
    56
      
deba@2363
    57
      int addId() {
deba@2363
    58
        if (id_handler == 0) {
deba@2363
    59
          int xn, fn = impl.cross.size();
deba@2363
    60
          if (impl.first_free == -1) {
deba@2363
    61
            xn = impl.index.size();
deba@2363
    62
            impl.index.push_back(fn);
deba@2363
    63
          } else {
deba@2363
    64
            xn = impl.first_free;
deba@2363
    65
            impl.first_free = impl.index[impl.first_free];
deba@2363
    66
            impl.index[xn] = fn;
deba@2363
    67
          }
deba@2363
    68
          impl.cross.push_back(xn);
deba@2363
    69
          return xn;
deba@2363
    70
        } else {
deba@2363
    71
          return id_handler->addId(impl);
deba@2363
    72
        }
deba@2363
    73
      }
deba@2363
    74
deba@2363
    75
      void eraseId(int xn) {
deba@2363
    76
        if (id_handler == 0) {
deba@2363
    77
          int fn = impl.index[xn];
deba@2363
    78
          impl.index[xn] = impl.first_free;
deba@2363
    79
          impl.first_free = xn;
deba@2363
    80
          for(int i = fn + 1; i < (int)impl.cross.size(); ++i) {
deba@2363
    81
            impl.cross[i - 1] = impl.cross[i];
deba@2363
    82
            impl.index[impl.cross[i]]--;
deba@2363
    83
          }
deba@2363
    84
          impl.cross.pop_back();
deba@2363
    85
        } else {
deba@2363
    86
          id_handler->eraseId(impl, xn);
deba@2363
    87
        }
deba@2363
    88
      }
deba@2363
    89
deba@2363
    90
      void firstFloating(int& fn) const {
deba@2363
    91
        fn = impl.first_index;
deba@2363
    92
        if (fn == (int)impl.cross.size()) fn = -1;
deba@2363
    93
      }
deba@2363
    94
deba@2363
    95
      void nextFloating(int& fn) const {
deba@2363
    96
        ++fn;
deba@2363
    97
        if (fn == (int)impl.cross.size()) fn = -1;
deba@2363
    98
      }
deba@2363
    99
deba@2363
   100
      void firstFix(int& xn) const {
deba@2363
   101
        int fn;
deba@2363
   102
        firstFloating(fn);
deba@2363
   103
        xn = fn != -1 ? fixId(fn) : -1;
deba@2363
   104
      }
deba@2363
   105
      
deba@2363
   106
      void nextFix(int& xn) const {
deba@2363
   107
        int fn = floatingId(xn);
deba@2363
   108
        nextFloating(fn);
deba@2363
   109
        xn = fn != -1 ? fixId(fn) : -1;    
deba@2363
   110
      }
deba@2363
   111
deba@2363
   112
    protected:
deba@2363
   113
      LpIdImpl impl;
deba@2363
   114
      IdHandler *id_handler;
deba@2363
   115
    };
deba@2363
   116
  
deba@2363
   117
    class RelocateIdHandler : public LpId::IdHandler {
deba@2363
   118
    public:
deba@2363
   119
deba@2363
   120
      virtual int addId(LpIdImpl& impl) {
deba@2363
   121
        int xn, fn = impl.cross.size();
deba@2363
   122
        if (impl.first_free == -1) {
deba@2363
   123
          xn = impl.index.size();
deba@2363
   124
          impl.index.push_back(fn);
deba@2363
   125
        } else {
deba@2363
   126
          xn = impl.first_free;
deba@2363
   127
          impl.first_free = impl.index[impl.first_free];
deba@2363
   128
          impl.index[xn] = fn;
deba@2363
   129
        }
deba@2363
   130
        impl.cross.push_back(xn);
deba@2363
   131
        return xn;
deba@2363
   132
      }
deba@2363
   133
deba@2363
   134
      virtual void eraseId(LpIdImpl& impl, int xn) {
deba@2363
   135
        int fn = impl.index[xn];
deba@2363
   136
        impl.index[xn] = impl.first_free;
deba@2363
   137
        impl.first_free = xn;
deba@2363
   138
        impl.cross[fn] = impl.cross.back();
deba@2363
   139
        impl.index[impl.cross.back()] = fn;
deba@2363
   140
        impl.cross.pop_back();
deba@2363
   141
      }
deba@2363
   142
    };
deba@2363
   143
  }  
deba@2363
   144
}
deba@2363
   145
deba@2363
   146
#endif