alpar@1677
|
1 |
/* -*- C++ -*-
|
alpar@1677
|
2 |
* lemon/iterable_maps.h - Part of LEMON, a generic C++ optimization library
|
alpar@1677
|
3 |
*
|
alpar@1677
|
4 |
* Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
alpar@1677
|
5 |
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
alpar@1677
|
6 |
*
|
alpar@1677
|
7 |
* Permission to use, modify and distribute this software is granted
|
alpar@1677
|
8 |
* provided that this copyright notice appears in all copies. For
|
alpar@1677
|
9 |
* precise terms see the accompanying LICENSE file.
|
alpar@1677
|
10 |
*
|
alpar@1677
|
11 |
* This software is provided "AS IS" with no warranty of any kind,
|
alpar@1677
|
12 |
* express or implied, and with no claim as to its suitability for any
|
alpar@1677
|
13 |
* purpose.
|
alpar@1677
|
14 |
*
|
alpar@1677
|
15 |
*/
|
alpar@1677
|
16 |
|
alpar@1677
|
17 |
#include <vector>
|
alpar@1677
|
18 |
#include <limits>
|
alpar@1677
|
19 |
|
alpar@1677
|
20 |
///\ingroup maps
|
alpar@1677
|
21 |
///\file
|
alpar@1677
|
22 |
///\brief Maps that makes it possible to iterate through the keys having
|
alpar@1677
|
23 |
///a certain value
|
alpar@1677
|
24 |
///
|
alpar@1677
|
25 |
///
|
alpar@1677
|
26 |
|
alpar@1677
|
27 |
|
alpar@1677
|
28 |
namespace lemon {
|
alpar@1677
|
29 |
|
alpar@1677
|
30 |
///\todo This is only a static map!
|
alpar@1677
|
31 |
///\param BaseMap is an interger map.
|
alpar@1677
|
32 |
template<class BaseMap>
|
alpar@1677
|
33 |
class IterableBoolMap
|
alpar@1677
|
34 |
{
|
alpar@1677
|
35 |
public:
|
alpar@1677
|
36 |
|
alpar@1677
|
37 |
typedef typename BaseMap::Key Key;
|
alpar@1677
|
38 |
typedef bool Value;
|
alpar@1677
|
39 |
|
alpar@1677
|
40 |
friend class RefType;
|
alpar@1677
|
41 |
friend class FalseIt;
|
alpar@1677
|
42 |
friend class TrueIt;
|
alpar@1677
|
43 |
|
alpar@1677
|
44 |
private:
|
alpar@1677
|
45 |
BaseMap &cref;
|
alpar@1677
|
46 |
std::vector<Key> vals;
|
alpar@1677
|
47 |
int sep; //map[e] is true <=> cref[e]>=sep
|
alpar@1677
|
48 |
|
alpar@1677
|
49 |
bool isTrue(Key k) {return cref[k]>=sep;}
|
alpar@1677
|
50 |
void swap(Key k, int s)
|
alpar@1677
|
51 |
{
|
alpar@1677
|
52 |
int ti=cref[k];
|
alpar@1677
|
53 |
Key tk=vals[s];
|
alpar@1677
|
54 |
cref[k]=s; vals[s]=k;
|
alpar@1677
|
55 |
cref[tk]=ti; vals[ti]=tk;
|
alpar@1677
|
56 |
}
|
alpar@1677
|
57 |
|
alpar@1677
|
58 |
void setTrue(Key k) { if(cref[k]<sep) { sep--; swap(k,sep); } }
|
alpar@1677
|
59 |
void setFalse(Key k) { if(cref[k]>=sep) { swap(k,sep); sep++; } }
|
alpar@1677
|
60 |
|
alpar@1677
|
61 |
public:
|
alpar@1677
|
62 |
///\e
|
alpar@1677
|
63 |
void set(Key k,Value v) { if(v) setTrue(k); else setFalse(k);}
|
alpar@1677
|
64 |
|
alpar@1677
|
65 |
///\e
|
alpar@1677
|
66 |
class FalseIt
|
alpar@1677
|
67 |
{
|
alpar@1677
|
68 |
const IterableBoolMap &M;
|
alpar@1677
|
69 |
int i;
|
alpar@1677
|
70 |
public:
|
alpar@1677
|
71 |
explicit FalseIt(const IterableBoolMap &_M) : M(_M), i(0) { }
|
alpar@1677
|
72 |
FalseIt(Invalid)
|
alpar@1677
|
73 |
: M(*((IterableBoolMap*)(0))), i(std::numeric_limits<int>::max()) { }
|
alpar@1677
|
74 |
FalseIt &operator++() { ++i; return *this;}
|
alpar@1677
|
75 |
operator Key() const { return i<M.sep ? M.vals[i] : INVALID; }
|
alpar@1677
|
76 |
bool operator !=(Invalid) const { return i<M.sep; }
|
alpar@1677
|
77 |
bool operator ==(Invalid) const { return i>=M.sep; }
|
alpar@1677
|
78 |
};
|
alpar@1677
|
79 |
///\e
|
alpar@1677
|
80 |
class TrueIt
|
alpar@1677
|
81 |
{
|
alpar@1677
|
82 |
const IterableBoolMap &M;
|
alpar@1677
|
83 |
int i;
|
alpar@1677
|
84 |
public:
|
alpar@1677
|
85 |
explicit TrueIt(const IterableBoolMap &_M)
|
alpar@1677
|
86 |
: M(_M), i(M.vals.size()-1) { }
|
alpar@1677
|
87 |
TrueIt(Invalid)
|
alpar@1677
|
88 |
: M(*((IterableBoolMap*)(0))), i(-1) { }
|
alpar@1677
|
89 |
TrueIt &operator++() { --i; return *this;}
|
alpar@1677
|
90 |
operator Key() const { return i>=M.sep ? M.vals[i] : INVALID; }
|
alpar@1677
|
91 |
bool operator !=(Invalid) const { return i>=M.sep; }
|
alpar@1677
|
92 |
bool operator ==(Invalid) const { return i<M.sep; }
|
alpar@1677
|
93 |
};
|
alpar@1677
|
94 |
|
alpar@1677
|
95 |
///\e
|
alpar@1677
|
96 |
class RefType
|
alpar@1677
|
97 |
{
|
alpar@1677
|
98 |
IterableBoolMap &M;
|
alpar@1677
|
99 |
Key k;
|
alpar@1677
|
100 |
public:
|
alpar@1677
|
101 |
RefType(IterableBoolMap &_M,Key _k) : M(_M), k(_k) { }
|
alpar@1677
|
102 |
|
alpar@1677
|
103 |
operator Value() const
|
alpar@1677
|
104 |
{
|
alpar@1677
|
105 |
return M.isTrue(k);
|
alpar@1677
|
106 |
}
|
alpar@1677
|
107 |
Value operator = (Value v) const { M.set(k,v); return v; }
|
alpar@1677
|
108 |
};
|
alpar@1677
|
109 |
|
alpar@1677
|
110 |
public:
|
alpar@1677
|
111 |
explicit IterableBoolMap(BaseMap &_m,bool init=false) : cref(_m)
|
alpar@1677
|
112 |
{
|
alpar@1677
|
113 |
sep=0;
|
alpar@1677
|
114 |
for(typename BaseMap::MapSet::iterator i=cref.mapSet().begin();
|
alpar@1677
|
115 |
i!=cref.mapSet().end();
|
alpar@1677
|
116 |
++i) {
|
alpar@1677
|
117 |
i->second=sep;
|
alpar@1677
|
118 |
vals.push_back(i->first);
|
alpar@1677
|
119 |
sep++;
|
alpar@1677
|
120 |
}
|
alpar@1677
|
121 |
if(init) sep=0;
|
alpar@1677
|
122 |
}
|
alpar@1677
|
123 |
RefType operator[] (Key k) { return RefType(*this,k);}
|
alpar@1677
|
124 |
Value operator[] (Key k) const { return isTrue(k);}
|
alpar@1677
|
125 |
};
|
alpar@1677
|
126 |
|
alpar@1677
|
127 |
|
alpar@1677
|
128 |
|
alpar@1677
|
129 |
|
alpar@1677
|
130 |
/// \addtogroup graph_maps
|
alpar@1677
|
131 |
/// @{
|
alpar@1677
|
132 |
|
alpar@1677
|
133 |
/// Iterable bool NodeMap
|
alpar@1677
|
134 |
|
alpar@1677
|
135 |
/// This map can be used in the same way
|
alpar@1677
|
136 |
/// as the standard NodeMap<bool> of the
|
alpar@1677
|
137 |
/// given graph \c Graph.
|
alpar@1677
|
138 |
/// In addition, this class provides two iterators called \ref TrueIt
|
alpar@1677
|
139 |
/// and \ref FalseIt to iterate through the "true" and "false" nodes.
|
alpar@1677
|
140 |
template <class Graph>
|
alpar@1677
|
141 |
class IterableBoolNodeMap
|
alpar@1677
|
142 |
{
|
alpar@1677
|
143 |
typename Graph::NodeMap<int> cmap;
|
alpar@1677
|
144 |
|
alpar@1677
|
145 |
public:
|
alpar@1677
|
146 |
|
alpar@1677
|
147 |
typedef IterableBoolMap<typename Graph::NodeMap<int> > BimType;
|
alpar@1677
|
148 |
BimType imap;
|
alpar@1677
|
149 |
|
alpar@1677
|
150 |
|
alpar@1677
|
151 |
typedef typename BimType::RefType RefType;
|
alpar@1677
|
152 |
typedef typename Graph::Node Key;
|
alpar@1677
|
153 |
typedef bool Value;
|
alpar@1677
|
154 |
|
alpar@1677
|
155 |
friend class FalseIt;
|
alpar@1677
|
156 |
friend class TrueIt;
|
alpar@1677
|
157 |
|
alpar@1677
|
158 |
///\e
|
alpar@1677
|
159 |
IterableBoolNodeMap(const Graph &g,bool b=false) : cmap(g), imap(cmap,b) {}
|
alpar@1677
|
160 |
|
alpar@1677
|
161 |
public:
|
alpar@1677
|
162 |
///\e
|
alpar@1677
|
163 |
void set(Key k, bool v) { imap.set(k,v);}
|
alpar@1677
|
164 |
#ifdef DOXYGEN
|
alpar@1677
|
165 |
///\e
|
alpar@1677
|
166 |
bool &operator[](Key k) { return imap[k];}
|
alpar@1677
|
167 |
///\e
|
alpar@1677
|
168 |
const bool &operator[](Key k) const { return imap[k];}
|
alpar@1677
|
169 |
#else
|
alpar@1677
|
170 |
Value operator[](Key k) const { return imap[k];}
|
alpar@1677
|
171 |
RefType operator[](Key k) { return imap[k];}
|
alpar@1677
|
172 |
#endif
|
alpar@1677
|
173 |
///Iterator for the "false" nodes
|
alpar@1677
|
174 |
class FalseIt : public BimType::FalseIt
|
alpar@1677
|
175 |
{
|
alpar@1677
|
176 |
public:
|
alpar@1677
|
177 |
explicit FalseIt(const IterableBoolNodeMap &m)
|
alpar@1677
|
178 |
: BimType::FalseIt(m.imap) { }
|
alpar@1677
|
179 |
FalseIt(Invalid i) : BimType::FalseIt(i) { }
|
alpar@1677
|
180 |
};
|
alpar@1677
|
181 |
///Iterator for the "true" nodes
|
alpar@1677
|
182 |
class TrueIt : public BimType::TrueIt
|
alpar@1677
|
183 |
{
|
alpar@1677
|
184 |
public:
|
alpar@1677
|
185 |
explicit TrueIt(const IterableBoolNodeMap &m)
|
alpar@1677
|
186 |
: BimType::TrueIt(m.imap) { }
|
alpar@1677
|
187 |
TrueIt(Invalid i) : BimType::TrueIt(i) { }
|
alpar@1677
|
188 |
};
|
alpar@1677
|
189 |
};
|
alpar@1677
|
190 |
|
alpar@1677
|
191 |
/// Iterable bool EdgeMap
|
alpar@1677
|
192 |
|
alpar@1677
|
193 |
/// This map can be used in the same way
|
alpar@1677
|
194 |
/// as the standard EdgeMap<bool> of the
|
alpar@1677
|
195 |
/// given graph \c Graph.
|
alpar@1677
|
196 |
/// In addition, this class provides two iterators called \ref TrueIt
|
alpar@1677
|
197 |
/// and \ref FalseIt to iterate through the "true" and "false" edges.
|
alpar@1677
|
198 |
template <class Graph>
|
alpar@1677
|
199 |
class IterableBoolEdgeMap
|
alpar@1677
|
200 |
{
|
alpar@1677
|
201 |
typename Graph::EdgeMap<int> cmap;
|
alpar@1677
|
202 |
|
alpar@1677
|
203 |
public:
|
alpar@1677
|
204 |
|
alpar@1677
|
205 |
typedef IterableBoolMap<typename Graph::EdgeMap<int> > BimType;
|
alpar@1677
|
206 |
BimType imap;
|
alpar@1677
|
207 |
|
alpar@1677
|
208 |
|
alpar@1677
|
209 |
typedef typename BimType::RefType RefType;
|
alpar@1677
|
210 |
typedef typename Graph::Edge Key;
|
alpar@1677
|
211 |
typedef bool Value;
|
alpar@1677
|
212 |
|
alpar@1677
|
213 |
friend class FalseIt;
|
alpar@1677
|
214 |
friend class TrueIt;
|
alpar@1677
|
215 |
|
alpar@1677
|
216 |
///\e
|
alpar@1677
|
217 |
IterableBoolEdgeMap(const Graph &g,bool b=false) : cmap(g), imap(cmap,b) {}
|
alpar@1677
|
218 |
|
alpar@1677
|
219 |
public:
|
alpar@1677
|
220 |
///\e
|
alpar@1677
|
221 |
void set(Key k, bool v) { imap.set(k,v);}
|
alpar@1677
|
222 |
#ifdef DOXYGEN
|
alpar@1677
|
223 |
///\e
|
alpar@1677
|
224 |
bool &operator[](Key k) { return imap[k];}
|
alpar@1677
|
225 |
///\e
|
alpar@1677
|
226 |
const bool &operator[](Key k) const { return imap[k];}
|
alpar@1677
|
227 |
#else
|
alpar@1677
|
228 |
Value operator[](Key k) const { return imap[k];}
|
alpar@1677
|
229 |
RefType operator[](Key k) { return imap[k];}
|
alpar@1677
|
230 |
#endif
|
alpar@1677
|
231 |
///Iterator for the "false" edges
|
alpar@1677
|
232 |
class FalseIt : public BimType::FalseIt
|
alpar@1677
|
233 |
{
|
alpar@1677
|
234 |
public:
|
alpar@1677
|
235 |
explicit FalseIt(const IterableBoolEdgeMap &m)
|
alpar@1677
|
236 |
: BimType::FalseIt(m.imap) { }
|
alpar@1677
|
237 |
FalseIt(Invalid i) : BimType::FalseIt(i) { }
|
alpar@1677
|
238 |
};
|
alpar@1677
|
239 |
///Iterator for the "true" edges
|
alpar@1677
|
240 |
class TrueIt : public BimType::TrueIt
|
alpar@1677
|
241 |
{
|
alpar@1677
|
242 |
public:
|
alpar@1677
|
243 |
explicit TrueIt(const IterableBoolEdgeMap &m)
|
alpar@1677
|
244 |
: BimType::TrueIt(m.imap) { }
|
alpar@1677
|
245 |
TrueIt(Invalid i) : BimType::TrueIt(i) { }
|
alpar@1677
|
246 |
};
|
alpar@1677
|
247 |
};
|
alpar@1677
|
248 |
|
alpar@1677
|
249 |
/// @}
|
alpar@1677
|
250 |
}
|