Reimplemented Suurballe class.
- The new version is the specialized version of CapacityScaling.
- It is about 10-20 times faster than the former Suurballe algorithm
and about 20-50 percent faster than CapacityScaling.
- Doc improvements.
- The test file is also replaced.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2008
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();