1
0
This repository has been archived on 2025-03-06. You can view files and clone it, but cannot push or open issues or pull requests.
Jip J. Dekker 981be2067e Squashed 'software/gecode_on_replay/' content from commit 8051d92b9
git-subtree-dir: software/gecode_on_replay
git-subtree-split: 8051d92b9c89e49cccfbd1c201371580d7703ab4
2021-06-16 14:04:29 +10:00

210 lines
6.4 KiB
C++

/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Patrick Pekczynski <pekczynski@ps.uni-sb.de>
*
* Copyright:
* Patrick Pekczynski, 2004
*
* This file is part of Gecode, the generic constraint
* development environment:
* http://www.gecode.org
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
namespace Gecode { namespace Int { namespace Sorted {
/**
* \brief Build \f$\sigma\f$
*
* Creates a sorting permutation \f$\sigma\f$ by sorting the
* views in \a x according to their lower bounds
*/
template<class View, bool Perm>
inline void
sort_sigma(ViewArray<View>& x, ViewArray<View>& z) {
if (Perm) {
Region r;
ViewPair<View>* xz = r.alloc<ViewPair<View> >(x.size());
for (int i=x.size(); i--; ) {
xz[i].x=x[i]; xz[i].z=z[i];
}
TupleMinIncExt<View> min_inc;
Support::quicksort<ViewPair<View>,TupleMinIncExt<View> >
(&xz[0], x.size(), min_inc);
for (int i=x.size(); i--; ) {
x[i]=xz[i].x; z[i]=xz[i].z;
}
} else {
TupleMinInc<View> min_inc;
Support::quicksort<View,TupleMinInc<View> >(&x[0], x.size(), min_inc);
}
}
/**
* \brief Build \f$\tau\f$
*
* Creates a sorting permutation \f$\tau\f$ by sorting
* a given array of indices in \a tau according to the upper bounds
* of the views in \a x
*/
template<class View, bool Perm>
inline void
sort_tau(ViewArray<View>& x, ViewArray<View>& z, int tau[]) {
if (Perm) {
TupleMaxIncExt<View> ltmax(x,z);
Support::quicksort(&(*tau), x.size(), ltmax);
} else {
TupleMaxInc<View> ltmax(x);
Support::quicksort(&(*tau), x.size(), ltmax);
}
}
/**
* \brief Performing normalization on the views in \a y
*
* The views in \a y are called normalized if
* \f$\forall i\in\{0,\dots, n-1\}: min(y_0) \leq \dots \leq min(y_{n-1}) \wedge
* max(y_0) \leq \dots \leq max(y_{n-1})\f$ holds.
*/
template<class View>
inline bool
normalize(Space& home,
ViewArray<View>& y,
ViewArray<View>& x,
bool& nofix) {
int ys = y.size();
for (int i = 1; i < ys; i++) {
ModEvent me_lb = y[i].gq(home, y[i - 1].min());
if (me_failed(me_lb))
return false;
nofix |= (me_modified(me_lb) && y[i - 1].min() != y[i].min());
}
for (int i = ys - 1; i--; ) {
ModEvent me_ub = y[i].lq(home, y[i + 1].max());
if (me_failed(me_ub))
return false;
nofix |= (me_modified(me_ub) && y[i + 1].max() != y[i].max());
}
int xs = x.size();
for (int i = xs; i--; ) {
ModEvent me = x[i].gq(home, y[0].min());
if (me_failed(me))
return false;
nofix |= (me_modified(me) && x[i].min() != y[0].min());
me = x[i].lq(home, y[xs - 1].max());
if (me_failed(me))
return false;
nofix |= (me_modified(me) && x[i].max() != y[xs - 1].max());
}
return true;
}
/**
* \brief Bounds consistency on the permutation views
*
* Check, whether the permutation view are bounds consistent.
* This function tests, whether there are "crossing edges", i.e.
* whether the current domains permit matchings between unsorted views
* \a x and the sorted variables \a y violating the property
* that \a y is sorted.
*/
template<class View>
inline bool
perm_bc(Space& home, int tau[],
SccComponent sinfo[],
int scclist[],
ViewArray<View>& x,
ViewArray<View>& z,
bool& crossingedge,
bool& nofix) {
int ps = x.size();
for (int i = 1; i < ps; i++) {
// if there are "crossed edges"
if (x[i - 1].min() < x[i].min()) {
if (z[i - 1].min() > z[i].min()) {
if (z[i].min() != sinfo[scclist[i]].leftmost) {
// edge does not take part in solution
if (z[i].assigned()) { // vital edge do not remove it
if (x[i - 1].max() < x[i].min()) {
// invalid permutation
// the upper bound sorting cannot fix this
return false;
}
} else {
crossingedge = true;
// and the permutation can still be changed
// fix the permutation, i.e. modify z
ModEvent me_z = z[i].gq(home, z[i - 1].min());
if (me_failed(me_z)) {
return false;
}
nofix |= ( me_modified(me_z) &&
z[i - 1].min() != z[i].min());
}
}
}
}
}
// the same check as above for the upper bounds
for (int i = ps - 1; i--; ) {
if (x[tau[i]].max() < x[tau[i + 1]].max()) {
if (z[tau[i]].max() > z[tau[i + 1]].max()) {
if (z[tau[i]].max() != sinfo[scclist[tau[i]]].rightmost) {
// edge does not take part in solution
if (z[tau[i]].assigned()) {
if (x[tau[i + 1]].min() > x[tau[i]].max()) {
// invalid permutation
return false;
}
} else {
crossingedge = true;
ModEvent me_z = z[tau[i]].lq(home, z[tau[i + 1]].max());
if (me_failed(me_z)) {
return false;
}
nofix |= (me_modified(me_z) &&
z[tau[i + 1]].max() != z[tau[i]].max());
}
}
}
}
}
return true;
}
}}}
// STATISTICS: int-prop