this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Patrick Pekczynski <pekczynski@ps.uni-sb.de> 5 * 6 * Copyright: 7 * Patrick Pekczynski, 2004 8 * 9 * This file is part of Gecode, the generic constraint 10 * development environment: 11 * http://www.gecode.org 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining 14 * a copy of this software and associated documentation files (the 15 * "Software"), to deal in the Software without restriction, including 16 * without limitation the rights to use, copy, modify, merge, publish, 17 * distribute, sublicense, and/or sell copies of the Software, and to 18 * permit persons to whom the Software is furnished to do so, subject to 19 * the following conditions: 20 * 21 * The above copyright notice and this permission notice shall be 22 * included in all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 * 32 */ 33 34namespace Gecode { namespace Int { namespace Sorted { 35 36 /** 37 * \brief Glover's maximum matching in a bipartite graph 38 * 39 * Compute a matching in the bipartite convex intersection graph with 40 * one partition containing the x views and the other containing 41 * the y views. The algorithm works with an implicit array structure 42 * of the intersection graph. 43 * 44 * Union-Find Implementation of F.Glover's matching algorithm. 45 * 46 * The idea is to mimick a priority queue storing x-indices 47 * \f$[i_0,\dots, i_{n-1}]\f$, s.t. the upper domain bounds are sorted 48 * \f$D_{i_0} \leq\dots\leq D_{i_{n-1}}\f$ where \f$ D_{i_0}\f$ 49 * is the top element 50 * 51 */ 52 53 template<class View> 54 inline bool 55 glover(ViewArray<View>& x, ViewArray<View>& y, 56 int tau[], int phi[], OfflineMinItem sequence[], int vertices[]) { 57 58 int xs = x.size(); 59 OfflineMin seq(sequence, vertices, xs); 60 int s = 0; 61 seq.makeset(); 62 63 for (int z = 0; z < xs; z++) { // forall y nodes 64 int maxy = y[z].max(); 65 // creating the sequence of inserts and extractions from the queue 66 for( ; s <xs && x[s].min() <= maxy; s++) { 67 seq[s].iset = z; 68 seq[z].rank++; 69 } 70 } 71 72 // offline-min-procedure 73 for (int i = 0; i < xs; i++) { 74 // the upper bound of the x-node should be minimal 75 int perm = tau[i]; 76 // find the iteration where \tau(i) became a matching candidate 77 int iter = seq[perm].iset; 78 if (iter<0) 79 return false; 80 int j = 0; 81 j = seq.find_pc(iter); 82 // check whether the sequence is valid 83 if (j >= xs) 84 return false; 85 // if there is no intersection between the matching candidate 86 // and the y node then there exists NO perfect matching 87 if (x[perm].max() < y[j].min()) 88 return false; 89 phi[j] = perm; 90 seq[perm].iset = -5; //remove from candidate set 91 int sqjsucc = seq[j].succ; 92 if (sqjsucc < xs) { 93 seq.unite(j,sqjsucc,sqjsucc); 94 } else { 95 seq[seq[j].root].name = sqjsucc; // end of sequence achieved 96 } 97 98 // adjust tree list 99 int pr = seq[j].pred; 100 if (pr != -1) 101 seq[pr].succ = sqjsucc; 102 if (sqjsucc != xs) 103 seq[sqjsucc].pred = pr; 104 } 105 return true; 106 } 107 108 /** 109 * \brief Symmetric glover function for the upper domain bounds 110 * 111 */ 112 template<class View> 113 inline bool 114 revglover(ViewArray<View>& x, ViewArray<View>& y, 115 int tau[], int phiprime[], OfflineMinItem sequence[], 116 int vertices[]) { 117 118 int xs = x.size(); 119 OfflineMin seq(sequence, vertices, xs); 120 int s = xs - 1; 121 seq.makeset(); 122 123 int miny = 0; 124 for (int z = xs; z--; ) { // forall y nodes 125 miny = y[z].min(); 126 // creating the sequence of inserts and extractions from the queue 127 for ( ; s > -1 && x[tau[s]].max() >= miny; s--) { 128 seq[tau[s]].iset = z; 129 seq[z].rank++; 130 } 131 } 132 133 // offline-min-procedure 134 for (int i = xs; i--; ) { 135 int perm = i; 136 int iter = seq[perm].iset; 137 if (iter < 0) 138 return false; 139 int j = 0; 140 j = seq.find_pc(iter); 141 if (j <= -1) 142 return false; 143 // if there is no intersection between the matching candidate 144 // and the y node then there exists NO perfect matching 145 if (x[perm].min() > y[j].max()) 146 return false; 147 phiprime[j] = perm; 148 seq[perm].iset = -5; 149 int sqjsucc = seq[j].pred; 150 if (sqjsucc >= 0) { 151 seq.unite(j, sqjsucc, sqjsucc); 152 } else { 153 seq[seq[j].root].name = sqjsucc; // end of sequence achieved 154 } 155 156 // adjust tree list 157 int pr = seq[j].succ; 158 if (pr != xs) 159 seq[pr].pred = sqjsucc; 160 if (sqjsucc != -1) 161 seq[sqjsucc].succ = pr; 162 } 163 return true; 164 } 165 166}}} 167 168// STATISTICS: int-prop 169