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