<ahref="all__different_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="l00035"name="l00035"></a><spanclass="lineno"> 35</span><spanclass="comment">// Enforces that the given tuple of variables takes different values. This fully</span></div>
<divclass="line"><aid="l00036"name="l00036"></a><spanclass="lineno"> 36</span><spanclass="comment">// encodes all the variables and simply enforces a <= 1 constraint on each</span></div>
<divclass="line"><aid="l00037"name="l00037"></a><spanclass="lineno"> 37</span><spanclass="comment">// possible values.</span></div>
<divclass="line"><aid="l00041"name="l00041"></a><spanclass="lineno"> 41</span><spanclass="comment">// Enforces that the given tuple of variables takes different values.</span></div>
<divclass="line"><aid="l00042"name="l00042"></a><spanclass="lineno"> 42</span><spanclass="comment">// Same as AllDifferentBinary() but use a different propagator that only enforce</span></div>
<divclass="line"><aid="l00043"name="l00043"></a><spanclass="lineno"> 43</span><spanclass="comment">// the so called "bound consistency" on the variable domains.</span></div>
<divclass="line"><aid="l00045"name="l00045"></a><spanclass="lineno"> 45</span><spanclass="comment">// Compared to AllDifferentBinary() this doesn't require fully encoding the</span></div>
<divclass="line"><aid="l00046"name="l00046"></a><spanclass="lineno"> 46</span><spanclass="comment">// variables and it is also quite fast. Note that the propagation is different,</span></div>
<divclass="line"><aid="l00047"name="l00047"></a><spanclass="lineno"> 47</span><spanclass="comment">// this will not remove already taken values from inside a domain, but it will</span></div>
<divclass="line"><aid="l00048"name="l00048"></a><spanclass="lineno"> 48</span><spanclass="comment">// propagates more the domain bounds.</span></div>
<divclass="line"><aid="l00054"name="l00054"></a><spanclass="lineno"> 54</span><spanclass="comment">// This constraint forces all variables to take different values. This is meant</span></div>
<divclass="line"><aid="l00055"name="l00055"></a><spanclass="lineno"> 55</span><spanclass="comment">// to be used as a complement to an alldifferent decomposition like</span></div>
<divclass="line"><aid="l00056"name="l00056"></a><spanclass="lineno"> 56</span><spanclass="comment">// AllDifferentBinary(): DO NOT USE WITHOUT ONE. Doing the filtering that the</span></div>
<divclass="line"><aid="l00057"name="l00057"></a><spanclass="lineno"> 57</span><spanclass="comment">// decomposition can do with an appropriate algorithm should be cheaper and</span></div>
<divclass="line"><aid="l00058"name="l00058"></a><spanclass="lineno"> 58</span><spanclass="comment">// yield more accurate explanations.</span></div>
<divclass="line"><aid="l00060"name="l00060"></a><spanclass="lineno"> 60</span><spanclass="comment">// It uses the matching algorithm described in Regin at AAAI1994:</span></div>
<divclass="line"><aid="l00061"name="l00061"></a><spanclass="lineno"> 61</span><spanclass="comment">// "A filtering algorithm for constraints of difference in CSPs".</span></div>
<divclass="line"><aid="l00078"name="l00078"></a><spanclass="lineno"> 78</span><spanclass="comment">// MakeAugmentingPath() is a step in Ford-Fulkerson's augmenting path</span></div>
<divclass="line"><aid="l00079"name="l00079"></a><spanclass="lineno"> 79</span><spanclass="comment">// algorithm. It changes its current internal state (see vectors below)</span></div>
<divclass="line"><aid="l00080"name="l00080"></a><spanclass="lineno"> 80</span><spanclass="comment">// to assign a value to the start vertex using an augmenting path.</span></div>
<divclass="line"><aid="l00081"name="l00081"></a><spanclass="lineno"> 81</span><spanclass="comment">// If it is not possible, it keeps variable_to_value_[start] to -1 and returns</span></div>
<divclass="line"><aid="l00082"name="l00082"></a><spanclass="lineno"> 82</span><spanclass="comment">// false, otherwise it modifies the current assignment and returns true.</span></div>
<divclass="line"><aid="l00083"name="l00083"></a><spanclass="lineno"> 83</span><spanclass="comment">// It uses value/variable_visited to mark the nodes it visits during its</span></div>
<divclass="line"><aid="l00084"name="l00084"></a><spanclass="lineno"> 84</span><spanclass="comment">// search: one can use this information to generate an explanation of failure,</span></div>
<divclass="line"><aid="l00085"name="l00085"></a><spanclass="lineno"> 85</span><spanclass="comment">// or manipulate it to create what-if scenarios without modifying successor_.</span></div>
<divclass="line"><aid="l00092"name="l00092"></a><spanclass="lineno"> 92</span><spanclass="comment">// This caches all literals of the fully encoded variables.</span></div>
<divclass="line"><aid="l00093"name="l00093"></a><spanclass="lineno"> 93</span><spanclass="comment">// Values of a given variable are 0-indexed using offsets variable_min_value_,</span></div>
<divclass="line"><aid="l00094"name="l00094"></a><spanclass="lineno"> 94</span><spanclass="comment">// the set of all values is globally offset using offset min_all_values_.</span></div>
<divclass="line"><aid="l00095"name="l00095"></a><spanclass="lineno"> 95</span><spanclass="comment">// TODO(user): compare this encoding to a sparser hash_map encoding.</span></div>
<divclass="line"><aid="l00104"name="l00104"></a><spanclass="lineno"> 104</span><spanclass="comment">// Internal state of MakeAugmentingPath().</span></div>
<divclass="line"><aid="l00105"name="l00105"></a><spanclass="lineno"> 105</span><spanclass="comment">// value_to_variable_ and variable_to_value_ represent the current assignment;</span></div>
<divclass="line"><aid="l00106"name="l00106"></a><spanclass="lineno"> 106</span><spanclass="comment">// -1 means not assigned. Otherwise,</span></div>
<divclass="line"><aid="l00107"name="l00107"></a><spanclass="lineno"> 107</span><spanclass="comment">// variable_to_value_[var] = value <=> value_to_variable_[value] = var.</span></div>
<divclass="line"><aid="l00117"name="l00117"></a><spanclass="lineno"> 117</span><spanclass="comment">// Internal state of ComputeSCCs().</span></div>
<divclass="line"><aid="l00118"name="l00118"></a><spanclass="lineno"> 118</span><spanclass="comment">// Variable nodes are indexed by [0, num_variables_),</span></div>
<divclass="line"><aid="l00119"name="l00119"></a><spanclass="lineno"> 119</span><spanclass="comment">// value nodes by [num_variables_, num_variables_ + num_all_values_),</span></div>
<divclass="line"><aid="l00120"name="l00120"></a><spanclass="lineno"> 120</span><spanclass="comment">// and a dummy node with index num_variables_ + num_all_values_ is added.</span></div>
<divclass="line"><aid="l00121"name="l00121"></a><spanclass="lineno"> 121</span><spanclass="comment">// The graph passed to ComputeSCCs() is the residual of the possible graph</span></div>
<divclass="line"><aid="l00122"name="l00122"></a><spanclass="lineno"> 122</span><spanclass="comment">// by the current matching, i.e. its arcs are:</span></div>
<divclass="line"><aid="l00123"name="l00123"></a><spanclass="lineno"> 123</span><spanclass="comment">// _ (var, val) if val \in dom(var) and var not matched to val,</span></div>
<divclass="line"><aid="l00124"name="l00124"></a><spanclass="lineno"> 124</span><spanclass="comment">// _ (val, var) if var matched to val,</span></div>
<divclass="line"><aid="l00125"name="l00125"></a><spanclass="lineno"> 125</span><spanclass="comment">// _ (val, dummy) if val not matched to any variable,</span></div>
<divclass="line"><aid="l00126"name="l00126"></a><spanclass="lineno"> 126</span><spanclass="comment">// _ (dummy, var) for all variables.</span></div>
<divclass="line"><aid="l00127"name="l00127"></a><spanclass="lineno"> 127</span><spanclass="comment">// In the original paper, forbidden arcs are identified by detecting that they</span></div>
<divclass="line"><aid="l00128"name="l00128"></a><spanclass="lineno"> 128</span><spanclass="comment">// are not in any alternating cycle or alternating path starting at a</span></div>
<divclass="line"><aid="l00129"name="l00129"></a><spanclass="lineno"> 129</span><spanclass="comment">// free vertex. Adding the dummy node allows to factor the alternating path</span></div>
<divclass="line"><aid="l00130"name="l00130"></a><spanclass="lineno"> 130</span><spanclass="comment">// part in the alternating cycle, and filter with only the SCC decomposition.</span></div>
<divclass="line"><aid="l00131"name="l00131"></a><spanclass="lineno"> 131</span><spanclass="comment">// When num_variables_ == num_all_values_, the dummy node is useless,</span></div>
<divclass="line"><aid="l00132"name="l00132"></a><spanclass="lineno"> 132</span><spanclass="comment">// we add it anyway to simplify the code.</span></div>
<divclass="line"><aid="l00140"name="l00140"></a><spanclass="lineno"> 140</span><spanclass="comment">// Implements the all different bound consistent propagator with explanation.</span></div>
<divclass="line"><aid="l00141"name="l00141"></a><spanclass="lineno"> 141</span><spanclass="comment">// That is, given n affine expressions that must take different values, this</span></div>
<divclass="line"><aid="l00142"name="l00142"></a><spanclass="lineno"> 142</span><spanclass="comment">// propagates the bounds of each expression as much as possible. The key is to</span></div>
<divclass="line"><aid="l00143"name="l00143"></a><spanclass="lineno"> 143</span><spanclass="comment">// detect the so called Hall interval which are interval of size k that contains</span></div>
<divclass="line"><aid="l00144"name="l00144"></a><spanclass="lineno"> 144</span><spanclass="comment">// the domain of k expressinos. Because all the variables must take different</span></div>
<divclass="line"><aid="l00145"name="l00145"></a><spanclass="lineno"> 145</span><spanclass="comment">// values, we can deduce that the domain of the other variables cannot contains</span></div>
<divclass="line"><aid="l00146"name="l00146"></a><spanclass="lineno"> 146</span><spanclass="comment">// such Hall interval.</span></div>
<divclass="line"><aid="l00148"name="l00148"></a><spanclass="lineno"> 148</span><spanclass="comment">// We use a "fast" O(n log n) algorithm.</span></div>
<divclass="line"><aid="l00150"name="l00150"></a><spanclass="lineno"> 150</span><spanclass="comment">// TODO(user): It might be difficult to find something faster than what is</span></div>
<divclass="line"><aid="l00151"name="l00151"></a><spanclass="lineno"> 151</span><spanclass="comment">// implemented here. Some related reference:</span></div>
<divclass="line"><aid="l00162"name="l00162"></a><spanclass="lineno"> 162</span><spanclass="comment">// We locally cache the lb/ub for faster sorting and to guarantee some</span></div>
<divclass="line"><aid="l00163"name="l00163"></a><spanclass="lineno"> 163</span><spanclass="comment">// invariant when we push bounds.</span></div>
<divclass="line"><aid="l00170"name="l00170"></a><spanclass="lineno"> 170</span><spanclass="comment">// Fills integer_reason_ with the reason why we have the given hall interval.</span></div>
<divclass="line"><aid="l00173"name="l00173"></a><spanclass="lineno"> 173</span><spanclass="comment">// Do half the job of Propagate(). This will split the variable into</span></div>
<divclass="line"><aid="l00174"name="l00174"></a><spanclass="lineno"> 174</span><spanclass="comment">// independent subset, and call PropagateLowerBoundsInternal() on each of</span></div>
<divclass="line"><aid="l00180"name="l00180"></a><spanclass="lineno"> 180</span><spanclass="comment">// Internally, we will maintain a set of non-consecutive integer intervals of</span></div>
<divclass="line"><aid="l00181"name="l00181"></a><spanclass="lineno"> 181</span><spanclass="comment">// the form [start, end]. Each point (i.e. IntegerValue) of such interval will</span></div>
<divclass="line"><aid="l00182"name="l00182"></a><spanclass="lineno"> 182</span><spanclass="comment">// be associated to an unique input expression and via an union-find algorithm</span></div>
<divclass="line"><aid="l00183"name="l00183"></a><spanclass="lineno"> 183</span><spanclass="comment">// point to its start. The end only make sense for representative.</span></div>
<divclass="line"><aid="l00185"name="l00185"></a><spanclass="lineno"> 185</span><spanclass="comment">// TODO(user): Because we don't use rank, we have a worst case complexity of</span></div>
<divclass="line"><aid="l00186"name="l00186"></a><spanclass="lineno"> 186</span><spanclass="comment">// O(n log n). We could try a normal Union-find data structure, but then we</span></div>
<divclass="line"><aid="l00187"name="l00187"></a><spanclass="lineno"> 187</span><spanclass="comment">// also have to maintain a start vector.</span></div>
<divclass="line"><aid="l00189"name="l00189"></a><spanclass="lineno"> 189</span><spanclass="comment">// Note that during the execution of the algorithm we start from empty</span></div>
<divclass="line"><aid="l00190"name="l00190"></a><spanclass="lineno"> 190</span><spanclass="comment">// intervals and finish with a set of points of size num_vars.</span></div>
<divclass="line"><aid="l00192"name="l00192"></a><spanclass="lineno"> 192</span><spanclass="comment">// The list of all points are maintained in the dense vectors index_to_*_</span></div>
<divclass="line"><aid="l00193"name="l00193"></a><spanclass="lineno"> 193</span><spanclass="comment">// where we have remapped values to indices (with GetIndex()) to make sure it</span></div>
<divclass="line"><aid="l00194"name="l00194"></a><spanclass="lineno"> 194</span><spanclass="comment">// always fall into the correct range.</span></div>
<divclass="line"><aid="l00207"name="l00207"></a><spanclass="lineno"> 207</span><spanclass="comment">// These vector will be either sorted by lb or by -ub.</span></div>
<divclass="line"><aid="l00211"name="l00211"></a><spanclass="lineno"> 211</span><spanclass="comment">// The list of Hall intervalls detected so far, sorted.</span></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>