lemon/bits/solver_bits.h
author Akos Ladanyi <ladanyi@tmit.bme.hu>
Tue, 18 Aug 2009 21:39:35 +0100
changeset 513 17cabb114d52
child 519 c786cd201266
permissions -rw-r--r--
Remove duplicate list_graph.h entry from source list (#308)
deba@459
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@459
     2
 *
deba@459
     3
 * This file is a part of LEMON, a generic C++ optimization library.
deba@459
     4
 *
deba@459
     5
 * Copyright (C) 2003-2008
deba@459
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@459
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@459
     8
 *
deba@459
     9
 * Permission to use, modify and distribute this software is granted
deba@459
    10
 * provided that this copyright notice appears in all copies. For
deba@459
    11
 * precise terms see the accompanying LICENSE file.
deba@459
    12
 *
deba@459
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@459
    14
 * express or implied, and with no claim as to its suitability for any
deba@459
    15
 * purpose.
deba@459
    16
 *
deba@459
    17
 */
deba@459
    18
deba@459
    19
#ifndef LEMON_BITS_SOLVER_BITS_H
deba@459
    20
#define LEMON_BITS_SOLVER_BITS_H
deba@459
    21
deba@459
    22
namespace lemon {
deba@459
    23
deba@459
    24
  namespace _solver_bits {
deba@459
    25
deba@459
    26
    class VarIndex {
deba@459
    27
    private:
deba@459
    28
      struct ItemT {
deba@459
    29
        int prev, next;
deba@459
    30
        int index;
deba@459
    31
      };
deba@459
    32
      std::vector<ItemT> items;
deba@459
    33
      int first_item, last_item, first_free_item;
deba@459
    34
deba@459
    35
      std::vector<int> cross;
deba@459
    36
deba@459
    37
    public:
deba@459
    38
deba@459
    39
      VarIndex()
deba@459
    40
        : first_item(-1), last_item(-1), first_free_item(-1) {
deba@459
    41
      }
deba@459
    42
deba@459
    43
      void clear() {
deba@459
    44
        first_item = -1;
deba@459
    45
        first_free_item = -1;
deba@459
    46
        items.clear();
deba@459
    47
        cross.clear();
deba@459
    48
      }
deba@459
    49
deba@459
    50
      int addIndex(int idx) {
deba@459
    51
        int n;
deba@459
    52
        if (first_free_item == -1) {
deba@459
    53
          n = items.size();
deba@459
    54
          items.push_back(ItemT());
deba@459
    55
        } else {
deba@459
    56
          n = first_free_item;
deba@459
    57
          first_free_item = items[n].next;
deba@459
    58
          if (first_free_item != -1) {
deba@459
    59
            items[first_free_item].prev = -1;
deba@459
    60
          }
deba@459
    61
        }
deba@459
    62
        items[n].index = idx;
deba@459
    63
        if (static_cast<int>(cross.size()) <= idx) {
deba@459
    64
          cross.resize(idx + 1, -1);
deba@459
    65
        }
deba@459
    66
        cross[idx] = n;
deba@459
    67
deba@459
    68
        items[n].prev = last_item;
deba@459
    69
        items[n].next = -1;
deba@459
    70
        if (last_item != -1) {
deba@459
    71
          items[last_item].next = n;
deba@459
    72
        } else {
deba@459
    73
          first_item = n;
deba@459
    74
        }
deba@459
    75
        last_item = n;
deba@459
    76
deba@459
    77
        return n;
deba@459
    78
      }
deba@459
    79
deba@459
    80
      int addIndex(int idx, int n) {
deba@459
    81
        while (n >= static_cast<int>(items.size())) {
deba@459
    82
          items.push_back(ItemT());
deba@459
    83
          items.back().prev = -1;
deba@459
    84
          items.back().next = first_free_item;
deba@459
    85
          if (first_free_item != -1) {
deba@459
    86
            items[first_free_item].prev = items.size() - 1;
deba@459
    87
          }
deba@459
    88
          first_free_item = items.size() - 1;
deba@459
    89
        }
deba@459
    90
        if (items[n].next != -1) {
deba@459
    91
          items[items[n].next].prev = items[n].prev;
deba@459
    92
        }
deba@459
    93
        if (items[n].prev != -1) {
deba@459
    94
          items[items[n].prev].next = items[n].next;
deba@459
    95
        } else {
deba@459
    96
          first_free_item = items[n].next;
deba@459
    97
        }
deba@459
    98
deba@459
    99
        items[n].index = idx;
deba@459
   100
        if (static_cast<int>(cross.size()) <= idx) {
deba@459
   101
          cross.resize(idx + 1, -1);
deba@459
   102
        }
deba@459
   103
        cross[idx] = n;
deba@459
   104
deba@459
   105
        items[n].prev = last_item;
deba@459
   106
        items[n].next = -1;
deba@459
   107
        if (last_item != -1) {
deba@459
   108
          items[last_item].next = n;
deba@459
   109
        } else {
deba@459
   110
          first_item = n;
deba@459
   111
        }
deba@459
   112
        last_item = n;
deba@459
   113
deba@459
   114
        return n;
deba@459
   115
      }
deba@459
   116
deba@459
   117
      void eraseIndex(int idx) {
deba@459
   118
        int n = cross[idx];
deba@459
   119
deba@459
   120
        if (items[n].prev != -1) {
deba@459
   121
          items[items[n].prev].next = items[n].next;
deba@459
   122
        } else {
deba@459
   123
          first_item = items[n].next;
deba@459
   124
        }
deba@459
   125
        if (items[n].next != -1) {
deba@459
   126
          items[items[n].next].prev = items[n].prev;
deba@459
   127
        } else {
deba@459
   128
          last_item = items[n].prev;
deba@459
   129
        }
deba@459
   130
deba@459
   131
        if (first_free_item != -1) {
deba@459
   132
          items[first_free_item].prev = n;
deba@459
   133
        }
deba@459
   134
        items[n].next = first_free_item;
deba@459
   135
        items[n].prev = -1;
deba@459
   136
        first_free_item = n;
deba@459
   137
deba@459
   138
        while (!cross.empty() && cross.back() == -1) {
deba@459
   139
          cross.pop_back();
deba@459
   140
        }
deba@459
   141
      }
deba@459
   142
deba@459
   143
      int maxIndex() const {
deba@459
   144
        return cross.size() - 1;
deba@459
   145
      }
deba@459
   146
deba@459
   147
      void shiftIndices(int idx) {
deba@459
   148
        for (int i = idx + 1; i < static_cast<int>(cross.size()); ++i) {
deba@459
   149
          cross[i - 1] = cross[i];
deba@459
   150
          if (cross[i] != -1) {
deba@459
   151
            --items[cross[i]].index;
deba@459
   152
          }
deba@459
   153
        }
deba@459
   154
        cross.back() = -1;
deba@459
   155
        cross.pop_back();
deba@459
   156
        while (!cross.empty() && cross.back() == -1) {
deba@459
   157
          cross.pop_back();
deba@459
   158
        }
deba@459
   159
      }
deba@459
   160
deba@459
   161
      void relocateIndex(int idx, int jdx) {
deba@459
   162
        cross[idx] = cross[jdx];
deba@459
   163
        items[cross[jdx]].index = idx;
deba@459
   164
        cross[jdx] = -1;
deba@459
   165
deba@459
   166
        while (!cross.empty() && cross.back() == -1) {
deba@459
   167
          cross.pop_back();
deba@459
   168
        }
deba@459
   169
      }
deba@459
   170
deba@459
   171
      int operator[](int idx) const {
deba@459
   172
        return cross[idx];
deba@459
   173
      }
deba@459
   174
deba@459
   175
      int operator()(int fdx) const {
deba@459
   176
        return items[fdx].index;
deba@459
   177
      }
deba@459
   178
deba@459
   179
      void firstItem(int& fdx) const {
deba@459
   180
        fdx = first_item;
deba@459
   181
      }
deba@459
   182
deba@459
   183
      void nextItem(int& fdx) const {
deba@459
   184
        fdx = items[fdx].next;
deba@459
   185
      }
deba@459
   186
deba@459
   187
    };
deba@459
   188
  }
deba@459
   189
}
deba@459
   190
deba@459
   191
#endif