Skip to content

Commit 3ddd849

Browse files
committed
Fix weighted set propagator (sometimes missed some cardinality reasoning)
git-svn-id: file:///Volumes/GecodeGitMigration/gecode-svn-mirror/gecode/trunk@15225 e85b7adc-8362-4630-8c63-7469d557c915
1 parent 1c59f46 commit 3ddd849

File tree

2 files changed

+21
-19
lines changed

2 files changed

+21
-19
lines changed

gecode/set/int/weights.hpp

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -251,34 +251,37 @@ namespace Gecode { namespace Set { namespace Int {
251251
template<class View>
252252
ExecStatus
253253
Weights<View>::propagate(Space& home, const ModEventDelta&) {
254-
255254
ModEvent me = ME_SET_NONE;
256255

257256
if (!x.assigned()) {
258257
// Collect the weights of the elements in the unknown set in an array
259258
int size = elements.size();
260259
Region r(home);
261-
int* currentWeights = r.alloc<int>(size);
260+
int* minWeights = r.alloc<int>(size);
261+
int* maxWeights = r.alloc<int>(size);
262262

263263
UnknownRanges<View> ur(x);
264264
Iter::Ranges::ToValues<UnknownRanges<View> > urv(ur);
265265
for (int i=0; i<size; i++) {
266266
if (!urv() || elements[i]<urv.val()) {
267-
currentWeights[i] = 0;
267+
minWeights[i] = INT_MAX;
268+
maxWeights[i] = INT_MIN;
268269
} else {
269270
assert(elements[i] == urv.val());
270-
currentWeights[i] = weights[i];
271+
minWeights[i] = weights[i];
272+
maxWeights[i] = weights[i];
271273
++urv;
272274
}
273275
}
274276

275277
// Sort the weights of the unknown elements
276278
IntLess il;
277-
Support::quicksort<int>(currentWeights, size, il);
279+
Support::quicksort<int>(minWeights, size, il);
280+
Support::quicksort<int>(maxWeights, size, il);
278281

279282
// The maximum number of elements that can still be added to x
280283
int delta = static_cast<int>(std::min(x.unknownSize(), x.cardMax() - x.glbSize()));
281-
284+
282285
// The weight of the elements already in x
283286
GlbRanges<View> glb(x);
284287
int glbWeight = weightI<GlbRanges<View> >(elements, weights, glb);
@@ -290,27 +293,27 @@ namespace Gecode { namespace Set { namespace Int {
290293
// all other elements are minimal)
291294
int lowWeight = glbWeight;
292295
for (int i=0; i<delta-1; i++) {
293-
if (currentWeights[i] >= 0)
296+
if (minWeights[i] >= 0)
294297
break;
295-
lowWeight+=currentWeights[i];
298+
lowWeight+=minWeights[i];
296299
}
297300

298301
// Compute the lowest possible weight of x. If there is another element
299302
// with negative weight left, then add its weight to lowWeight.
300303
// Otherwise lowWeight is already the lowest possible weight.
301304
int lowestWeight = lowWeight;
302-
if (delta>0 && currentWeights[delta-1]<0)
303-
lowestWeight+=currentWeights[delta-1];
305+
if (delta>0 && minWeights[delta-1]<0)
306+
lowestWeight+=minWeights[delta-1];
304307

305308
// If after including the minimal number of required elements,
306309
// no more element with negative weight is available, then
307310
// a tighter lower bound can be computed.
308311
if ( (x.cardMin() - x.glbSize() > 0 &&
309-
currentWeights[x.cardMin() - x.glbSize() - 1] >= 0) ||
310-
currentWeights[0] >= 0 ) {
312+
minWeights[x.cardMin() - x.glbSize() - 1] >= 0) ||
313+
minWeights[0] >= 0 ) {
311314
int lowestPosWeight = glbWeight;
312315
for (unsigned int i=0; i<x.cardMin() - x.glbSize(); i++) {
313-
lowestPosWeight += currentWeights[i];
316+
lowestPosWeight += minWeights[i];
314317
}
315318
lowestWeight = std::max(lowestWeight, lowestPosWeight);
316319
}
@@ -320,9 +323,9 @@ namespace Gecode { namespace Set { namespace Int {
320323
// upper bound.
321324
int highestWeight = glbWeight;
322325
for (int i=0; i<delta; i++) {
323-
if (currentWeights[size-i-1]<=0)
326+
if (maxWeights[size-i-1]<=0)
324327
break;
325-
highestWeight += currentWeights[size-i-1];
328+
highestWeight += maxWeights[size-i-1];
326329
}
327330

328331
// Prune the weight using the computed bounds
@@ -352,7 +355,8 @@ namespace Gecode { namespace Set { namespace Int {
352355
return home.ES_SUBSUMED(*this);
353356
}
354357

355-
return me_modified(me) ? ES_NOFIX : ES_FIX;
358+
// return me_modified(me) ? ES_NOFIX : ES_FIX;
359+
return ES_NOFIX;
356360
}
357361

358362
}}}

test/set/int.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -384,9 +384,7 @@ namespace Test { namespace Set {
384384
Weights(const char* t, IntArgs& el, IntArgs& w,
385385
int min = -10000, int max = 10000)
386386
: SetTest(t,1,ds_33,false,1),
387-
elements(el), weights(w), minWeight(min), maxWeight(max) {
388-
disabled = false;
389-
}
387+
elements(el), weights(w), minWeight(min), maxWeight(max) {}
390388
/// %Test whether \a x is solution
391389
virtual bool solution(const SetAssignment& x) const {
392390
CountableSetRanges x0(x.lub, x[0]);

0 commit comments

Comments
 (0)