00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef _CSP_EXAMPLES_Random_H
00025 #define _CSP_EXAMPLES_Random_H
00026
00027
00028 #ifndef __cplusplus
00029 #error Must use C++ for the type Random.
00030 #endif
00031
00032
00033 #include <string>
00034 #include <stdexcept>
00035
00036
00037 #include "values/Int.h"
00038 #include "variables/Int.h"
00039
00040
00041 CSP_NAMESPACE_BEGIN(Random)
00042
00043
00044 using namespace std;
00045
00046 #ifdef __GNUG__
00047 using namespace __gnu_cxx;
00048 #endif
00049
00050 #if defined(_MSC_VER) && (_MSC_VER == 1310)
00051 using namespace stdext;
00052 #endif
00053
00054
00055 class Variable;
00056 class Value;
00057
00058
00059 class Problem :
00060 public csp::Problem
00061 {
00062 public:
00063 Problem(
00064 csp::RandomSequence& randomSequence,
00065 const wstring& model,
00066 bool flawed,
00067 bool weightSearch,
00068 size_t nVariables,
00069 size_t domainSize,
00070 double density,
00071 double tightness,
00072 bool nonStandardDensity = true,
00073 size_t weakSpots = 0,
00074 size_t weakSpotConstraints = 5);
00075
00076 Problem(const Problem& problem);
00077 Problem(csp::RandomSequence& randomSequence, wifstream& wifs);
00078
00079 virtual wstring name() const { return L"Random"; }
00080
00081 bool weightSearch() const { return m_weightSearch; }
00082
00083 double weight() const;
00084 double minWeight() const;
00085 double maxWeight() const;
00086
00087 double currentWeight() const;
00088
00089 double minAcceptableWeight() const { return m_minAcceptableWeight; }
00090 double maxAcceptableWeight() const { return m_maxAcceptableWeight; }
00091
00092 void setMinAcceptableWeight(double minAcceptableWeight)
00093 {
00094 assert(minWeight() <= minAcceptableWeight);
00095 assert(minAcceptableWeight <= maxWeight());
00096 m_minAcceptableWeight = minAcceptableWeight;
00097 }
00098
00099 void setMaxAcceptableWeight(double maxAcceptableWeight)
00100 {
00101 assert(minWeight() <= maxAcceptableWeight);
00102 assert(maxAcceptableWeight <= maxWeight());
00103 m_maxAcceptableWeight = maxAcceptableWeight;
00104 }
00105
00108 double minFutureWeight() const;
00109
00112 double maxFutureWeight() const;
00113
00114 double idealWeight() const { return m_idealWeight; }
00115
00116 void computeConstraintAcceptableWeightRange();
00117
00123 virtual void save(wofstream& wofs) const;
00124
00126 void loadSolutions(wifstream& wifs);
00127
00129 void saveSolution(wofstream& wofs) const;
00130
00131 virtual wostream& printSolution(wostream& wos) const;
00132 virtual wostream& print(wostream& wos) const;
00133
00134 private:
00135 class Pair
00136 {
00137 public:
00138 Variable* variable0;
00139 Variable* variable1;
00140 };
00141
00142 void constructor(
00143 const wstring& model,
00144 bool flawed,
00145 bool weightSearch,
00146 size_t nVariables,
00147 size_t domainSize,
00148 double density,
00149 double tightness,
00150 bool nonStandardDensity,
00151 size_t weakSpots,
00152 size_t weakSpotConstraints);
00153
00159 void createConnectingConstraints(size_t nPairs);
00160
00164 void createCompleteConstraintSet(vector<Pair>& all);
00165
00170 void createConstraints(size_t nConstraints, size_t nPairs);
00171
00176 void createConstraints(double probability, size_t nPairs);
00177
00210 wstring m_model;
00211
00221 bool m_flawed;
00222
00223 bool m_weightSearch;
00224 double m_idealWeight;
00225 double m_minAcceptableWeight;
00226 double m_maxAcceptableWeight;
00227
00228
00229
00230 size_t m_nVariables;
00231 size_t m_domainSize;
00232 double m_density;
00233 double m_tightness;
00234
00239 double m_densityGranularity;
00240
00245 double m_tightnessGranularity;
00246
00247 bool m_nonStandardDensity;
00248
00249 size_t m_weakSpots;
00250 size_t m_weakSpotConstraints;
00251
00252 wstring m_checksum;
00253 };
00254
00255
00256 class Value :
00257 public csp::values::Int
00258 {
00259 public:
00260 Value(const int v, const double weight) :
00261 csp::values::Int(v), m_weight(weight) {}
00262 Value(const Value& v) :
00263 csp::values::Int(v) { m_weight = v.m_weight; }
00264
00265 double weight() const { return m_weight; }
00266
00267
00268 Value& operator=(const Value& v)
00269 {
00270 Int::operator=(v);
00271 m_weight = v.m_weight;
00272 return *this;
00273 }
00274
00275 private:
00276 double m_weight;
00277 };
00278
00279
00280 typedef csp::Domain Domain;
00281
00282
00283 class Variable :
00284 public csp::variables::Int
00285 {
00286 public:
00287 Variable(
00288 const Problem& problem,
00289 const int min,
00290 const int max);
00291
00292 double weight() const { return value().weight(); }
00293
00294 double minWeight() const { return m_minWeight; }
00295 double maxWeight() const { return m_maxWeight; }
00296
00297 Value& value() const { return static_cast<Value&>(Int::value()); }
00298
00299 virtual wostream& print(wostream& wos) const
00300 {
00301 csp::variables::Int::print(wos);
00302
00303 return wos;
00304 }
00305
00306 virtual wstring color() const
00307 {
00308
00309
00310
00311 if (m_isBranching)
00312 return L"pink";
00313 if (m_isBackdoorKey)
00314 return L"orange";
00315 if (m_isBackdoor)
00316 return L"red";
00317 return csp::Variable::color();
00318 }
00319
00320 virtual wstring textColor() const { return csp::Variable::textColor(); }
00321
00322 virtual wstring shape() const
00323 {
00324 if (m_isBackdoor || m_isBackdoorKey || m_isBranching)
00325 return L"rectangle";
00326 return csp::Variable::shape();
00327 }
00328
00329 virtual void setBackdoorStatus(bool status) { m_isBackdoor = status; }
00330 virtual void setBackdoorKeyStatus(bool status) { m_isBackdoorKey = status; }
00331 virtual void setBranchingStatus(bool status) { m_isBranching = status; }
00332
00333 private:
00335 Variable(const Variable&);
00336
00338 Variable& operator=(const Variable&);
00339
00340 double m_minWeight;
00341 double m_maxWeight;
00342
00343 bool m_isBackdoor;
00344 bool m_isBackdoorKey;
00345 bool m_isBranching;
00346 };
00347
00348
00349 class Constraint :
00350 public csp::Constraint
00351 {
00352 public:
00353 Constraint(Problem& problem);
00354 Constraint(Problem& problem, const Constraint& constraint);
00355 virtual ~Constraint() { delete m_weights; }
00356
00357 double weight() const;
00358 double weight(const Variable& variable, const Value& value) const;
00359
00360 double minWeight() const { return m_minWeight; }
00361 double maxWeight() const { return m_maxWeight; }
00362
00363 void buildWrapper(
00364 const wstring& model,
00365 size_t nPairs,
00366 double probability,
00367 bool flawed);
00368
00370 void buildEmpty();
00371
00373 void addPair(int value0, int value1);
00374
00379 virtual bool check() const;
00380
00385 bool isFlawless() const;
00386
00388 ulonglong allowedTuples() const;
00389
00390 virtual wostream& print(wostream& wos) const
00391 {
00392 csp::Constraint::print(wos);
00393
00394 return wos;
00395 }
00396
00397 private:
00398 class Pair
00399 {
00400 public:
00401 Value* value0;
00402 Value* value1;
00403 };
00404
00405 void buildWeights(int value0, int value1, size_t domainSize);
00406
00407 size_t buildPairsUnconditionally(
00408 vector<Pair>& source, size_t n, size_t domainSize);
00409
00410 size_t buildFixedNumberOfPairs(
00411 vector<Pair>& source, size_t n, size_t domainSize);
00412
00414 void buildAllPairs(vector<Pair>& all);
00415
00421 void buildAllPairs(vector<Pair>& goods, vector<Pair>& rest);
00422
00427 void build(double probability, size_t nPairs, bool flawed);
00428
00433 void build(size_t nPairs, bool flawed);
00434
00435 Problem& m_problem;
00436
00437 double m_minWeight;
00438 double m_maxWeight;
00439
00440 csp::BitArray m_pairs;
00441 hash_map<int, double>* m_weights;
00442 };
00443
00444
00445 class AcceptableWeight :
00446 public csp::ValueOH
00447 {
00448 public:
00449 AcceptableWeight(
00450 csp::Decomposition& decomposition,
00451 const vector<pair<double, double> >& intervals,
00452 double quality = 1) :
00453 csp::ValueOH(L"Acceptable Weight", decomposition, intervals, quality),
00454 m_ignored(false)
00455 {
00456 if (m_quality < 1)
00457 LOG(L"Random::AcceptableWeight", Warning,
00458 L"Quality setting ignored");
00459 }
00460
00461 void setIgnoredFlag(bool ignored) { m_ignored = ignored; }
00462
00463 void select(
00464 csp::Domain& domain,
00465 csp::Domain& selected,
00466 csp::Variable& variable);
00467
00468 virtual long double score(
00469 csp::Variable& ,
00470 const csp::Value& )
00471 {
00472 LOG(L"Random::AcceptableWeight", Debug, L"Not implemented!");
00473 assert(0);
00474 abort();
00475 return -1;
00476 }
00477
00478 private:
00479
00480 bool m_ignored;
00481
00482 typedef struct
00483 {
00484 csp::Value* m_value;
00485 double m_proximity;
00486 } proximity_type;
00487
00488 template<class T>
00489 struct proximity_less :
00490 public binary_function<T, T, bool>
00491 {
00492 public:
00493 bool operator()(const T& x, const T& y) const
00494 {
00495 return fabs(x.m_proximity) < fabs(y.m_proximity);
00496 }
00497 };
00498 };
00499
00500
00501 CSP_NAMESPACE_END(Random)
00502
00503
00504 #endif
00505
00506
00507
00508