this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Christian Schulte <schulte@gecode.org> 5 * Vincent Barichard <Vincent.Barichard@univ-angers.fr> 6 * 7 * Copyright: 8 * Christian Schulte, 2005 9 * Vincent Barichard, 2012 10 * 11 * This file is part of Gecode, the generic constraint 12 * development environment: 13 * http://www.gecode.org 14 * 15 * Permission is hereby granted, free of charge, to any person obtaining 16 * a copy of this software and associated documentation files (the 17 * "Software"), to deal in the Software without restriction, including 18 * without limitation the rights to use, copy, modify, merge, publish, 19 * distribute, sublicense, and/or sell copies of the Software, and to 20 * permit persons to whom the Software is furnished to do so, subject to 21 * the following conditions: 22 * 23 * The above copyright notice and this permission notice shall be 24 * included in all copies or substantial portions of the Software. 25 * 26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 30 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 31 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 32 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 33 * 34 */ 35 36#include "test/float.hh" 37 38#include <gecode/minimodel.hh> 39 40namespace Test { namespace Float { 41 42 /// %Tests for linear constraints 43 namespace Linear { 44 45 /// Check whether \a has only one coefficients 46 bool one(const Gecode::FloatValArgs& a) { 47 for (int i=a.size(); i--; ) 48 if (a[i] != 1) 49 return false; 50 return true; 51 } 52 53 /** 54 * \defgroup TaskTestFloatLinear Linear constraints 55 * \ingroup TaskTestFloat 56 */ 57 //@{ 58 /// %Test linear relation over float variables 59 class FloatFloat : public Test { 60 protected: 61 /// Coefficients 62 Gecode::FloatValArgs a; 63 /// Float relation type to propagate 64 Gecode::FloatRelType frt; 65 /// Result 66 Gecode::FloatNum c; 67 public: 68 /// Create and register test 69 FloatFloat(const std::string& s, const Gecode::FloatVal& d, 70 const Gecode::FloatValArgs& a0, Gecode::FloatRelType frt0, 71 Gecode::FloatNum c0, Gecode::FloatNum st) 72 : Test("Linear::Float::"+ 73 str(frt0)+"::"+s+"::"+str(c0)+"::" 74 +str(a0.size()), 75 a0.size(),d,st,CPLT_ASSIGNMENT,true), 76 a(a0), frt(frt0), c(c0) { 77 using namespace Gecode; 78 testfix = false; 79 if ((frt == FRT_NQ) || (frt == FRT_LE) || (frt == FRT_GR) || reified) 80 testsubsumed = false; 81 } 82 /// %Test whether \a x is solution 83 virtual MaybeType solution(const Assignment& x) const { 84 Gecode::FloatVal e = 0.0; 85 for (int i=x.size(); i--; ) 86 e += a[i]*x[i]; 87 switch (cmp(e, frt, Gecode::FloatVal(c))) { 88 case MT_FALSE: { 89 Gecode::FloatVal eError = e; 90 for (int i=x.size(); i--; ) 91 eError -= a[i]*x[i]; 92 if (cmp(e+eError, frt, Gecode::FloatVal(c)) == MT_FALSE) 93 return MT_FALSE; 94 else 95 return MT_MAYBE; 96 } 97 case MT_TRUE: 98 return MT_TRUE; 99 case MT_MAYBE: 100 return MT_MAYBE; 101 } 102 GECODE_NEVER; 103 return MT_FALSE; 104 } 105 /// Post constraint on \a x 106 virtual void post(Gecode::Space& home, Gecode::FloatVarArray& x) { 107 if (one(a)) 108 Gecode::linear(home, x, frt, c); 109 else 110 Gecode::linear(home, a, x, frt, c); 111 } 112 /// Post reified constraint on \a x for \a r 113 virtual void post(Gecode::Space& home, Gecode::FloatVarArray& x, 114 Gecode::Reify r) { 115 if (one(a)) 116 Gecode::linear(home, x, frt, c, r); 117 else 118 Gecode::linear(home, a, x, frt, c, r); 119 } 120 }; 121 122 /// %Test linear relation over float variables 123 class FloatVar : public Test { 124 protected: 125 /// Coefficients 126 Gecode::FloatValArgs a; 127 /// Float relation type to propagate 128 Gecode::FloatRelType frt; 129 public: 130 /// Create and register test 131 FloatVar(const std::string& s, const Gecode::FloatVal& d, 132 const Gecode::FloatValArgs& a0, Gecode::FloatRelType frt0, Gecode::FloatNum st) 133 : Test("Linear::Var::"+ 134 str(frt0)+"::"+s+"::"+str(a0.size()), 135 a0.size()+1,d,st,CPLT_ASSIGNMENT,true), 136 a(a0), frt(frt0) { 137 using namespace Gecode; 138 testfix = false; 139 if ((frt == FRT_NQ) || (frt == FRT_LE) || (frt == FRT_GR) || reified) 140 testsubsumed = false; 141 } 142 /// %Test whether \a x is solution 143 virtual MaybeType solution(const Assignment& x) const { 144 Gecode::FloatVal e = 0.0; 145 for (int i=a.size(); i--; ) 146 e += a[i]*x[i]; 147 switch (cmp(e, frt, x[a.size()])) { 148 case MT_FALSE: { 149 Gecode::FloatVal eError = e; 150 for (int i=a.size(); i--; ) 151 eError -= a[i]*x[i]; 152 if (cmp(e+eError, frt, x[a.size()]) == MT_FALSE) 153 return MT_FALSE; 154 else 155 return MT_MAYBE; 156 } 157 case MT_TRUE: 158 return MT_TRUE; 159 case MT_MAYBE: 160 return MT_MAYBE; 161 } 162 GECODE_NEVER; 163 return MT_FALSE; 164 } 165 /// Post constraint on \a x 166 virtual void post(Gecode::Space& home, Gecode::FloatVarArray& x) { 167 int n = a.size(); 168 Gecode::FloatVarArgs y(n); 169 for (int i=n; i--; ) 170 y[i] = x[i]; 171 if (one(a)) 172 Gecode::linear(home, y, frt, x[n]); 173 else 174 Gecode::linear(home, a, y, frt, x[n]); 175 } 176 /// Post reified constraint on \a x for \a r 177 virtual void post(Gecode::Space& home, Gecode::FloatVarArray& x, 178 Gecode::Reify r) { 179 int n = a.size(); 180 Gecode::FloatVarArgs y(n); 181 for (int i=n; i--; ) 182 y[i] = x[i]; 183 if (one(a)) 184 Gecode::linear(home, y, frt, x[n], r); 185 else 186 Gecode::linear(home, a, y, frt, x[n], r); 187 } 188 }; 189 190 /// Help class to create and register tests 191 class Create { 192 public: 193 /// Perform creation and registration 194 Create(void) { 195 using namespace Gecode; 196 { 197 FloatNum step = 0.7; 198 FloatVal f1(-2,2); 199 FloatVal f2(-3,-1); 200 FloatVal f3(3,8); 201 202 FloatValArgs a1(1); 203 a1[0] = 0.0; 204 205 for (FloatRelTypes frts; frts(); ++frts) { 206 (void) new FloatFloat("11",f1,a1,frts.frt(),0.0,step); 207 (void) new FloatVar("11",f1,a1,frts.frt(),step); 208 (void) new FloatFloat("21",f2,a1,frts.frt(),0.0,step); 209 (void) new FloatVar("21",f2,a1,frts.frt(),step); 210 (void) new FloatFloat("31",f3,a1,frts.frt(),1.0,step); 211 } 212 213 const FloatVal av2[4] = {1.0,1.0,1.0,1.0}; 214 const FloatVal av3[4] = {1.0,-1.0,-1.0,1.0}; 215 const FloatVal av4[4] = {2.0,3.0,5.0,7.0}; 216 const FloatVal av5[4] = {-2.0,3.0,-5.0,7.0}; 217 218 for (int i=1; i<=4; i++) { 219 FloatValArgs a2(i, av2); 220 FloatValArgs a3(i, av3); 221 FloatValArgs a4(i, av4); 222 FloatValArgs a5(i, av5); 223 for (FloatRelTypes frts; frts(); ++frts) { 224 (void) new FloatFloat("12",f1,a2,frts.frt(),0.0,step); 225 (void) new FloatFloat("13",f1,a3,frts.frt(),0.0,step); 226 (void) new FloatFloat("14",f1,a4,frts.frt(),0.0,step); 227 (void) new FloatFloat("15",f1,a5,frts.frt(),0.0,step); 228 (void) new FloatFloat("22",f2,a2,frts.frt(),0.0,step); 229 (void) new FloatFloat("23",f2,a3,frts.frt(),0.0,step); 230 (void) new FloatFloat("24",f2,a4,frts.frt(),0.0,step); 231 (void) new FloatFloat("25",f2,a5,frts.frt(),0.0,step); 232 (void) new FloatFloat("32",f3,a2,frts.frt(),1.0,step); 233 if (i < 4) { 234 (void) new FloatVar("12",f1,a2,frts.frt(),step); 235 (void) new FloatVar("13",f1,a3,frts.frt(),step); 236 (void) new FloatVar("14",f1,a4,frts.frt(),step); 237 (void) new FloatVar("15",f1,a5,frts.frt(),step); 238 (void) new FloatVar("22",f2,a2,frts.frt(),step); 239 (void) new FloatVar("23",f2,a3,frts.frt(),step); 240 (void) new FloatVar("24",f2,a4,frts.frt(),step); 241 (void) new FloatVar("25",f2,a5,frts.frt(),step); 242 } 243 } 244 } 245 } 246 } 247 }; 248 249 Create c; 250 //@} 251 252 } 253}} 254 255// STATISTICS: test-float