00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <deque>
00015 #include <vector>
00016
00017 #include "base/integral_types.h"
00018 #include "base/logging.h"
00019 #include "base/concise_iterator.h"
00020 #include "base/map-util.h"
00021 #include "base/stl_util.h"
00022 #include "base/hash.h"
00023 #include "constraint_solver/constraint_solver.h"
00024 #include "constraint_solver/constraint_solveri.h"
00025 #include "util/bitset.h"
00026
00027 namespace operations_research {
00028
00029 struct Arc {
00030 Arc(DependencyGraphNode* const n, int64 o) : node(n), offset(o) {}
00031 DependencyGraphNode* node;
00032 int64 offset;
00033 };
00034
00035 typedef std::vector<Arc> Arcs;
00036
00037
00038 class DependencyGraphNode {
00039 public:
00040 enum PerformedState { UNPERFORMED, PERFORMED, UNDECIDED };
00041 explicit DependencyGraphNode(DependencyGraph* const graph) : graph_(graph) {
00042 CHECK_NOTNULL(graph_);
00043 }
00044 virtual ~DependencyGraphNode() {}
00045 virtual int64 Min() const = 0;
00046 virtual int64 Max() const = 0;
00047 virtual PerformedState State() = 0;
00048 void SetMin(int64 new_min);
00049 virtual void SetMinInternal(int64 new_min) = 0;
00050 void SetMax(int64 new_max);
00051 virtual void SetMaxInternal(int64 new_max) = 0;
00052 virtual void SetState(PerformedState state) = 0;
00053 virtual string DebugString() const = 0;
00054
00055 void AddMinDependency(DependencyGraphNode* const node, int64 offset);
00056 void AddMaxDependency(DependencyGraphNode* const node, int64 offset);
00057 const Arcs& min_dependencies() const { return min_dependencies_; }
00058 const Arcs& max_dependencies() const { return max_dependencies_; }
00059 void PropagateMin();
00060 void PropagateMax();
00061 DependencyGraph* graph() const { return graph_; }
00062
00063 private:
00064 Arcs min_dependencies_;
00065 Arcs max_dependencies_;
00066 DependencyGraph* const graph_;
00067 };
00068
00069 namespace {
00070 class IntervalVarStartAdapter : public DependencyGraphNode {
00071 public:
00072 IntervalVarStartAdapter(DependencyGraph* const graph, IntervalVar* const var)
00073 : DependencyGraphNode(graph), interval_var_(var) {
00074 CHECK_NOTNULL(graph);
00075 CHECK_NOTNULL(var);
00076 Demon* const demon =
00077 interval_var_->solver()->MakeCallbackDemon(
00078 NewPermanentCallback(
00079 this,
00080 &IntervalVarStartAdapter::WhenIntervalChanged));
00081 interval_var_->WhenAnything(demon);
00082 }
00083
00084 virtual ~IntervalVarStartAdapter() {}
00085
00086 virtual int64 Min() const {
00087 return interval_var_->StartMin();
00088 }
00089
00090 virtual int64 Max() const {
00091 return interval_var_->StartMax();
00092 }
00093
00094 virtual void SetMinInternal(int64 new_min) {
00095 interval_var_->SetStartMin(new_min);
00096 }
00097
00098 virtual void SetMaxInternal(int64 new_max) {
00099 interval_var_->SetStartMax(new_max);
00100 }
00101
00102 virtual PerformedState State() {
00103 if (interval_var_->MustBePerformed()) {
00104 return PERFORMED;
00105 } else if (interval_var_->MayBePerformed()) {
00106 return UNPERFORMED;
00107 } else {
00108 return UNDECIDED;
00109 }
00110 }
00111
00112 virtual void SetState(PerformedState state) {
00113 CHECK_NE(state, UNDECIDED);
00114 interval_var_->SetPerformed(state == PERFORMED);
00115 }
00116
00117 virtual string DebugString() const {
00118 return StringPrintf("Node-Start(%s)", interval_var_->DebugString().c_str());
00119 }
00120
00121 virtual void WhenIntervalChanged() {
00122 graph()->Enqueue(this, true);
00123 graph()->Enqueue(this, false);
00124 }
00125
00126 private:
00127 IntervalVar* const interval_var_;
00128 };
00129
00130 class NonReversibleDependencyGraph : public DependencyGraph {
00131 public:
00132
00133 struct QueueElem {
00134 QueueElem(DependencyGraphNode* const n, bool c) : node(n), changed_min(c) {}
00135 DependencyGraphNode* node;
00136 bool changed_min;
00137 };
00138
00139 explicit NonReversibleDependencyGraph(Solver* const solver)
00140 : solver_(solver), in_process_(0) {}
00141
00142 virtual ~NonReversibleDependencyGraph() {}
00143
00144 virtual void AddEquality(DependencyGraphNode* const left,
00145 DependencyGraphNode* const right,
00146 int64 offset) {
00147 AddInequality(left, right, offset);
00148 AddInequality(right, left, -offset);
00149 }
00150
00151 virtual void AddInequality(DependencyGraphNode* const left,
00152 DependencyGraphNode* const right,
00153 int64 offset) {
00154 right->AddMinDependency(left, offset);
00155 left->AddMaxDependency(right, offset);
00156 Freeze();
00157 Enqueue(right, true);
00158 Enqueue(left, false);
00159 UnFreeze();
00160 }
00161
00162 virtual void PropagatePerformed(DependencyGraphNode* const node) {
00163 Freeze();
00164 Enqueue(node, true);
00165 Enqueue(node, false);
00166 UnFreeze();
00167 }
00168
00169 virtual void Enqueue(DependencyGraphNode* const node, bool changed_min) {
00170 CheckStamp();
00171 actives_.push_back(QueueElem(node, changed_min));
00172 ProcessQueue();
00173 }
00174
00175 private:
00176 bool Dequeue(DependencyGraphNode** const node, bool* const changed_min) {
00177 DCHECK(node != NULL);
00178 DCHECK(changed_min != NULL);
00179 if (actives_.empty()) {
00180 return false;
00181 }
00182
00183 *node = actives_.front().node;
00184 *changed_min = actives_.front().changed_min;
00185 actives_.pop_front();
00186 return true;
00187 }
00188
00189 void ProcessQueue() {
00190 if (in_process_ == 0) {
00191 ++in_process_;
00192 DependencyGraphNode* node = NULL;
00193 bool changed_min = false;
00194 while (Dequeue(&node, &changed_min)) {
00195 if (changed_min) {
00196 node->PropagateMin();
00197 } else {
00198 node->PropagateMax();
00199 }
00200 }
00201 --in_process_;
00202 }
00203 }
00204
00205 void CheckStamp() {
00206 if (in_process_ == 0 && solver_->fail_stamp() != fail_stamp_) {
00207 Clear();
00208 fail_stamp_ = solver_->fail_stamp();
00209 }
00210 }
00211
00212 void Freeze() {
00213 CheckStamp();
00214 ++in_process_;
00215 }
00216
00217 void UnFreeze() {
00218 --in_process_;
00219 ProcessQueue();
00220 }
00221
00222 void Clear() {
00223 actives_.clear();
00224 in_process_ = 0;
00225 }
00226
00227 Solver* const solver_;
00228 std::deque<QueueElem> actives_;
00229 int in_process_;
00230 uint64 fail_stamp_;
00231 };
00232 }
00233
00234
00235
00236 void DependencyGraphNode::AddMinDependency(DependencyGraphNode* const node,
00237 int64 offset) {
00238 min_dependencies_.push_back(Arc(node, offset));
00239 }
00240
00241 void DependencyGraphNode::SetMin(int64 new_min) {
00242 if (Min() < new_min) {
00243 SetMinInternal(new_min);
00244 graph_->Enqueue(this, true);
00245 }
00246 }
00247
00248 void DependencyGraphNode::SetMax(int64 new_max) {
00249 if (Max() > new_max) {
00250 SetMaxInternal(new_max);
00251 graph_->Enqueue(this, false);
00252 }
00253 }
00254
00255 void DependencyGraphNode::PropagateMin() {
00256 if (State() == PERFORMED) {
00257 const int64 current_min = Min();
00258 for (ConstIter<Arcs> it(min_dependencies_); !it.at_end(); ++it) {
00259 it->node->SetMin(current_min + it->offset);
00260 }
00261 }
00262 }
00263
00264 void DependencyGraphNode::AddMaxDependency(DependencyGraphNode* const node,
00265 int64 offset) {
00266 max_dependencies_.push_back(Arc(node, offset));
00267 }
00268
00269 void DependencyGraphNode::PropagateMax() {
00270 if (State() == PERFORMED) {
00271 const int64 current_max = Max();
00272 for (ConstIter<Arcs> it(max_dependencies_); !it.at_end(); ++it) {
00273 it->node->SetMax(current_max - it->offset);
00274 }
00275 }
00276 }
00277
00278
00279
00280 DependencyGraph::~DependencyGraph() {
00281 STLDeleteElements(&managed_nodes_);
00282 }
00283
00284 DependencyGraphNode* DependencyGraph::BuildStartNode(IntervalVar* const var) {
00285 DependencyGraphNode* const already_there =
00286 FindPtrOrNull(start_node_map_, var);
00287 if (already_there != NULL) {
00288 return already_there;
00289 }
00290 DependencyGraphNode* const newly_created =
00291 new IntervalVarStartAdapter(this, var);
00292 start_node_map_[var] = newly_created;
00293 managed_nodes_.push_back(newly_created);
00294 return newly_created;
00295 }
00296
00297
00298
00299 void DependencyGraph::AddStartsAfterEndWithDelay(IntervalVar* const var1,
00300 IntervalVar* const var2,
00301 int64 delay) {
00302
00303 CHECK_EQ(var2->DurationMin(), var2->DurationMax());
00304 DependencyGraphNode* const node1 = BuildStartNode(var1);
00305 DependencyGraphNode* const node2 = BuildStartNode(var2);
00306 AddInequality(node1, node2, delay + var2->DurationMin());
00307 }
00308
00309 void DependencyGraph::AddStartsAtEndWithDelay(IntervalVar* const var1,
00310 IntervalVar* const var2,
00311 int64 delay) {
00312
00313 CHECK_EQ(var2->DurationMin(), var2->DurationMax());
00314 DependencyGraphNode* const node1 = BuildStartNode(var1);
00315 DependencyGraphNode* const node2 = BuildStartNode(var2);
00316 AddEquality(node1, node2, delay + var2->DurationMin());
00317 }
00318
00319 void DependencyGraph::AddStartsAfterStartWithDelay(IntervalVar* const var1,
00320 IntervalVar* const var2,
00321 int64 delay) {
00322 DependencyGraphNode* const node1 = BuildStartNode(var1);
00323 DependencyGraphNode* const node2 = BuildStartNode(var2);
00324 AddInequality(node1, node2, delay);
00325 }
00326
00327 void DependencyGraph::AddStartsAtStartWithDelay(IntervalVar* const var1,
00328 IntervalVar* const var2,
00329 int64 delay) {
00330 DependencyGraphNode* const node1 = BuildStartNode(var1);
00331 DependencyGraphNode* const node2 = BuildStartNode(var2);
00332 AddEquality(node1, node2, delay);
00333 }
00334
00335 DependencyGraph* BuildDependencyGraph(Solver* const solver) {
00336 return new NonReversibleDependencyGraph(solver);
00337 }
00338
00339 DependencyGraph* Solver::Graph() const {
00340 return dependency_graph_.get();
00341 }
00342 }