00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <string.h>
00015 #include <string>
00016 #include <vector>
00017
00018 #include "base/integral_types.h"
00019 #include "base/logging.h"
00020 #include "base/scoped_ptr.h"
00021 #include "base/stringprintf.h"
00022 #include "constraint_solver/constraint_solver.h"
00023 #include "util/string_array.h"
00024
00025 namespace operations_research {
00026
00027
00028
00029
00030
00031 namespace {
00032 class ScheduleOrPostpone : public Decision {
00033 public:
00034 ScheduleOrPostpone(IntervalVar* const var, int64 est, int64* const marker)
00035 : var_(var), est_(est), marker_(marker) {}
00036 virtual ~ScheduleOrPostpone() {}
00037
00038 virtual void Apply(Solver* const s) {
00039 var_->SetPerformed(true);
00040 var_->SetStartRange(est_, est_);
00041 }
00042
00043 virtual void Refute(Solver* const s) {
00044 s->SaveAndSetValue(marker_, est_ + 1);
00045 }
00046
00047 virtual void Accept(DecisionVisitor* const visitor) const {
00048 CHECK_NOTNULL(visitor);
00049 visitor->VisitScheduleOrPostpone(var_, est_);
00050 }
00051
00052 virtual string DebugString() const {
00053 return StringPrintf("ScheduleOrPostpone(%s at %" GG_LL_FORMAT "d)",
00054 var_->DebugString().c_str(), est_);
00055 }
00056
00057 private:
00058 IntervalVar* const var_;
00059 const int64 est_;
00060 int64* const marker_;
00061 };
00062
00063 class SetTimesForward : public DecisionBuilder {
00064 public:
00065 SetTimesForward(const IntervalVar* const * vars, int size)
00066 : vars_(new IntervalVar*[size]),
00067 size_(size),
00068 markers_(new int64[size]) {
00069 memcpy(vars_.get(), vars, sizeof(*vars) * size);
00070 for (int i = 0; i < size_; ++i) {
00071 markers_[i] = kint64min;
00072 }
00073 }
00074
00075 virtual ~SetTimesForward() {}
00076
00077 virtual Decision* Next(Solver* const s) {
00078 int64 best_est = kint64max;
00079 int64 best_lct = kint64max;
00080 int support = -1;
00081 int refuted = 0;
00082 for (int i = 0; i < size_; ++i) {
00083 IntervalVar* const v = vars_[i];
00084 if (v->MayBePerformed() && v->StartMax() > v->StartMin()) {
00085 if (v->StartMin() >= markers_[i] &&
00086 (v->StartMin() < best_est ||
00087 (v->StartMin() == best_est && v->EndMax() < best_lct))) {
00088 best_est = v->StartMin();
00089 best_lct = v->EndMax();
00090 support = i;
00091 } else {
00092 refuted++;
00093 }
00094 }
00095 }
00096
00097
00098 if (support == -1) {
00099 if (refuted == 0) {
00100 return NULL;
00101 } else {
00102 s->Fail();
00103 }
00104 }
00105 return s->RevAlloc(new ScheduleOrPostpone(vars_[support],
00106 vars_[support]->StartMin(),
00107 &markers_[support]));
00108 }
00109
00110 virtual string DebugString() const {
00111 return "SetTimesForward()";
00112 }
00113
00114 virtual void Accept(ModelVisitor* const visitor) const {
00115 visitor->BeginVisitExtension(ModelVisitor::kVariableGroupExtension);
00116 visitor->VisitIntervalArrayArgument(ModelVisitor::kIntervalsArgument,
00117 vars_.get(),
00118 size_);
00119 visitor->EndVisitExtension(ModelVisitor::kVariableGroupExtension);
00120 }
00121
00122 private:
00123 scoped_array<IntervalVar*> vars_;
00124 const int size_;
00125 scoped_array<int64> markers_;
00126 };
00127
00128
00129
00130 class RankFirst : public Decision {
00131 public:
00132 RankFirst(SequenceVar* const seq, int index)
00133 : sequence_(seq), index_(index) {}
00134 virtual ~RankFirst() {}
00135
00136 virtual void Apply(Solver* const s) {
00137 sequence_->RankFirst(index_);
00138 }
00139
00140 virtual void Refute(Solver* const s) {
00141 sequence_->RankNotFirst(index_);
00142 }
00143
00144 void Accept(DecisionVisitor* const visitor) const {
00145 CHECK_NOTNULL(visitor);
00146 visitor->VisitRankFirstInterval(sequence_, index_);
00147 }
00148
00149 virtual string DebugString() const {
00150 return StringPrintf("RankFirst(%s, %d)",
00151 sequence_->DebugString().c_str(), index_);
00152 }
00153
00154 private:
00155 SequenceVar* const sequence_;
00156 const int index_;
00157 };
00158
00159 class RankLast : public Decision {
00160 public:
00161 RankLast(SequenceVar* const seq, int index)
00162 : sequence_(seq), index_(index) {}
00163 virtual ~RankLast() {}
00164
00165 virtual void Apply(Solver* const s) {
00166 sequence_->RankLast(index_);
00167 }
00168
00169 virtual void Refute(Solver* const s) {
00170 sequence_->RankNotLast(index_);
00171 }
00172
00173 void Accept(DecisionVisitor* const visitor) const {
00174 CHECK_NOTNULL(visitor);
00175 visitor->VisitRankLastInterval(sequence_, index_);
00176 }
00177
00178 virtual string DebugString() const {
00179 return StringPrintf("RankLast(%s, %d)",
00180 sequence_->DebugString().c_str(), index_);
00181 }
00182
00183 private:
00184 SequenceVar* const sequence_;
00185 const int index_;
00186 };
00187
00188 class RankFirstIntervalVars : public DecisionBuilder {
00189 public:
00190 RankFirstIntervalVars(const SequenceVar* const * sequences,
00191 int size,
00192 Solver::SequenceStrategy str)
00193 : sequences_(new SequenceVar*[size]), size_(size), strategy_(str) {
00194 memcpy(sequences_.get(), sequences, size_ * sizeof(*sequences));
00195 }
00196
00197 virtual ~RankFirstIntervalVars() {}
00198
00199 virtual Decision* Next(Solver* const s) {
00200 SequenceVar* best_sequence = NULL;
00201 std::vector<int> best_possible_firsts;
00202 while (true) {
00203 if (FindSequenceVar(s, &best_sequence, &best_possible_firsts)) {
00204
00205 DCHECK(best_sequence != NULL);
00206 if (best_possible_firsts.size() == 1 &&
00207 best_sequence->Interval(
00208 best_possible_firsts.back())->MustBePerformed()) {
00209 best_sequence->RankFirst(best_possible_firsts.back());
00210 continue;
00211 }
00212 int best_interval = -1;
00213 if (!FindIntervalVar(s,
00214 best_sequence,
00215 best_possible_firsts,
00216 &best_interval)) {
00217 s->Fail();
00218 }
00219 CHECK_NE(-1, best_interval);
00220 return s->RevAlloc(new RankFirst(best_sequence, best_interval));
00221 } else {
00222 for (int i = 0; i < size_; ++i) {
00223 CHECK_EQ(0, sequences_[i]->NotRanked()) << sequences_[i]->DebugString();
00224 }
00225 return NULL;
00226 }
00227 }
00228 }
00229
00230 virtual void Accept(ModelVisitor* const visitor) const {
00231 visitor->BeginVisitExtension(ModelVisitor::kVariableGroupExtension);
00232 visitor->VisitSequenceArrayArgument(ModelVisitor::kSequencesArgument,
00233 sequences_.get(),
00234 size_);
00235 visitor->EndVisitExtension(ModelVisitor::kVariableGroupExtension);
00236 }
00237
00238 private:
00239
00240 bool FindIntervalVarOnStartMin(Solver* const s,
00241 SequenceVar* const best_sequence,
00242 const std::vector<int>& best_possible_firsts,
00243 int* const best_interval_index) {
00244 int best_interval = -1;
00245 int64 best_start_min = kint64max;
00246 for (int index = 0; index < best_possible_firsts.size(); ++index) {
00247 const int candidate = best_possible_firsts[index];
00248 IntervalVar* const interval = best_sequence->Interval(candidate);
00249 if (interval->StartMin() < best_start_min) {
00250 best_interval = candidate;
00251 best_start_min = interval->StartMin();
00252 }
00253 }
00254 if (best_interval == -1) {
00255 return false;
00256 } else {
00257 *best_interval_index = best_interval;
00258 return true;
00259 }
00260 }
00261
00262 bool FindIntervalVarRandomly(Solver* const s,
00263 SequenceVar* const best_sequence,
00264 const std::vector<int>& best_possible_firsts,
00265 int* const best_interval_index) {
00266 DCHECK(!best_possible_firsts.empty());
00267 const int index = s->Rand32(best_possible_firsts.size());
00268 *best_interval_index = best_possible_firsts[index];
00269 return true;
00270 }
00271
00272 bool FindIntervalVar(Solver* const s,
00273 SequenceVar* const best_sequence,
00274 const std::vector<int>& best_possible_firsts,
00275 int* const best_interval_index) {
00276 switch (strategy_) {
00277 case Solver::SEQUENCE_DEFAULT:
00278 case Solver::SEQUENCE_SIMPLE:
00279 case Solver::CHOOSE_MIN_SLACK_RANK_FORWARD:
00280 return FindIntervalVarOnStartMin(s,
00281 best_sequence,
00282 best_possible_firsts,
00283 best_interval_index);
00284 case Solver::CHOOSE_RANDOM_RANK_FORWARD:
00285 return FindIntervalVarRandomly(s,
00286 best_sequence,
00287 best_possible_firsts,
00288 best_interval_index);
00289 default:
00290 LOG(FATAL) << "Unknown strategy " << strategy_;
00291 }
00292 }
00293
00294
00295 bool FindSequenceVarOnSlack(Solver* const s,
00296 SequenceVar** const best_sequence,
00297 std::vector<int>* const best_possible_firsts) const {
00298 int64 best_slack = kint64max;
00299 int64 best_ahmin = kint64max;
00300 *best_sequence = NULL;
00301 best_possible_firsts->clear();
00302 for (int i = 0; i < size_; ++i) {
00303 SequenceVar* const candidate_sequence = sequences_[i];
00304 if (candidate_sequence->NotRanked() > 0) {
00305 std::vector<int> candidate_possible_firsts;
00306 std::vector<int> candidate_possible_Lasts;
00307 candidate_sequence->ComputePossibleFirstsAndLasts(
00308 &candidate_possible_firsts,
00309 &candidate_possible_Lasts);
00310
00311 if (candidate_possible_firsts.size() == 0) {
00312 s->Fail();
00313 }
00314
00315 if (candidate_possible_firsts.size() == 1 &&
00316 candidate_sequence->Interval(
00317 candidate_possible_firsts.back())->MustBePerformed()) {
00318 *best_sequence = candidate_sequence;
00319 *best_possible_firsts = candidate_possible_firsts;
00320 return true;
00321 }
00322
00323
00324 int64 hmin, hmax, dmin, dmax;
00325 candidate_sequence->HorizonRange(&hmin, &hmax);
00326 candidate_sequence->DurationRange(&dmin, &dmax);
00327 int64 ahmin, ahmax;
00328 candidate_sequence->ActiveHorizonRange(&ahmin, &ahmax);
00329 const int64 current_slack = (hmax - hmin - dmax);
00330 if (current_slack < best_slack ||
00331 (current_slack == best_slack && ahmin < best_ahmin)) {
00332 best_slack = current_slack;
00333 *best_sequence = candidate_sequence;
00334 *best_possible_firsts = candidate_possible_firsts;
00335 best_ahmin = ahmin;
00336 }
00337 }
00338 }
00339 return *best_sequence != NULL;
00340 }
00341
00342 bool FindSequenceVarRandomly(Solver* const s,
00343 SequenceVar** const best_sequence,
00344 std::vector<int>* const best_possible_firsts) const {
00345 std::vector<int> all_candidates;
00346 std::vector<std::vector<int> > all_possible_firsts;
00347 for (int i = 0; i < size_; ++i) {
00348 SequenceVar* const candidate_sequence = sequences_[i];
00349 if (candidate_sequence->NotRanked() > 0) {
00350 std::vector<int> candidate_possible_firsts;
00351 std::vector<int> candidate_possible_Lasts;
00352 candidate_sequence->ComputePossibleFirstsAndLasts(
00353 &candidate_possible_firsts,
00354 &candidate_possible_Lasts);
00355
00356 if (candidate_possible_firsts.size() == 0) {
00357 s->Fail();
00358 }
00359
00360 if (candidate_possible_firsts.size() == 1 &&
00361 candidate_sequence->Interval(
00362 candidate_possible_firsts.back())->MustBePerformed()) {
00363 *best_sequence = candidate_sequence;
00364 *best_possible_firsts = candidate_possible_firsts;
00365 return true;
00366 }
00367
00368 all_candidates.push_back(i);
00369 all_possible_firsts.push_back(candidate_possible_firsts);
00370 }
00371 }
00372 if (all_candidates.empty()) {
00373 return false;
00374 }
00375 const int chosen = s->Rand32(all_candidates.size());
00376 *best_sequence = sequences_[all_candidates[chosen]];
00377 *best_possible_firsts = all_possible_firsts[chosen];
00378 return true;
00379 }
00380
00381 bool FindSequenceVar(Solver* const s,
00382 SequenceVar** const best_sequence,
00383 std::vector<int>* const best_possible_firsts) const {
00384 switch (strategy_) {
00385 case Solver::SEQUENCE_DEFAULT:
00386 case Solver::SEQUENCE_SIMPLE:
00387 case Solver::CHOOSE_MIN_SLACK_RANK_FORWARD:
00388 return FindSequenceVarOnSlack(s,
00389 best_sequence,
00390 best_possible_firsts);
00391 case Solver::CHOOSE_RANDOM_RANK_FORWARD:
00392 return FindSequenceVarRandomly(s,
00393 best_sequence,
00394 best_possible_firsts);
00395 default:
00396 LOG(FATAL) << "Unknown strategy " << strategy_;
00397 }
00398 }
00399
00400 scoped_array<SequenceVar*> sequences_;
00401 const int size_;
00402 const Solver::SequenceStrategy strategy_;
00403 };
00404 }
00405
00406 Decision* Solver::MakeScheduleOrPostpone(IntervalVar* const var,
00407 int64 est,
00408 int64* const marker) {
00409 CHECK_NOTNULL(var);
00410 CHECK_NOTNULL(marker);
00411 return RevAlloc(new ScheduleOrPostpone(var, est, marker));
00412 }
00413
00414 DecisionBuilder* Solver::MakePhase(const std::vector<IntervalVar*>& intervals,
00415 IntervalStrategy str) {
00416 return RevAlloc(new SetTimesForward(intervals.data(), intervals.size()));
00417 }
00418
00419 Decision* Solver::MakeRankFirstInterval(SequenceVar* const sequence,
00420 int index) {
00421 CHECK_NOTNULL(sequence);
00422 return RevAlloc(new RankFirst(sequence, index));
00423 }
00424
00425 Decision* Solver::MakeRankLastInterval(SequenceVar* const sequence, int index) {
00426 CHECK_NOTNULL(sequence);
00427 return RevAlloc(new RankLast(sequence, index));
00428 }
00429
00430 DecisionBuilder* Solver::MakePhase(const std::vector<SequenceVar*>& sequences,
00431 SequenceStrategy str) {
00432 return RevAlloc(new RankFirstIntervalVars(sequences.data(),
00433 sequences.size(),
00434 str));
00435 }
00436
00437 }