<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="l00032"name="l00032"></a><spanclass="lineno"> 32</span><spanclass="comment">// Enforces that the given tuple of variables takes different values. This fully</span></div>
<divclass="line"><aid="l00033"name="l00033"></a><spanclass="lineno"> 33</span><spanclass="comment">// encodes all the variables and simply enforces a <= 1 constraint on each</span></div>
<divclass="line"><aid="l00034"name="l00034"></a><spanclass="lineno"> 34</span><spanclass="comment">// possible values.</span></div>
<divclass="line"><aid="l00038"name="l00038"></a><spanclass="lineno"> 38</span><spanclass="comment">// Enforces that the given tuple of variables takes different values.</span></div>
<divclass="line"><aid="l00039"name="l00039"></a><spanclass="lineno"> 39</span><spanclass="comment">// Same as AllDifferentBinary() but use a different propagator that only enforce</span></div>
<divclass="line"><aid="l00040"name="l00040"></a><spanclass="lineno"> 40</span><spanclass="comment">// the so called "bound consistency" on the variable domains.</span></div>
<divclass="line"><aid="l00042"name="l00042"></a><spanclass="lineno"> 42</span><spanclass="comment">// Compared to AllDifferentBinary() this doesn't require fully encoding the</span></div>
<divclass="line"><aid="l00043"name="l00043"></a><spanclass="lineno"> 43</span><spanclass="comment">// variables and it is also quite fast. Note that the propagation is different,</span></div>
<divclass="line"><aid="l00044"name="l00044"></a><spanclass="lineno"> 44</span><spanclass="comment">// this will not remove already taken values from inside a domain, but it will</span></div>
<divclass="line"><aid="l00045"name="l00045"></a><spanclass="lineno"> 45</span><spanclass="comment">// propagates more the domain bounds.</span></div>
<divclass="line"><aid="l00051"name="l00051"></a><spanclass="lineno"> 51</span><spanclass="comment">// This constraint forces all variables to take different values. This is meant</span></div>
<divclass="line"><aid="l00052"name="l00052"></a><spanclass="lineno"> 52</span><spanclass="comment">// to be used as a complement to an alldifferent decomposition like</span></div>
<divclass="line"><aid="l00053"name="l00053"></a><spanclass="lineno"> 53</span><spanclass="comment">// AllDifferentBinary(): DO NOT USE WITHOUT ONE. Doing the filtering that the</span></div>
<divclass="line"><aid="l00054"name="l00054"></a><spanclass="lineno"> 54</span><spanclass="comment">// decomposition can do with an appropriate algorithm should be cheaper and</span></div>
<divclass="line"><aid="l00055"name="l00055"></a><spanclass="lineno"> 55</span><spanclass="comment">// yield more accurate explanations.</span></div>
<divclass="line"><aid="l00057"name="l00057"></a><spanclass="lineno"> 57</span><spanclass="comment">// It uses the matching algorithm described in Regin at AAAI1994:</span></div>
<divclass="line"><aid="l00058"name="l00058"></a><spanclass="lineno"> 58</span><spanclass="comment">// "A filtering algorithm for constraints of difference in CSPs".</span></div>
<divclass="line"><aid="l00075"name="l00075"></a><spanclass="lineno"> 75</span><spanclass="comment">// MakeAugmentingPath() is a step in Ford-Fulkerson's augmenting path</span></div>
<divclass="line"><aid="l00076"name="l00076"></a><spanclass="lineno"> 76</span><spanclass="comment">// algorithm. It changes its current internal state (see vectors below)</span></div>
<divclass="line"><aid="l00077"name="l00077"></a><spanclass="lineno"> 77</span><spanclass="comment">// to assign a value to the start vertex using an augmenting path.</span></div>
<divclass="line"><aid="l00078"name="l00078"></a><spanclass="lineno"> 78</span><spanclass="comment">// If it is not possible, it keeps variable_to_value_[start] to -1 and returns</span></div>
<divclass="line"><aid="l00079"name="l00079"></a><spanclass="lineno"> 79</span><spanclass="comment">// false, otherwise it modifies the current assignment and returns true.</span></div>
<divclass="line"><aid="l00080"name="l00080"></a><spanclass="lineno"> 80</span><spanclass="comment">// It uses value/variable_visited to mark the nodes it visits during its</span></div>
<divclass="line"><aid="l00081"name="l00081"></a><spanclass="lineno"> 81</span><spanclass="comment">// search: one can use this information to generate an explanation of failure,</span></div>
<divclass="line"><aid="l00082"name="l00082"></a><spanclass="lineno"> 82</span><spanclass="comment">// or manipulate it to create what-if scenarios without modifying successor_.</span></div>
<divclass="line"><aid="l00089"name="l00089"></a><spanclass="lineno"> 89</span><spanclass="comment">// This caches all literals of the fully encoded variables.</span></div>
<divclass="line"><aid="l00090"name="l00090"></a><spanclass="lineno"> 90</span><spanclass="comment">// Values of a given variable are 0-indexed using offsets variable_min_value_,</span></div>
<divclass="line"><aid="l00091"name="l00091"></a><spanclass="lineno"> 91</span><spanclass="comment">// the set of all values is globally offset using offset min_all_values_.</span></div>
<divclass="line"><aid="l00092"name="l00092"></a><spanclass="lineno"> 92</span><spanclass="comment">// TODO(user): compare this encoding to a sparser hash_map encoding.</span></div>
<divclass="line"><aid="l00101"name="l00101"></a><spanclass="lineno"> 101</span><spanclass="comment">// Internal state of MakeAugmentingPath().</span></div>
<divclass="line"><aid="l00102"name="l00102"></a><spanclass="lineno"> 102</span><spanclass="comment">// value_to_variable_ and variable_to_value_ represent the current assignment;</span></div>
<divclass="line"><aid="l00103"name="l00103"></a><spanclass="lineno"> 103</span><spanclass="comment">// -1 means not assigned. Otherwise,</span></div>
<divclass="line"><aid="l00104"name="l00104"></a><spanclass="lineno"> 104</span><spanclass="comment">// variable_to_value_[var] = value <=> value_to_variable_[value] = var.</span></div>
<divclass="line"><aid="l00114"name="l00114"></a><spanclass="lineno"> 114</span><spanclass="comment">// Internal state of ComputeSCCs().</span></div>
<divclass="line"><aid="l00115"name="l00115"></a><spanclass="lineno"> 115</span><spanclass="comment">// Variable nodes are indexed by [0, num_variables_),</span></div>
<divclass="line"><aid="l00116"name="l00116"></a><spanclass="lineno"> 116</span><spanclass="comment">// value nodes by [num_variables_, num_variables_ + num_all_values_),</span></div>
<divclass="line"><aid="l00117"name="l00117"></a><spanclass="lineno"> 117</span><spanclass="comment">// and a dummy node with index num_variables_ + num_all_values_ is added.</span></div>
<divclass="line"><aid="l00118"name="l00118"></a><spanclass="lineno"> 118</span><spanclass="comment">// The graph passed to ComputeSCCs() is the residual of the possible graph</span></div>
<divclass="line"><aid="l00119"name="l00119"></a><spanclass="lineno"> 119</span><spanclass="comment">// by the current matching, i.e. its arcs are:</span></div>
<divclass="line"><aid="l00120"name="l00120"></a><spanclass="lineno"> 120</span><spanclass="comment">// _ (var, val) if val \in dom(var) and var not matched to val,</span></div>
<divclass="line"><aid="l00121"name="l00121"></a><spanclass="lineno"> 121</span><spanclass="comment">// _ (val, var) if var matched to val,</span></div>
<divclass="line"><aid="l00122"name="l00122"></a><spanclass="lineno"> 122</span><spanclass="comment">// _ (val, dummy) if val not matched to any variable,</span></div>
<divclass="line"><aid="l00123"name="l00123"></a><spanclass="lineno"> 123</span><spanclass="comment">// _ (dummy, var) for all variables.</span></div>
<divclass="line"><aid="l00124"name="l00124"></a><spanclass="lineno"> 124</span><spanclass="comment">// In the original paper, forbidden arcs are identified by detecting that they</span></div>
<divclass="line"><aid="l00125"name="l00125"></a><spanclass="lineno"> 125</span><spanclass="comment">// are not in any alternating cycle or alternating path starting at a</span></div>
<divclass="line"><aid="l00126"name="l00126"></a><spanclass="lineno"> 126</span><spanclass="comment">// free vertex. Adding the dummy node allows to factor the alternating path</span></div>
<divclass="line"><aid="l00127"name="l00127"></a><spanclass="lineno"> 127</span><spanclass="comment">// part in the alternating cycle, and filter with only the SCC decomposition.</span></div>
<divclass="line"><aid="l00128"name="l00128"></a><spanclass="lineno"> 128</span><spanclass="comment">// When num_variables_ == num_all_values_, the dummy node is useless,</span></div>
<divclass="line"><aid="l00129"name="l00129"></a><spanclass="lineno"> 129</span><spanclass="comment">// we add it anyway to simplify the code.</span></div>
<divclass="line"><aid="l00137"name="l00137"></a><spanclass="lineno"> 137</span><spanclass="comment">// Implements the all different bound consistent propagator with explanation.</span></div>
<divclass="line"><aid="l00138"name="l00138"></a><spanclass="lineno"> 138</span><spanclass="comment">// That is, given n affine expressions that must take different values, this</span></div>
<divclass="line"><aid="l00139"name="l00139"></a><spanclass="lineno"> 139</span><spanclass="comment">// propagates the bounds of each expression as much as possible. The key is to</span></div>
<divclass="line"><aid="l00140"name="l00140"></a><spanclass="lineno"> 140</span><spanclass="comment">// detect the so called Hall interval which are interval of size k that contains</span></div>
<divclass="line"><aid="l00141"name="l00141"></a><spanclass="lineno"> 141</span><spanclass="comment">// the domain of k expressinos. Because all the variables must take different</span></div>
<divclass="line"><aid="l00142"name="l00142"></a><spanclass="lineno"> 142</span><spanclass="comment">// values, we can deduce that the domain of the other variables cannot contains</span></div>
<divclass="line"><aid="l00143"name="l00143"></a><spanclass="lineno"> 143</span><spanclass="comment">// such Hall interval.</span></div>
<divclass="line"><aid="l00145"name="l00145"></a><spanclass="lineno"> 145</span><spanclass="comment">// We use a "fast" O(n log n) algorithm.</span></div>
<divclass="line"><aid="l00147"name="l00147"></a><spanclass="lineno"> 147</span><spanclass="comment">// TODO(user): It might be difficult to find something faster than what is</span></div>
<divclass="line"><aid="l00148"name="l00148"></a><spanclass="lineno"> 148</span><spanclass="comment">// implemented here. Some related reference:</span></div>
<divclass="line"><aid="l00159"name="l00159"></a><spanclass="lineno"> 159</span><spanclass="comment">// We locally cache the lb/ub for faster sorting and to guarantee some</span></div>
<divclass="line"><aid="l00160"name="l00160"></a><spanclass="lineno"> 160</span><spanclass="comment">// invariant when we push bounds.</span></div>
<divclass="line"><aid="l00167"name="l00167"></a><spanclass="lineno"> 167</span><spanclass="comment">// Fills integer_reason_ with the reason why we have the given hall interval.</span></div>
<divclass="line"><aid="l00170"name="l00170"></a><spanclass="lineno"> 170</span><spanclass="comment">// Do half the job of Propagate(). This will split the variable into</span></div>
<divclass="line"><aid="l00171"name="l00171"></a><spanclass="lineno"> 171</span><spanclass="comment">// independent subset, and call PropagateLowerBoundsInternal() on each of</span></div>
<divclass="line"><aid="l00177"name="l00177"></a><spanclass="lineno"> 177</span><spanclass="comment">// Internally, we will maintain a set of non-consecutive integer intervals of</span></div>
<divclass="line"><aid="l00178"name="l00178"></a><spanclass="lineno"> 178</span><spanclass="comment">// the form [start, end]. Each point (i.e. IntegerValue) of such interval will</span></div>
<divclass="line"><aid="l00179"name="l00179"></a><spanclass="lineno"> 179</span><spanclass="comment">// be associated to an unique input expression and via an union-find algorithm</span></div>
<divclass="line"><aid="l00180"name="l00180"></a><spanclass="lineno"> 180</span><spanclass="comment">// point to its start. The end only make sense for representative.</span></div>
<divclass="line"><aid="l00182"name="l00182"></a><spanclass="lineno"> 182</span><spanclass="comment">// TODO(user): Because we don't use rank, we have a worst case complexity of</span></div>
<divclass="line"><aid="l00183"name="l00183"></a><spanclass="lineno"> 183</span><spanclass="comment">// O(n log n). We could try a normal Union-find data structure, but then we</span></div>
<divclass="line"><aid="l00184"name="l00184"></a><spanclass="lineno"> 184</span><spanclass="comment">// also have to maintain a start vector.</span></div>
<divclass="line"><aid="l00186"name="l00186"></a><spanclass="lineno"> 186</span><spanclass="comment">// Note that during the execution of the algorithm we start from empty</span></div>
<divclass="line"><aid="l00187"name="l00187"></a><spanclass="lineno"> 187</span><spanclass="comment">// intervals and finish with a set of points of size num_vars.</span></div>
<divclass="line"><aid="l00189"name="l00189"></a><spanclass="lineno"> 189</span><spanclass="comment">// The list of all points are maintained in the dense vectors index_to_*_</span></div>
<divclass="line"><aid="l00190"name="l00190"></a><spanclass="lineno"> 190</span><spanclass="comment">// where we have remapped values to indices (with GetIndex()) to make sure it</span></div>
<divclass="line"><aid="l00191"name="l00191"></a><spanclass="lineno"> 191</span><spanclass="comment">// always fall into the correct range.</span></div>
<divclass="line"><aid="l00204"name="l00204"></a><spanclass="lineno"> 204</span><spanclass="comment">// These vector will be either sorted by lb or by -ub.</span></div>
<divclass="line"><aid="l00208"name="l00208"></a><spanclass="lineno"> 208</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>