3  * This file is a part of LEMON, a generic C++ optimization library
 
     5  * Copyright (C) 2003-2007
 
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
 
     9  * Permission to use, modify and distribute this software is granted
 
    10  * provided that this copyright notice appears in all copies. For
 
    11  * precise terms see the accompanying LICENSE file.
 
    13  * This software is provided "AS IS" with no warranty of any kind,
 
    14  * express or implied, and with no claim as to its suitability for any
 
    19 #ifndef LEMON_BITS_LP_SOLVER_ID_H
 
    20 #define LEMON_BITS_LP_SOLVER_ID_H
 
    27       std::vector<int> index;
 
    28       std::vector<int> cross;
 
    38         virtual ~IdHandler() {}
 
    39         virtual int addId(LpIdImpl&) = 0;
 
    40         virtual void eraseId(LpIdImpl&, int xn) = 0;
 
    43       LpId(int min_index = 0) {
 
    46         impl.first_index = min_index;
 
    47         impl.cross.resize(impl.first_index);
 
    50       void setIdHandler(IdHandler& ih) {
 
    54       int fixId(int fn) const {return impl.cross[fn];}
 
    55       int floatingId(int xn) const {return impl.index[xn];}
 
    58         if (id_handler == 0) {
 
    59           int xn, fn = impl.cross.size();
 
    60           if (impl.first_free == -1) {
 
    61             xn = impl.index.size();
 
    62             impl.index.push_back(fn);
 
    65             impl.first_free = impl.index[impl.first_free];
 
    68           impl.cross.push_back(xn);
 
    71           return id_handler->addId(impl);
 
    75       void eraseId(int xn) {
 
    76         if (id_handler == 0) {
 
    77           int fn = impl.index[xn];
 
    78           impl.index[xn] = impl.first_free;
 
    80           for(int i = fn + 1; i < int(impl.cross.size()); ++i) {
 
    81             impl.cross[i - 1] = impl.cross[i];
 
    82             impl.index[impl.cross[i]]--;
 
    84           impl.cross.pop_back();
 
    86           id_handler->eraseId(impl, xn);
 
    90       void firstFloating(int& fn) const {
 
    91         fn = impl.first_index;
 
    92         if (fn == int(impl.cross.size())) fn = -1;
 
    95       void nextFloating(int& fn) const {
 
    97         if (fn == int(impl.cross.size())) fn = -1;
 
   100       void firstFix(int& xn) const {
 
   103         xn = fn != -1 ? fixId(fn) : -1;
 
   106       void nextFix(int& xn) const {
 
   107         int fn = floatingId(xn);
 
   109         xn = fn != -1 ? fixId(fn) : -1;    
 
   114       IdHandler *id_handler;
 
   117     class RelocateIdHandler : public LpId::IdHandler {
 
   120       virtual int addId(LpIdImpl& impl) {
 
   121         int xn, fn = impl.cross.size();
 
   122         if (impl.first_free == -1) {
 
   123           xn = impl.index.size();
 
   124           impl.index.push_back(fn);
 
   126           xn = impl.first_free;
 
   127           impl.first_free = impl.index[impl.first_free];
 
   130         impl.cross.push_back(xn);
 
   134       virtual void eraseId(LpIdImpl& impl, int xn) {
 
   135         int fn = impl.index[xn];
 
   136         impl.index[xn] = impl.first_free;
 
   137         impl.first_free = xn;
 
   138         impl.cross[fn] = impl.cross.back();
 
   139         impl.index[impl.cross.back()] = fn;
 
   140         impl.cross.pop_back();