<ahref="theta__tree_8h.html">Go to the documentation of this file.</a><divclass="fragment"><divclass="line"><aid="l00001"name="l00001"></a><spanclass="lineno"> 1</span><spanclass="comment">// Copyright 2010-2021 Google LLC</span></div>
<divclass="line"><aid="l00002"name="l00002"></a><spanclass="lineno"> 2</span><spanclass="comment">// Licensed under the Apache License, Version 2.0 (the "License");</span></div>
<divclass="line"><aid="l00003"name="l00003"></a><spanclass="lineno"> 3</span><spanclass="comment">// you may not use this file except in compliance with the License.</span></div>
<divclass="line"><aid="l00004"name="l00004"></a><spanclass="lineno"> 4</span><spanclass="comment">// You may obtain a copy of the License at</span></div>
<divclass="line"><aid="l00008"name="l00008"></a><spanclass="lineno"> 8</span><spanclass="comment">// Unless required by applicable law or agreed to in writing, software</span></div>
<divclass="line"><aid="l00009"name="l00009"></a><spanclass="lineno"> 9</span><spanclass="comment">// distributed under the License is distributed on an "AS IS" BASIS,</span></div>
<divclass="line"><aid="l00010"name="l00010"></a><spanclass="lineno"> 10</span><spanclass="comment">// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div>
<divclass="line"><aid="l00011"name="l00011"></a><spanclass="lineno"> 11</span><spanclass="comment">// See the License for the specific language governing permissions and</span></div>
<divclass="line"><aid="l00012"name="l00012"></a><spanclass="lineno"> 12</span><spanclass="comment">// limitations under the License.</span></div>
<divclass="line"><aid="l00026"name="l00026"></a><spanclass="lineno"> 26</span><spanclass="comment">// The Theta-Lambda tree can be used to implement several scheduling algorithms.</span></div>
<divclass="line"><aid="l00028"name="l00028"></a><spanclass="lineno"> 28</span><spanclass="comment">// This template class is instantiated only for IntegerValue and int64_t.</span></div>
<divclass="line"><aid="l00030"name="l00030"></a><spanclass="lineno"> 30</span><spanclass="comment">// The tree structure itself is a binary tree coded in a vector, where node 0 is</span></div>
<divclass="line"><aid="l00031"name="l00031"></a><spanclass="lineno"> 31</span><spanclass="comment">// unused, node 1 is the root, node 2 is the left child of the root, node 3 its</span></div>
<divclass="line"><aid="l00032"name="l00032"></a><spanclass="lineno"> 32</span><spanclass="comment">// right child, etc.</span></div>
<divclass="line"><aid="l00034"name="l00034"></a><spanclass="lineno"> 34</span><spanclass="comment">// The API gives access to rightmost events that realize a given envelope.</span></div>
<divclass="line"><aid="l00037"name="l00037"></a><spanclass="lineno"> 37</span><spanclass="comment">// _ (0) Petr Vilim's PhD thesis "Global Constraints in Scheduling".</span></div>
<divclass="line"><aid="l00038"name="l00038"></a><spanclass="lineno"> 38</span><spanclass="comment">// _ (1) Petr Vilim "Edge Finding Filtering Algorithm for Discrete Cumulative</span></div>
<divclass="line"><aid="l00039"name="l00039"></a><spanclass="lineno"> 39</span><spanclass="comment">// Resources in O(kn log n)"</span></div>
<divclass="line"><aid="l00040"name="l00040"></a><spanclass="lineno"> 40</span><spanclass="comment">// _ (2) Petr Vilim "Max energy filtering algorithm for discrete cumulative</span></div>
<divclass="line"><aid="l00042"name="l00042"></a><spanclass="lineno"> 42</span><spanclass="comment">// _ (3) Wolf & Schrader "O(n log n) Overload Checking for the Cumulative</span></div>
<divclass="line"><aid="l00043"name="l00043"></a><spanclass="lineno"> 43</span><spanclass="comment">// Constraint and Its Application".</span></div>
<divclass="line"><aid="l00045"name="l00045"></a><spanclass="lineno"> 45</span><spanclass="comment">// in O(n^2 log n)".</span></div>
<divclass="line"><aid="l00046"name="l00046"></a><spanclass="lineno"> 46</span><spanclass="comment">// _ (5) Ouellet & Quimper "Time-table extended-edge-finding for the cumulative</span></div>
<divclass="line"><aid="l00049"name="l00049"></a><spanclass="lineno"> 49</span><spanclass="comment">// Instead of providing one declination of the theta-tree per possible filtering</span></div>
<divclass="line"><aid="l00050"name="l00050"></a><spanclass="lineno"> 50</span><spanclass="comment">// algorithm, this generalization intends to provide a data structure that can</span></div>
<divclass="line"><aid="l00051"name="l00051"></a><spanclass="lineno"> 51</span><spanclass="comment">// fit several algorithms.</span></div>
<divclass="line"><aid="l00052"name="l00052"></a><spanclass="lineno"> 52</span><spanclass="comment">// This tree is based around the notion of events. It has events at its leaves</span></div>
<divclass="line"><aid="l00053"name="l00053"></a><spanclass="lineno"> 53</span><spanclass="comment">// that can be present or absent, and present events come with an</span></div>
<divclass="line"><aid="l00054"name="l00054"></a><spanclass="lineno"> 54</span><spanclass="comment">// initial_envelope, a minimal and a maximal energy.</span></div>
<divclass="line"><aid="l00055"name="l00055"></a><spanclass="lineno"> 55</span><spanclass="comment">// All nodes maintain values on the set of present events under them:</span></div>
<divclass="line"><aid="l00062"name="l00062"></a><spanclass="lineno"> 62</span><spanclass="comment">// Thus, the envelope of a leaf representing an event, when present, is</span></div>
<divclass="line"><aid="l00065"name="l00065"></a><spanclass="lineno"> 65</span><spanclass="comment">// We also maintain envelope_opt with is the maximum envelope a node could take</span></div>
<divclass="line"><aid="l00066"name="l00066"></a><spanclass="lineno"> 66</span><spanclass="comment">// if at most one of the events were at its maximum energy.</span></div>
<divclass="line"><aid="l00075"name="l00075"></a><spanclass="lineno"> 75</span><spanclass="comment">// Most articles using theta-tree variants hack Vilim's original theta tree</span></div>
<divclass="line"><aid="l00076"name="l00076"></a><spanclass="lineno"> 76</span><spanclass="comment">// for the disjunctive resource constraint by manipulating envelope and</span></div>
<divclass="line"><aid="l00078"name="l00078"></a><spanclass="lineno"> 78</span><spanclass="comment">// _ in (0), initial_envelope = start_min, energy = duration</span></div>
<divclass="line"><aid="l00079"name="l00079"></a><spanclass="lineno"> 79</span><spanclass="comment">// _ in (3), initial_envelope = C * start_min, energy = demand * duration</span></div>
<divclass="line"><aid="l00080"name="l00080"></a><spanclass="lineno"> 80</span><spanclass="comment">// _ in (5), there are several trees in parallel:</span></div>
<divclass="line"><aid="l00081"name="l00081"></a><spanclass="lineno"> 81</span><spanclass="comment">// initial_envelope = C * start_min or (C - h) * start_min</span></div>
<divclass="line"><aid="l00082"name="l00082"></a><spanclass="lineno"> 82</span><spanclass="comment">// energy = demand * duration, h * (Horizon - start_min),</span></div>
<divclass="line"><aid="l00083"name="l00083"></a><spanclass="lineno"> 83</span><spanclass="comment">// or h * (end_min).</span></div>
<divclass="line"><aid="l00084"name="l00084"></a><spanclass="lineno"> 84</span><spanclass="comment">// _ in (2), same as (3), but putting the max energy instead of min in lambda.</span></div>
<divclass="line"><aid="l00085"name="l00085"></a><spanclass="lineno"> 85</span><spanclass="comment">// _ in OscaR's TimeTableOverloadChecker,</span></div>
<divclass="line"><aid="l00086"name="l00086"></a><spanclass="lineno"> 86</span><spanclass="comment">// initial_envelope = C * start_min -</span></div>
<divclass="line"><aid="l00087"name="l00087"></a><spanclass="lineno"> 87</span><spanclass="comment">// energy of mandatory profile before start_min,</span></div>
<divclass="line"><aid="l00088"name="l00088"></a><spanclass="lineno"> 88</span><spanclass="comment">// energy = demand * duration</span></div>
<divclass="line"><aid="l00090"name="l00090"></a><spanclass="lineno"> 90</span><spanclass="comment">// There is hope to unify the variants of these algorithms by abstracting the</span></div>
<divclass="line"><aid="l00091"name="l00091"></a><spanclass="lineno"> 91</span><spanclass="comment">// tasks away to reason only on events.</span></div>
<divclass="line"><aid="l00093"name="l00093"></a><spanclass="lineno"> 93</span><spanclass="comment">// The minimal value of an envelope, for instance the envelope of the empty set.</span></div>
<divclass="line"><aid="l00106"name="l00106"></a><spanclass="lineno"> 106</span><spanclass="comment">// Builds a reusable tree. Initialization is done with Reset().</span></div>
<divclass="line"><aid="l00109"name="l00109"></a><spanclass="lineno"> 109</span><spanclass="comment">// Initializes this class for events in [0, num_events) and makes all of them</span></div>
<divclass="line"><aid="l00110"name="l00110"></a><spanclass="lineno"> 110</span><spanclass="comment">// absent. Instead of allocating and de-allocating trees at every usage, i.e.</span></div>
<divclass="line"><aid="l00111"name="l00111"></a><spanclass="lineno"> 111</span><spanclass="comment">// at every Propagate() of the scheduling algorithms that uses it, this class</span></div>
<divclass="line"><aid="l00112"name="l00112"></a><spanclass="lineno"> 112</span><spanclass="comment">// allows to keep the same memory for each call.</span></div>
<divclass="line"><aid="l00115"name="l00115"></a><spanclass="lineno"> 115</span><spanclass="comment">// Recomputes the values of internal nodes of the tree from the values in the</span></div>
<divclass="line"><aid="l00116"name="l00116"></a><spanclass="lineno"> 116</span><spanclass="comment">// leaves. We enable batching modifications to the tree by providing</span></div>
<divclass="line"><aid="l00117"name="l00117"></a><spanclass="lineno"> 117</span><spanclass="comment">// DelayedXXX() methods that run in O(1), but those methods do not</span></div>
<divclass="line"><aid="l00118"name="l00118"></a><spanclass="lineno"> 118</span><spanclass="comment">// update internal nodes. This breaks tree invariants, so that GetXXX()</span></div>
<divclass="line"><aid="l00119"name="l00119"></a><spanclass="lineno"> 119</span><spanclass="comment">// methods will not reflect modifications made to events.</span></div>
<divclass="line"><aid="l00120"name="l00120"></a><spanclass="lineno"> 120</span><spanclass="comment">// RecomputeTreeForDelayedOperations() restores those invariants in O(n).</span></div>
<divclass="line"><aid="l00121"name="l00121"></a><spanclass="lineno"> 121</span><spanclass="comment">// Thus, batching operations can be done by first doing calls to DelayedXXX()</span></div>
<divclass="line"><aid="l00122"name="l00122"></a><spanclass="lineno"> 122</span><spanclass="comment">// methods, then calling RecomputeTreeForDelayedOperations() once.</span></div>
<divclass="line"><aid="l00125"name="l00125"></a><spanclass="lineno"> 125</span><spanclass="comment">// Makes event present and updates its initial envelope and min/max energies.</span></div>
<divclass="line"><aid="l00126"name="l00126"></a><spanclass="lineno"> 126</span><spanclass="comment">// The initial_envelope must be >= ThetaLambdaTreeNegativeInfinity().</span></div>
<divclass="line"><aid="l00127"name="l00127"></a><spanclass="lineno"> 127</span><spanclass="comment">// This updates the tree in O(log n).</span></div>
<divclass="line"><aid="l00131"name="l00131"></a><spanclass="lineno"> 131</span><spanclass="comment">// Delayed version of AddOrUpdateEvent(),</span></div>
<divclass="line"><aid="l00132"name="l00132"></a><spanclass="lineno"> 132</span><spanclass="comment">// see RecomputeTreeForDelayedOperations().</span></div>
<divclass="line"><aid="l00136"name="l00136"></a><spanclass="lineno"> 136</span><spanclass="comment">// Adds event to the lambda part of the tree only.</span></div>
<divclass="line"><aid="l00137"name="l00137"></a><spanclass="lineno"> 137</span><spanclass="comment">// This will leave GetEnvelope() unchanged, only GetOptionalEnvelope() can</span></div>
<divclass="line"><aid="l00138"name="l00138"></a><spanclass="lineno"> 138</span><spanclass="comment">// be affected. This is done by setting envelope to IntegerTypeMinimumValue(),</span></div>
<divclass="line"><aid="l00139"name="l00139"></a><spanclass="lineno"> 139</span><spanclass="comment">// energy_min to 0, and initial_envelope_opt and energy_max to the parameters.</span></div>
<divclass="line"><aid="l00140"name="l00140"></a><spanclass="lineno"> 140</span><spanclass="comment">// This updates the tree in O(log n).</span></div>
<divclass="line"><aid="l00144"name="l00144"></a><spanclass="lineno"> 144</span><spanclass="comment">// Delayed version of AddOrUpdateOptionalEvent(),</span></div>
<divclass="line"><aid="l00145"name="l00145"></a><spanclass="lineno"> 145</span><spanclass="comment">// see RecomputeTreeForDelayedOperations().</span></div>
<divclass="line"><aid="l00150"name="l00150"></a><spanclass="lineno"> 150</span><spanclass="comment">// Makes event absent, compute the new envelope in O(log n).</span></div>
<divclass="line"><aid="l00153"name="l00153"></a><spanclass="lineno"> 153</span><spanclass="comment">// Delayed version of RemoveEvent(), see RecomputeTreeForDelayedOperations().</span></div>
<divclass="line"><aid="l00156"name="l00156"></a><spanclass="lineno"> 156</span><spanclass="comment">// Returns the maximum envelope using all the energy_min in O(1).</span></div>
<divclass="line"><aid="l00157"name="l00157"></a><spanclass="lineno"> 157</span><spanclass="comment">// If theta is empty, returns ThetaLambdaTreeNegativeInfinity().</span></div>
<divclass="line"><aid="l00160"name="l00160"></a><spanclass="lineno"> 160</span><spanclass="comment">// Returns the maximum envelope using the energy min of all task but</span></div>
<divclass="line"><aid="l00161"name="l00161"></a><spanclass="lineno"> 161</span><spanclass="comment">// one and the energy max of the last one in O(1).</span></div>
<divclass="line"><aid="l00162"name="l00162"></a><spanclass="lineno"> 162</span><spanclass="comment">// If theta and lambda are empty, returns ThetaLambdaTreeNegativeInfinity().</span></div>
<divclass="line"><aid="l00165"name="l00165"></a><spanclass="lineno"> 165</span><spanclass="comment">// Computes the maximum event s.t. GetEnvelopeOf(event) > envelope_max.</span></div>
<divclass="line"><aid="l00166"name="l00166"></a><spanclass="lineno"> 166</span><spanclass="comment">// There must be such an event, i.e. GetEnvelope() > envelope_max.</span></div>
<divclass="line"><aid="l00167"name="l00167"></a><spanclass="lineno"> 167</span><spanclass="comment">// This finds the maximum event e such that</span></div>
<divclass="line"><aid="l00176"name="l00176"></a><spanclass="lineno"> 176</span><spanclass="comment">// Computes a pair of events (critical_event, optional_event) such that</span></div>
<divclass="line"><aid="l00177"name="l00177"></a><spanclass="lineno"> 177</span><spanclass="comment">// if optional_event was at its maximum energy, the envelope of critical_event</span></div>
<divclass="line"><aid="l00178"name="l00178"></a><spanclass="lineno"> 178</span><spanclass="comment">// would be greater than target_envelope.</span></div>
<divclass="line"><aid="l00180"name="l00180"></a><spanclass="lineno"> 180</span><spanclass="comment">// This assumes that such a pair exists, i.e. GetOptionalEnvelope() should be</span></div>
<divclass="line"><aid="l00181"name="l00181"></a><spanclass="lineno"> 181</span><spanclass="comment">// greater than target_envelope. More formally, this finds events such that:</span></div>
<divclass="line"><aid="l00187"name="l00187"></a><spanclass="lineno"> 187</span><spanclass="comment">// For efficiency reasons, this also fills available_energy with the maximum</span></div>
<divclass="line"><aid="l00188"name="l00188"></a><spanclass="lineno"> 188</span><spanclass="comment">// energy the optional task can take such that the optional envelope of the</span></div>
<divclass="line"><aid="l00189"name="l00189"></a><spanclass="lineno"> 189</span><spanclass="comment">// pair would be target_envelope, i.e.</span></div>
<divclass="line"><aid="l00215"name="l00215"></a><spanclass="lineno"> 215</span><spanclass="comment">// Propagates the change of leaf energies and envelopes towards the root.</span></div>
<divclass="line"><aid="l00218"name="l00218"></a><spanclass="lineno"> 218</span><spanclass="comment">// Finds the maximum leaf under node such that</span></div>
<divclass="line"><aid="l00225"name="l00225"></a><spanclass="lineno"> 225</span><spanclass="comment">// Returns the leaf with maximum energy delta under node.</span></div>
<divclass="line"><aid="l00228"name="l00228"></a><spanclass="lineno"> 228</span><spanclass="comment">// Finds the leaves and energy relevant for</span></div>
<divclass="line"><aid="l00234"name="l00234"></a><spanclass="lineno"> 234</span><spanclass="comment">// Number of events of the last Reset().</span></div>
<divclass="line"><aid="l00239"name="l00239"></a><spanclass="lineno"> 239</span><spanclass="comment">// A bool used in debug mode, to check that sequences of delayed operations</span></div>
<divclass="line"><aid="l00240"name="l00240"></a><spanclass="lineno"> 240</span><spanclass="comment">// are ended by Reset() or RecomputeTreeForDelayedOperations().</span></div>
<divclass="ttc"id="aclassoperations__research_1_1sat_1_1_theta_lambda_tree_html_a0cd86cea355b2b1f70e5494fdce82979"><divclass="ttname"><ahref="classoperations__research_1_1sat_1_1_theta_lambda_tree.html#a0cd86cea355b2b1f70e5494fdce82979">operations_research::sat::ThetaLambdaTree::GetEventsWithOptionalEnvelopeGreaterThan</a></div><divclass="ttdeci">void GetEventsWithOptionalEnvelopeGreaterThan(IntegerType target_envelope, int *critical_event, int *optional_event, IntegerType *available_energy) const</div><divclass="ttdef"><b>Definition:</b><ahref="theta__tree_8cc_source.html#l00190">theta_tree.cc:190</a></div></div>
<divclass="ttc"id="anamespaceoperations__research_html"><divclass="ttname"><ahref="namespaceoperations__research.html">operations_research</a></div><divclass="ttdoc">Collection of objects used to extend the Constraint Solver library.</div><divclass="ttdef"><b>Definition:</b><ahref="dense__doubly__linked__list_8h_source.html#l00021">dense_doubly_linked_list.h:21</a></div></div>