atmostOne.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
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "gecode/set/distinct.hh"
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 namespace Gecode { namespace Set { namespace Distinct {
00050
00051
00052
00053
00054
00055
00056 Actor*
00057 AtmostOne::copy(Space* home, bool share) {
00058 return new (home) AtmostOne(home,share,*this);
00059 }
00060
00061 Support::Symbol
00062 AtmostOne::ati(void) {
00063 return Support::Symbol("Gecode::Set::Distinct::AtmostOne");
00064 }
00065
00066 Reflection::ActorSpec
00067 AtmostOne::spec(const Space* home, Reflection::VarMap& m) const {
00068 return NaryPropagator<SetView, PC_SET_ANY>::spec(home, m, ati())
00069 << c;
00070 }
00071
00072 ExecStatus
00073 AtmostOne::propagate(Space* home, ModEventDelta) {
00074
00075 GECODE_AUTOARRAY(LubRanges<SetView>, lubs, x.size());
00076 for (int i = x.size(); i--; ) {
00077 lubs[i].init(x[i]);
00078 }
00079 Iter::Ranges::NaryUnion<LubRanges<SetView> > bigT(lubs, x.size());
00080 Iter::Ranges::Cache<Iter::Ranges::NaryUnion<LubRanges<SetView> > >
00081 bigTC(bigT);
00082
00083 Iter::Ranges::ToValues<Iter::Ranges::Cache<Iter::Ranges::NaryUnion<LubRanges<SetView> > > >
00084 as(bigTC);
00085
00086 while (as()) {
00087 int a = as.val(); ++as;
00088
00089
00090 int cardSa = 0;
00091 for (int i=x.size(); i--;)
00092 if (x[i].contains(a))
00093 cardSa++;
00094
00095
00096 GLBndSet bigTa(home);
00097 for (int i=x.size(); i--;) {
00098 if (!x[i].notContains(a)) {
00099 LubRanges<SetView> xilub(x[i]);
00100 bigTa.includeI(home, xilub);
00101 }
00102 }
00103
00104
00105 int maxa = (bigTa.size() - 1) / (c - 1);
00106 bigTa.dispose(home);
00107
00108
00109
00110 if (maxa < cardSa)
00111 return ES_FAILED;
00112
00113 if (maxa == cardSa) {
00114
00115
00116
00117 for (int i=x.size(); i--;) {
00118 if (!x[i].contains(a)) {
00119 GECODE_ME_CHECK(x[i].exclude(home, a));
00120 }
00121 }
00122 } else {
00123 GECODE_AUTOARRAY(LubRanges<SetView>, lubs2, x.size());
00124 for (int i = x.size(); i--; ) {
00125 lubs2[i].init(x[i]);
00126 }
00127 Iter::Ranges::NaryUnion<LubRanges<SetView> > bigT2(lubs2, x.size());
00128
00129 GECODE_AUTOARRAY(GlbRanges<SetView>, glbs, cardSa);
00130 int count = 0;
00131 for (int i=x.size(); i--; ) {
00132 if (x[i].contains(a)) {
00133 glbs[count].init(x[i]);
00134 count++;
00135 }
00136 }
00137 Iter::Ranges::NaryUnion<GlbRanges<SetView> > glbsa(glbs, cardSa);
00138 Iter::Ranges::Diff<Iter::Ranges::NaryUnion<LubRanges<SetView> >,
00139 Iter::Ranges::NaryUnion<GlbRanges<SetView> > > deltaA(bigT2, glbsa);
00140 Iter::Ranges::Cache<
00141 Iter::Ranges::Diff<Iter::Ranges::NaryUnion<LubRanges<SetView> >,
00142 Iter::Ranges::NaryUnion<GlbRanges<SetView> > > > deltaAC(deltaA);
00143
00144
00145
00146
00147
00148 if (Iter::Ranges::size(deltaAC) == c - 1) {
00149
00150
00151
00152
00153
00154
00155
00156
00157 for (int i=x.size(); i--; ) {
00158 if (!x[i].contains(a) && !x[i].notContains(a)) {
00159 deltaAC.reset();
00160 LubRanges<SetView> xilub(x[i]);
00161 if (!Iter::Ranges::subset(deltaAC, xilub)) {
00162 GECODE_ME_CHECK(x[i].exclude(home, a));
00163 }
00164 }
00165 }
00166 }
00167
00168 }
00169
00170 }
00171
00172 return ES_NOFIX;
00173 }
00174
00175 void
00176 AtmostOne::post(Space* home, Reflection::VarMap& vars,
00177 const Reflection::ActorSpec& spec) {
00178 spec.checkArity(2);
00179 ViewArray<SetView> s(home, vars, spec[0]);
00180 int c = spec[1]->toInt();
00181 (void) new (home) AtmostOne(home,s,c);
00182 }
00183
00184 }}
00185
00186 namespace {
00187 GECODE_REGISTER1(Set::Distinct::AtmostOne);
00188 }
00189
00190 }
00191
00192