void RefRemoveOp::apply(shared_ptr<OsmMap>& map) { // get all the REF1 IDs that will be removed GetRefVisitor grv(_criterion); map->visitRo(grv); // remove all the elements that meet the criteria RefRemoveVisitor rrv(_criterion); map->visitRw(rrv); // remove all the REF1 references that were removed from REF2 entries. This might happen if // you remove all buildings, but there are some POIs remaining that were matched to the buildings. UpdateRefVisitor urv(grv.getRefs()); map->visitRw(urv); }
ExecStatus Weights<View>::propagate(Space& home, const ModEventDelta&) { ModEvent me = ME_SET_NONE; if (!x.assigned()) { // Collect the weights of the elements in the unknown set in an array int size = elements.size(); Region r(home); int* currentWeights = r.alloc<int>(size); UnknownRanges<View> ur(x); Iter::Ranges::ToValues<UnknownRanges<View> > urv(ur); for (int i=0; i<size; i++) { if (!urv() || elements[i]<urv.val()) { currentWeights[i] = 0; } else { assert(elements[i] == urv.val()); currentWeights[i] = weights[i]; ++urv; } } // Sort the weights of the unknown elements IntLess il; Support::quicksort<int>(currentWeights, size, il); // The maximum number of elements that can still be added to x int delta = static_cast<int>(std::min(x.unknownSize(), x.cardMax() - x.glbSize())); // The weight of the elements already in x GlbRanges<View> glb(x); int glbWeight = weightI<GlbRanges<View> >(elements, weights, glb); // Compute the weight of the current lower bound of x, plus at most // delta-1 further elements with smallest negative weights. This weight // determines which elements in the upper bound cannot possibly be // added to x (those whose weight would exceed the capacity even if // all other elements are minimal) int lowWeight = glbWeight; for (int i=0; i<delta-1; i++) { if (currentWeights[i] >= 0) break; lowWeight+=currentWeights[i]; } // Compute the lowest possible weight of x. If there is another element // with negative weight left, then add its weight to lowWeight. // Otherwise lowWeight is already the lowest possible weight. int lowestWeight = lowWeight; if (delta>0 && currentWeights[delta-1]<0) lowestWeight+=currentWeights[delta-1]; // If after including the minimal number of required elements, // no more element with negative weight is available, then // a tighter lower bound can be computed. if ( (x.cardMin() - x.glbSize() > 0 && currentWeights[x.cardMin() - x.glbSize() - 1] >= 0) || currentWeights[0] >= 0 ) { int lowestPosWeight = glbWeight; for (unsigned int i=0; i<x.cardMin() - x.glbSize(); i++) { lowestPosWeight += currentWeights[i]; } lowestWeight = std::max(lowestWeight, lowestPosWeight); } // Compute the highest possible weight of x as the weight of the lower // bound plus the weight of the delta heaviest elements still in the // upper bound. int highestWeight = glbWeight; for (int i=0; i<delta; i++) { if (currentWeights[size-i-1]<=0) break; highestWeight += currentWeights[size-i-1]; } // Prune the weight using the computed bounds GECODE_ME_CHECK(y.gq(home, lowestWeight)); GECODE_ME_CHECK(y.lq(home, highestWeight)); // Exclude all elements that are too heavy from the set x. // Elements are too heavy if their weight alone already // exceeds the remaining capacity int remainingCapacity = y.max()-lowWeight; UnknownRanges<View> ur2(x); Iter::Ranges::ToValues<UnknownRanges<View> > urv2(ur2); OverweightValues<Iter::Ranges::ToValues<UnknownRanges<View> > > ov(remainingCapacity, elements, weights, urv2); Iter::Values::ToRanges<OverweightValues< Iter::Ranges::ToValues<UnknownRanges<View> > > > ovr(ov); me = x.excludeI(home, ovr); GECODE_ME_CHECK(me); } if (x.assigned()) { // If x is assigned, just compute its weight and assign y. GlbRanges<View> glb(x); int w = weightI<GlbRanges<View> >(elements, weights, glb); GECODE_ME_CHECK(y.eq(home, w)); return home.ES_SUBSUMED(*this); } return me_modified(me) ? ES_NOFIX : ES_FIX; }