Dip  0.92.4
MAD_Qualex.h
Go to the documentation of this file.
1 //===========================================================================//
2 // This file is part of the Decomp Solver Framework. //
3 // //
4 // Decomp is distributed under the Common Public License as part of the //
5 // COIN-OR repository (http://www.coin-or.org). //
6 // //
7 // Authors: Matthew Galati, SAS Institute Inc. (matthew.galati@sas.com) //
8 // Ted Ralphs, Lehigh University (ted@lehigh.edu) //
9 // Jiadong Wang, Lehigh University (jiw408@lehigh.edu) //
10 // //
11 // Copyright (C) 2002-2019, Lehigh University, Matthew Galati, and Ted Ralphs//
12 // All Rights Reserved. //
13 //===========================================================================//
14 
15 #ifndef MAD_QUALEX_INCLUDED
16 #define MAD_QUALEX_INCLUDED
17 
18 //---
19 //--- The MAD Qualex -- interface class for Qualex-MS solver
20 //--- http://www.busygin.dp.ua/npc.html
21 //---
22 
23 // --------------------------------------------------------------------- //
24 #include <algorithm>
25 using namespace std;
26 
27 // --------------------------------------------------------------------- //
28 #include "qualex.h"
29 #include "bool_vector.h"
30 #include "preproc_clique.h"
31 #include "greedy_clique.h"
32 
33 // --------------------------------------------------------------------- //
34 class MAD_Qualex{
35  public:
36 
37  //private:
38  MaxCliqueInfo * m_info;
39  Graph * m_graph; //temp storage for compl graph
40  Graph * m_graphOrig; //temp storage for compl graph (orig)
41  double * m_ijMatrix; //temp storage for qualex-ms
42 
43  vector<int> m_residual;
44  list<int> m_preselected;
45  list<int> m_clique;
48 
49 
50 
51 
52  public:
53  inline void addEdge(const int u,
54  const int v){
55  //---
56  //--- add an edge to the original graph
57  //--- NOTE: qualex will set edge u-v and v-u
58  //---
59  m_graphOrig->add_edge(u,v);
60  }
61 
62  inline void removeEdge(const int u,
63  const int v){
64  //---
65  //--- remove an edge to the original graph
66  //---
67  m_graphOrig->remove_edge(u,v);
68  }
69 
70  void removeNonNegVertices(const double * weights){
71  //---
72  //--- "remove" vertices with non-negative weights
73  //--- since the algorithm will look for cliques, we can
74  //--- just remove all the edges incident to the vertex
75  //--- therefore, it can't be selected as part of a clique
76  //---
77  int i, j;
78  for(i = 0; i < m_graph->n; i++){
79  if(weights[i] >= 0){
80  //printf("\nZERO OUT i: %d, weight: %g", i, weights[i]);
81 
82  vector<bool_vector>::iterator bi = m_graph->mates.begin() + i;
83  for(j = 0; j < m_graph->n; j++){
84  if(bi->at(j)){
85  m_graph->remove_edge(i,j);
86  }
87  }
88  //m_graph->mates[i].zero();
89  }
90  }
91  }
92 
93  void setUpForSolve(const double * vertexWeight){
94 
95  //---
96  //--- cleanup old copies, if exist
97  //---
98  UTIL_DELPTR(m_graph);
99  UTIL_DELPTR(m_info);
100  m_residual.clear();
101  m_preselected.clear();
102  m_clique.clear();
103  m_cliqueWeight = 0.0;
104 
105  //---
106  //--- allocate new graph
107  //---
108  m_graph = new Graph(m_graphOrig->n);
109  CoinAssertHint(m_graph, "Error: Out of Memory");
110 
111  //---
112  //--- copy orig graph adjMatrix into active graph
113  //--- NOTE: this is neccessary because preprocessor
114  //--- can change the structure of active graph
115  //---
116  u_long * dataSrc = NULL;
117  u_long * dataDst = NULL;
118  unsigned int i;
119  int dataSize = 0;
120  for(i = 0; i < m_graphOrig->mates.size(); i++){
121  dataSrc = m_graphOrig->mates[i].data;
122  dataDst = m_graph->mates[i].data;
123  dataSize = m_graph->mates[i].data_size;
124  memcpy(dataDst, dataSrc, dataSize * sizeof(u_long));
125  }
126 
127  //---
128  //--- copy vertex weights
129  //---
130  copy(vertexWeight,
131  vertexWeight + m_graph->n,
132  m_graph->weights.begin());
133  }
134 
135  void findMaxIndSetGreedy(const double * vertexWeight,
136  bool forClique = true){
137 
138  //printf("==== START findMaxIndSetGreedy\n");
139  //fflush(stdout);
140 
141  //---
142  //--- setup
143  //---
144  //setUpForSolve(vertexWeight);
145 
146  //---
147  //--- preprocess the current graph
148  //---
149 #if 0
150  //bug in preproc_clique?
151  m_preselected_weight = preproc_clique(*m_graph,
152  m_residual,
153  m_preselected,
154  m_cliqueWeight,
155  m_clique);
156 #else
157  int i;
158  m_residual.resize(m_graph->n);
159  for(i = 0; i < m_graph->n; i++)
160  m_residual[i] = i;
161 #endif
162 
163 #if 0
164  printf("\npreselected = %d", m_preselected.size());
165  printf("\nresidual size = %d", m_residual.size());
166  UtilPrintVector<int>(m_residual);
167 #endif
168 
169  if(!m_residual.empty()){
170  //---
171  //--- setup MaxCliqueInfo object
172  //---
173  m_info = new MaxCliqueInfo(*m_graph, forClique);
174  CoinAssertHint(m_info, "Error: Out of Memory");
175 
176  //---
177  //--- call greedy heuristic
178  //---
179  meta_greedy_clique(*m_info);
180 
181  //---
182  //--- if greedy improved upon ?, save the clique
183  //---
184  list<int>::iterator it;
185  if(m_info->lower_clique_bound > m_cliqueWeight) {
186  m_cliqueWeight = m_info->lower_clique_bound;
187  m_clique.erase(m_clique.begin(), m_clique.end());
188  for(it = m_info->clique.begin(); it != m_info->clique.end(); it++)
189  m_clique.push_back(m_residual[*it]);
190  }
191  }
192 
193  //---
194  //--- join preselected vertices to maximum clique
195  //---
196  m_clique.splice(m_clique.begin(), m_preselected);
197  m_cliqueWeight += m_preselected_weight;
198 
199 #if 0
200  printf("\npreselected = %d", m_preselected.size());
201  printf("\nresidual size = %d", m_residual.size());
202  printf("\nm_clique size = %d, wt = %g",
203  m_clique.size(), m_cliqueWeight);
204  UtilPrintVector<int>(m_residual);
205  UtilPrintList<int>(m_clique);
206 #endif
207 
208  //printf("\n==== END findMaxIndSetGreedy\n");
209  //fflush(stdout);
210  }
211 
213 
214  if(!m_residual.empty()){
215  printf("==== START findMaxIndSetQualexMS\n");
216  fflush(stdout);
217 
218  //this should not be called before Greedy
219  int i,j;
220  int n = m_graph->n;
221  double * sqrtw = m_info->sqrtw;
222 
223  memset(m_ijMatrix, 0, sizeof(double) * n * n);
224  for(i = 0; i < n; i++) {
225  m_ijMatrix[i*(n+1)] = m_graph->weights[i] - m_info->w_min;
226  bit_iterator bi(m_graph->mates[i]);
227  while((j = bi.next()) > -1) {
228  if(j > i)
229  break;
230  m_ijMatrix[i*n+j] = m_ijMatrix[j*n+i] = sqrtw[i] * sqrtw[j];
231  }
232  }
233  qualex_ms(*m_info, m_ijMatrix);
234 
235  //---
236  //--- if qualex improved upon greedy, save the clique
237  //---
238  list<int>::iterator it;
239  if(m_info->lower_clique_bound > m_cliqueWeight) {
240  m_cliqueWeight = m_info->lower_clique_bound;
241  m_clique.erase(m_clique.begin(), m_clique.end());
242  for(it = m_info->clique.begin(); it != m_info->clique.end(); it++)
243  m_clique.push_back(m_residual[*it]);
244  }
245 
246  //---
247  //--- join preselected vertices to maximum clique
248  //---
249  m_clique.splice(m_clique.begin(), m_preselected);
250  m_cliqueWeight += m_preselected_weight;
251 
252 #if 0
253  printf("\npreselected = %d", m_preselected.size());
254  printf("\nresidual size = %d", m_residual.size());
255  printf("\nm_clique size = %d, wt = %g",
256  m_clique.size(), m_cliqueWeight);
257  UtilPrintVector<int>(m_residual);
258  UtilPrintList<int>(m_clique);
259 #endif
260 
261  printf("==== END findMaxIndSetQualexMS\n");
262  fflush(stdout);
263  }
264  }
265 
266 
267  void printGraph(Graph * G){
268  int i, j;
269  int n = G->n;
270  vector<bool_vector> & mates = G->mates;
271  for(i = 0; i < n; i ++){
272  printf("%2d -> ", i);
273  bool_vector & matesI = mates[i];
274  assert(matesI.size == n);
275  for(j = 0; j < matesI.size; j++){
276  if(matesI.at(j))
277  printf(" %d", j);
278  }
279  printf("\n");
280  }
281  }
282 
283 
284  public:
285  MAD_Qualex(const int nVertices) :
286  m_info (NULL),
287  m_graph (NULL),
288  m_graphOrig (NULL),
289  m_ijMatrix (NULL),
290  m_residual (),
291  m_preselected (),
292  m_clique (),
293  m_preselected_weight(0.0),
294  m_cliqueWeight (0.0)
295 
296  {
297  CoinAssert(nVertices > 0);
298 
299  m_ijMatrix = new double[nVertices * nVertices];
300  CoinAssertHint(m_ijMatrix, "Error: Out of Memory");
301 
302  m_graphOrig = new Graph(nVertices);
303  CoinAssertHint(m_graphOrig, "Error: Out of Memory");
304  }
306  UTIL_DELPTR(m_info);
307  UTIL_DELPTR(m_graph);
308  UTIL_DELPTR(m_graphOrig);
309  UTIL_DELARR(m_ijMatrix);
310  }
311 };
312 
313 
314 #endif
list< int > m_preselected
Definition: MAD_Qualex.h:44
void printGraph(Graph *G)
Definition: MAD_Qualex.h:267
MAD_Qualex(const int nVertices)
Definition: MAD_Qualex.h:285
Graph * m_graph
Definition: MAD_Qualex.h:39
adjacency_list< vecS, vecS, undirectedS, no_property, edge_prop > Graph
Definition: TSP_Boost.h:36
double m_cliqueWeight
Definition: MAD_Qualex.h:47
#define UTIL_DELARR(x)
Definition: UtilMacros.h:29
Graph * m_graphOrig
Definition: MAD_Qualex.h:40
vector< int > m_residual
Definition: MAD_Qualex.h:43
#define CoinAssertHint(expression, hint)
Definition: CoinError.hpp:184
void findMaxIndSetGreedy(const double *vertexWeight, bool forClique=true)
Definition: MAD_Qualex.h:135
double * m_ijMatrix
Definition: MAD_Qualex.h:41
list< int > m_clique
Definition: MAD_Qualex.h:45
void findMaxIndSetQualexMS()
Definition: MAD_Qualex.h:212
#define UTIL_DELPTR(x)
Definition: UtilMacros.h:28
void addEdge(const int u, const int v)
Definition: MAD_Qualex.h:53
void removeEdge(const int u, const int v)
Definition: MAD_Qualex.h:62
#define CoinAssert(expression)
Definition: CoinError.hpp:183
MaxCliqueInfo * m_info
Definition: MAD_Qualex.h:38
double m_preselected_weight
Definition: MAD_Qualex.h:46
void removeNonNegVertices(const double *weights)
Definition: MAD_Qualex.h:70
void setUpForSolve(const double *vertexWeight)
Definition: MAD_Qualex.h:93