<ahref="all__different_8h.html">Go to the documentation of this file.</a><divclass="fragment"><divclass="line"><aname="l00001"></a><spanclass="lineno"> 1</span> <spanclass="comment">// Copyright 2010-2021 Google LLC</span></div>
<divclass="line"><aname="l00002"></a><spanclass="lineno"> 2</span> <spanclass="comment">// Licensed under the Apache License, Version 2.0 (the "License");</span></div>
<divclass="line"><aname="l00003"></a><spanclass="lineno"> 3</span> <spanclass="comment">// you may not use this file except in compliance with the License.</span></div>
<divclass="line"><aname="l00004"></a><spanclass="lineno"> 4</span> <spanclass="comment">// You may obtain a copy of the License at</span></div>
<divclass="line"><aname="l00008"></a><spanclass="lineno"> 8</span> <spanclass="comment">// Unless required by applicable law or agreed to in writing, software</span></div>
<divclass="line"><aname="l00009"></a><spanclass="lineno"> 9</span> <spanclass="comment">// distributed under the License is distributed on an "AS IS" BASIS,</span></div>
<divclass="line"><aname="l00010"></a><spanclass="lineno"> 10</span> <spanclass="comment">// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div>
<divclass="line"><aname="l00011"></a><spanclass="lineno"> 11</span> <spanclass="comment">// See the License for the specific language governing permissions and</span></div>
<divclass="line"><aname="l00012"></a><spanclass="lineno"> 12</span> <spanclass="comment">// limitations under the License.</span></div>
<divclass="line"><aname="l00032"></a><spanclass="lineno"> 32</span> <spanclass="comment">// Enforces that the given tuple of variables takes different values. This fully</span></div>
<divclass="line"><aname="l00033"></a><spanclass="lineno"> 33</span> <spanclass="comment">// encodes all the variables and simply enforces a <= 1 constraint on each</span></div>
<divclass="line"><aname="l00034"></a><spanclass="lineno"> 34</span> <spanclass="comment">// possible values.</span></div>
<divclass="line"><aname="l00038"></a><spanclass="lineno"> 38</span> <spanclass="comment">// Enforces that the given tuple of variables takes different values.</span></div>
<divclass="line"><aname="l00039"></a><spanclass="lineno"> 39</span> <spanclass="comment">// Same as AllDifferentBinary() but use a different propagator that only enforce</span></div>
<divclass="line"><aname="l00040"></a><spanclass="lineno"> 40</span> <spanclass="comment">// the so called "bound consistency" on the variable domains.</span></div>
<divclass="line"><aname="l00042"></a><spanclass="lineno"> 42</span> <spanclass="comment">// Compared to AllDifferentBinary() this doesn't require fully encoding the</span></div>
<divclass="line"><aname="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"><aname="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"><aname="l00045"></a><spanclass="lineno"> 45</span> <spanclass="comment">// propagates more the domain bounds.</span></div>
<divclass="line"><aname="l00049"></a><spanclass="lineno"> 49</span> <spanclass="comment">// This constraint forces all variables to take different values. This is meant</span></div>
<divclass="line"><aname="l00050"></a><spanclass="lineno"> 50</span> <spanclass="comment">// to be used as a complement to an alldifferent decomposition like</span></div>
<divclass="line"><aname="l00051"></a><spanclass="lineno"> 51</span> <spanclass="comment">// AllDifferentBinary(): DO NOT USE WITHOUT ONE. Doing the filtering that the</span></div>
<divclass="line"><aname="l00052"></a><spanclass="lineno"> 52</span> <spanclass="comment">// decomposition can do with an appropriate algorithm should be cheaper and</span></div>
<divclass="line"><aname="l00053"></a><spanclass="lineno"> 53</span> <spanclass="comment">// yield more accurate explanations.</span></div>
<divclass="line"><aname="l00055"></a><spanclass="lineno"> 55</span> <spanclass="comment">// It uses the matching algorithm described in Regin at AAAI1994:</span></div>
<divclass="line"><aname="l00056"></a><spanclass="lineno"> 56</span> <spanclass="comment">// "A filtering algorithm for constraints of difference in CSPs".</span></div>
<divclass="line"><aname="l00073"></a><spanclass="lineno"> 73</span> <spanclass="comment">// MakeAugmentingPath() is a step in Ford-Fulkerson's augmenting path</span></div>
<divclass="line"><aname="l00074"></a><spanclass="lineno"> 74</span> <spanclass="comment">// algorithm. It changes its current internal state (see vectors below)</span></div>
<divclass="line"><aname="l00075"></a><spanclass="lineno"> 75</span> <spanclass="comment">// to assign a value to the start vertex using an augmenting path.</span></div>
<divclass="line"><aname="l00076"></a><spanclass="lineno"> 76</span> <spanclass="comment">// If it is not possible, it keeps variable_to_value_[start] to -1 and returns</span></div>
<divclass="line"><aname="l00077"></a><spanclass="lineno"> 77</span> <spanclass="comment">// false, otherwise it modifies the current assignment and returns true.</span></div>
<divclass="line"><aname="l00078"></a><spanclass="lineno"> 78</span> <spanclass="comment">// It uses value/variable_visited to mark the nodes it visits during its</span></div>
<divclass="line"><aname="l00079"></a><spanclass="lineno"> 79</span> <spanclass="comment">// search: one can use this information to generate an explanation of failure,</span></div>
<divclass="line"><aname="l00080"></a><spanclass="lineno"> 80</span> <spanclass="comment">// or manipulate it to create what-if scenarios without modifying successor_.</span></div>
<divclass="line"><aname="l00087"></a><spanclass="lineno"> 87</span> <spanclass="comment">// This caches all literals of the fully encoded variables.</span></div>
<divclass="line"><aname="l00088"></a><spanclass="lineno"> 88</span> <spanclass="comment">// Values of a given variable are 0-indexed using offsets variable_min_value_,</span></div>
<divclass="line"><aname="l00089"></a><spanclass="lineno"> 89</span> <spanclass="comment">// the set of all values is globally offset using offset min_all_values_.</span></div>
<divclass="line"><aname="l00090"></a><spanclass="lineno"> 90</span> <spanclass="comment">// TODO(user): compare this encoding to a sparser hash_map encoding.</span></div>
<divclass="line"><aname="l00099"></a><spanclass="lineno"> 99</span> <spanclass="comment">// Internal state of MakeAugmentingPath().</span></div>
<divclass="line"><aname="l00100"></a><spanclass="lineno"> 100</span> <spanclass="comment">// value_to_variable_ and variable_to_value_ represent the current assignment;</span></div>
<divclass="line"><aname="l00101"></a><spanclass="lineno"> 101</span> <spanclass="comment">// -1 means not assigned. Otherwise,</span></div>
<divclass="line"><aname="l00102"></a><spanclass="lineno"> 102</span> <spanclass="comment">// variable_to_value_[var] = value <=> value_to_variable_[value] = var.</span></div>
<divclass="line"><aname="l00112"></a><spanclass="lineno"> 112</span> <spanclass="comment">// Internal state of ComputeSCCs().</span></div>
<divclass="line"><aname="l00113"></a><spanclass="lineno"> 113</span> <spanclass="comment">// Variable nodes are indexed by [0, num_variables_),</span></div>
<divclass="line"><aname="l00114"></a><spanclass="lineno"> 114</span> <spanclass="comment">// value nodes by [num_variables_, num_variables_ + num_all_values_),</span></div>
<divclass="line"><aname="l00115"></a><spanclass="lineno"> 115</span> <spanclass="comment">// and a dummy node with index num_variables_ + num_all_values_ is added.</span></div>
<divclass="line"><aname="l00116"></a><spanclass="lineno"> 116</span> <spanclass="comment">// The graph passed to ComputeSCCs() is the residual of the possible graph</span></div>
<divclass="line"><aname="l00117"></a><spanclass="lineno"> 117</span> <spanclass="comment">// by the current matching, i.e. its arcs are:</span></div>
<divclass="line"><aname="l00118"></a><spanclass="lineno"> 118</span> <spanclass="comment">// _ (var, val) if val \in dom(var) and var not matched to val,</span></div>
<divclass="line"><aname="l00119"></a><spanclass="lineno"> 119</span> <spanclass="comment">// _ (val, var) if var matched to val,</span></div>
<divclass="line"><aname="l00120"></a><spanclass="lineno"> 120</span> <spanclass="comment">// _ (val, dummy) if val not matched to any variable,</span></div>
<divclass="line"><aname="l00121"></a><spanclass="lineno"> 121</span> <spanclass="comment">// _ (dummy, var) for all variables.</span></div>
<divclass="line"><aname="l00122"></a><spanclass="lineno"> 122</span> <spanclass="comment">// In the original paper, forbidden arcs are identified by detecting that they</span></div>
<divclass="line"><aname="l00123"></a><spanclass="lineno"> 123</span> <spanclass="comment">// are not in any alternating cycle or alternating path starting at a</span></div>
<divclass="line"><aname="l00124"></a><spanclass="lineno"> 124</span> <spanclass="comment">// free vertex. Adding the dummy node allows to factor the alternating path</span></div>
<divclass="line"><aname="l00125"></a><spanclass="lineno"> 125</span> <spanclass="comment">// part in the alternating cycle, and filter with only the SCC decomposition.</span></div>
<divclass="line"><aname="l00126"></a><spanclass="lineno"> 126</span> <spanclass="comment">// When num_variables_ == num_all_values_, the dummy node is useless,</span></div>
<divclass="line"><aname="l00127"></a><spanclass="lineno"> 127</span> <spanclass="comment">// we add it anyway to simplify the code.</span></div>
<divclass="line"><aname="l00135"></a><spanclass="lineno"> 135</span> <spanclass="comment">// Implement the all different bound consistent propagator with explanation.</span></div>
<divclass="line"><aname="l00136"></a><spanclass="lineno"> 136</span> <spanclass="comment">// That is, given n variables that must be all different, this propagates the</span></div>
<divclass="line"><aname="l00137"></a><spanclass="lineno"> 137</span> <spanclass="comment">// bounds of each variables as much as possible. The key is to detect the so</span></div>
<divclass="line"><aname="l00138"></a><spanclass="lineno"> 138</span> <spanclass="comment">// called Hall interval which are interval of size k that contains the domain</span></div>
<divclass="line"><aname="l00139"></a><spanclass="lineno"> 139</span> <spanclass="comment">// of k variables. Because all the variables must take different values, we can</span></div>
<divclass="line"><aname="l00140"></a><spanclass="lineno"> 140</span> <spanclass="comment">// deduce that the domain of the other variables cannot contains such Hall</span></div>
<divclass="line"><aname="l00143"></a><spanclass="lineno"> 143</span> <spanclass="comment">// We use a "fast" O(n log n) algorithm.</span></div>
<divclass="line"><aname="l00145"></a><spanclass="lineno"> 145</span> <spanclass="comment">// TODO(user): It might be difficult to find something faster than what is</span></div>
<divclass="line"><aname="l00146"></a><spanclass="lineno"> 146</span> <spanclass="comment">// implemented here. Some related reference:</span></div>
<divclass="line"><aname="l00157"></a><spanclass="lineno"> 157</span> <spanclass="comment">// We locally cache the lb/ub for faster sorting and to guarantee some</span></div>
<divclass="line"><aname="l00158"></a><spanclass="lineno"> 158</span> <spanclass="comment">// invariant when we push bounds.</span></div>
<divclass="line"><aname="l00165"></a><spanclass="lineno"> 165</span> <spanclass="comment">// Fills integer_reason_ with the reason why we have the given hall interval.</span></div>
<divclass="line"><aname="l00168"></a><spanclass="lineno"> 168</span> <spanclass="comment">// Do half the job of Propagate(). This will split the variable into</span></div>
<divclass="line"><aname="l00169"></a><spanclass="lineno"> 169</span> <spanclass="comment">// independent subset, and call PropagateLowerBoundsInternal() on each of</span></div>
<divclass="line"><aname="l00175"></a><spanclass="lineno"> 175</span> <spanclass="comment">// Internally, we will maintain a set of non-consecutive integer intervals of</span></div>
<divclass="line"><aname="l00176"></a><spanclass="lineno"> 176</span> <spanclass="comment">// the form [start, end]. Each point (i.e. IntegerValue) of such interval will</span></div>
<divclass="line"><aname="l00177"></a><spanclass="lineno"> 177</span> <spanclass="comment">// be associated to an unique variable and via an union-find algorithm point</span></div>
<divclass="line"><aname="l00178"></a><spanclass="lineno"> 178</span> <spanclass="comment">// to its start. The end only make sense for representative.</span></div>
<divclass="line"><aname="l00180"></a><spanclass="lineno"> 180</span> <spanclass="comment">// TODO(user): Because we don't use rank, we have a worst case complexity of</span></div>
<divclass="line"><aname="l00181"></a><spanclass="lineno"> 181</span> <spanclass="comment">// O(n log n). We could try a normal Union-find data structure, but then we</span></div>
<divclass="line"><aname="l00182"></a><spanclass="lineno"> 182</span> <spanclass="comment">// also have to maintain a start vector.</span></div>
<divclass="line"><aname="l00184"></a><spanclass="lineno"> 184</span> <spanclass="comment">// Note that during the execution of the algorithm we start from empty</span></div>
<divclass="line"><aname="l00185"></a><spanclass="lineno"> 185</span> <spanclass="comment">// intervals and finish with a set of points of size num_vars.</span></div>
<divclass="line"><aname="l00187"></a><spanclass="lineno"> 187</span> <spanclass="comment">// The list of all points are maintained in the dense vectors index_to_*_</span></div>
<divclass="line"><aname="l00188"></a><spanclass="lineno"> 188</span> <spanclass="comment">// where we have remapped values to indices (with GetIndex()) to make sure it</span></div>
<divclass="line"><aname="l00189"></a><spanclass="lineno"> 189</span> <spanclass="comment">// always fall into the correct range.</span></div>
<divclass="line"><aname="l00206"></a><spanclass="lineno"> 206</span> <spanclass="comment">// These vector will be either sorted by lb or by ub.</span></div>
<divclass="line"><aname="l00210"></a><spanclass="lineno"> 210</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>