distinct.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "gecode/set.hh"
00023 #include "gecode/set/distinct.hh"
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 namespace Gecode { namespace Set { namespace Distinct {
00035
00036
00037
00038
00039
00040
00041 static ModEvent
00042 nosubset(Space* home, SetView x, SetView y) {
00043 GlbRanges<SetView> xglb(x);
00044 GlbRanges<SetView> yglb(y);
00045 Iter::Ranges::Diff<GlbRanges<SetView>, GlbRanges<SetView> >
00046 diff(xglb, yglb);
00047 if (!diff())
00048 return ME_SET_FAILED;
00049 if (diff.min() != diff.max())
00050 return ME_SET_NONE;
00051 int a = diff.min();
00052 ++diff;
00053 if (diff())
00054 return ME_SET_NONE;
00055 return y.exclude(home, a);
00056 }
00057
00058 Actor*
00059 Distinct::copy(Space* home, bool share) {
00060 return new (home) Distinct(home,share,*this);
00061 }
00062
00063 ExecStatus
00064 Distinct::propagate(Space* home) {
00065
00066 int curClique = x.size();
00067 int oldCliques = curClique;
00068
00069 while (curClique>1) {
00070
00071 unsigned int li = x[0].glbSize();
00072 curClique--;
00073 SetView tmp = x[curClique];
00074 x[curClique] = x[0];
00075 x[0] = tmp;
00076
00077 GECODE_AUTOARRAY(LubRanges<SetView>, cliqueLubs, oldCliques);
00078 cliqueLubs[0].init(x[curClique]);
00079 unsigned int ki = 1;
00080
00081
00082
00083
00084 for (int j=0; j<curClique; ) {
00085 GlbRanges<SetView> xjglb(x[j]);
00086 GlbRanges<SetView> xiglb(x[curClique]);
00087 if (Iter::Ranges::equal(xiglb, xjglb)) {
00088 curClique--;
00089 SetView tmp2 = x[curClique];
00090 x[curClique] = x[j];
00091 x[j] = tmp2;
00092 cliqueLubs[ki].init(x[curClique]);
00093 ki++;
00094 } else {
00095 j++;
00096 }
00097 }
00098
00099 Iter::Ranges::NaryUnion<LubRanges<SetView> > cliqueLub(cliqueLubs, ki);
00100 unsigned int ui = Iter::Ranges::size(cliqueLub);
00101
00102 unsigned int possible = bin.c(ui-li, c-li);
00103
00104 if (possible < ki)
00105 return ES_FAILED;
00106
00107 if (possible == ki) {
00108 for (int i=curClique; i--; ) {
00109 GECODE_ME_CHECK(nosubset(home, x[curClique], x[i]));
00110 }
00111 for (int i=oldCliques; i<x.size(); i++) {
00112 GECODE_ME_CHECK(nosubset(home, x[curClique], x[i]));
00113 }
00114 }
00115
00116 oldCliques = curClique;
00117 }
00118
00119 return ES_NOFIX;
00120 }
00121
00122 }}}
00123
00124