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
00039
00040 #include <gecode/int/circuit.hh>
00041
00042 namespace Gecode {
00043
00044 void
00045 circuit(Home home, int offset, const IntVarArgs& x, IntConLevel icl) {
00046 Int::Limits::nonnegative(offset,"Int::circuit");
00047 if (x.size() == 0)
00048 throw Int::TooFewArguments("Int::circuit");
00049 if (x.same(home))
00050 throw Int::ArgumentSame("Int::circuit");
00051 if (home.failed()) return;
00052 ViewArray<Int::IntView> xv(home,x);
00053
00054 if (offset == 0) {
00055 typedef Int::NoOffset<Int::IntView> NOV;
00056 NOV no;
00057 if (icl == ICL_DOM) {
00058 GECODE_ES_FAIL((Int::Circuit::Dom<Int::IntView,NOV>
00059 ::post(home,xv,no)));
00060 } else {
00061 GECODE_ES_FAIL((Int::Circuit::Val<Int::IntView,NOV>
00062 ::post(home,xv,no)));
00063 }
00064 } else {
00065 typedef Int::Offset OV;
00066 OV off(-offset);
00067 if (icl == ICL_DOM) {
00068 GECODE_ES_FAIL((Int::Circuit::Dom<Int::IntView,OV>
00069 ::post(home,xv,off)));
00070 } else {
00071 GECODE_ES_FAIL((Int::Circuit::Val<Int::IntView,OV>
00072 ::post(home,xv,off)));
00073 }
00074 }
00075 }
00076 void
00077 circuit(Home home, const IntVarArgs& x, IntConLevel icl) {
00078 circuit(home,0,x,icl);
00079 }
00080
00081 void
00082 circuit(Home home, const IntArgs& c, int offset,
00083 const IntVarArgs& x, const IntVarArgs& y, IntVar z,
00084 IntConLevel icl) {
00085 Int::Limits::nonnegative(offset,"Int::circuit");
00086 int n = x.size();
00087 if (n == 0)
00088 throw Int::TooFewArguments("Int::circuit");
00089 if (x.same(home))
00090 throw Int::ArgumentSame("Int::circuit");
00091 if ((y.size() != n) || (c.size() != n*n))
00092 throw Int::ArgumentSizeMismatch("Int::circuit");
00093 circuit(home, offset, x, icl);
00094 if (home.failed()) return;
00095 IntArgs cx(offset+n);
00096 for (int i=0; i<offset; i++)
00097 cx[i] = 0;
00098 for (int i=n; i--; ) {
00099 for (int j=0; j<n; j++)
00100 cx[offset+j] = c[i*n+j];
00101 element(home, cx, x[i], y[i]);
00102 }
00103 linear(home, y, IRT_EQ, z);
00104 }
00105 void
00106 circuit(Home home, const IntArgs& c,
00107 const IntVarArgs& x, const IntVarArgs& y, IntVar z,
00108 IntConLevel icl) {
00109 circuit(home,c,0,x,y,z,icl);
00110 }
00111 void
00112 circuit(Home home, const IntArgs& c, int offset,
00113 const IntVarArgs& x, IntVar z,
00114 IntConLevel icl) {
00115 Int::Limits::nonnegative(offset,"Int::circuit");
00116 if (home.failed()) return;
00117 IntVarArgs y(home, x.size(), Int::Limits::min, Int::Limits::max);
00118 circuit(home, c, offset, x, y, z, icl);
00119 }
00120 void
00121 circuit(Home home, const IntArgs& c,
00122 const IntVarArgs& x, IntVar z,
00123 IntConLevel icl) {
00124 circuit(home,c,0,x,z,icl);
00125 }
00126
00127 void
00128 path(Home home, int offset, const IntVarArgs& x, IntVar s, IntVar e,
00129 IntConLevel icl) {
00130 Int::Limits::nonnegative(offset,"Int::path");
00131 int n=x.size();
00132 if (n == 0)
00133 throw Int::TooFewArguments("Int::path");
00134 if (x.same(home))
00135 throw Int::ArgumentSame("Int::path");
00136 if (home.failed()) return;
00137 ViewArray<Int::IntView> xv(home,n+1);
00138 for (int i=n; i--; )
00139 xv[i] = Int::IntView(x[i]);
00140 xv[n] = s;
00141
00142 if (offset == 0) {
00143 element(home, x, e, n);
00144 typedef Int::NoOffset<Int::IntView> NOV;
00145 NOV no;
00146 if (icl == ICL_DOM) {
00147 GECODE_ES_FAIL((Int::Circuit::Dom<Int::IntView,NOV>
00148 ::post(home,xv,no)));
00149 } else {
00150 GECODE_ES_FAIL((Int::Circuit::Val<Int::IntView,NOV>
00151 ::post(home,xv,no)));
00152 }
00153 } else {
00154 IntVarArgs ox(n+offset);
00155 IntVar y(home, -1,-1);
00156 for (int i=offset; i--; )
00157 ox[i] = y;
00158 for (int i=n; i--; )
00159 ox[offset + i] = x[i];
00160 element(home, ox, e, offset+n);
00161 typedef Int::Offset OV;
00162 OV off(-offset);
00163 if (icl == ICL_DOM) {
00164 GECODE_ES_FAIL((Int::Circuit::Dom<Int::IntView,OV>
00165 ::post(home,xv,off)));
00166 } else {
00167 GECODE_ES_FAIL((Int::Circuit::Val<Int::IntView,OV>
00168 ::post(home,xv,off)));
00169 }
00170 }
00171 }
00172 void
00173 path(Home home, const IntVarArgs& x, IntVar s, IntVar e,
00174 IntConLevel icl) {
00175 path(home,0,x,s,e,icl);
00176 }
00177
00178 void
00179 path(Home home, const IntArgs& c, int offset,
00180 const IntVarArgs& x, IntVar s, IntVar e,
00181 const IntVarArgs& y, IntVar z,
00182 IntConLevel icl) {
00183 Int::Limits::nonnegative(offset,"Int::path");
00184 int n = x.size();
00185 if (n == 0)
00186 throw Int::TooFewArguments("Int::path");
00187 if (x.same(home))
00188 throw Int::ArgumentSame("Int::path");
00189 if ((y.size() != n) || (c.size() != n*n))
00190 throw Int::ArgumentSizeMismatch("Int::path");
00191 if (home.failed()) return;
00192 path(home, offset, x, s, e, icl);
00193 IntArgs cx(offset+n+1);
00194 for (int i=0; i<offset; i++)
00195 cx[i] = 0;
00196 cx[offset+n] = 0;
00197 for (int i=n; i--; ) {
00198 for (int j=0; j<n; j++)
00199 cx[offset+j] = c[i*n+j];
00200 element(home, cx, x[i], y[i]);
00201 }
00202 linear(home, y, IRT_EQ, z);
00203 }
00204 void
00205 path(Home home, const IntArgs& c,
00206 const IntVarArgs& x, IntVar s, IntVar e,
00207 const IntVarArgs& y, IntVar z,
00208 IntConLevel icl) {
00209 path(home,c,0,x,s,e,y,z,icl);
00210 }
00211 void
00212 path(Home home, const IntArgs& c, int offset,
00213 const IntVarArgs& x, IntVar s, IntVar e, IntVar z,
00214 IntConLevel icl) {
00215 Int::Limits::nonnegative(offset,"Int::path");
00216 if (home.failed()) return;
00217 IntVarArgs y(home, x.size(), Int::Limits::min, Int::Limits::max);
00218 path(home, c, offset, x, s, e, y, z, icl);
00219 }
00220 void
00221 path(Home home, const IntArgs& c,
00222 const IntVarArgs& x, IntVar s, IntVar e, IntVar z,
00223 IntConLevel icl) {
00224 path(home,c,0,x,s,e,z,icl);
00225 }
00226
00227 }
00228
00229