Dip  0.92.4
VRP_CVRPsep.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 VRP_CVRPSEP_INCLUDED
16 #define VRP_CVRPSEP_INCLUDED
17 
18 //---
19 //--- Interface class to CVRPSEP (separation routines for CVRP)
20 //--- Note: all CVRSEP arrays start counting from 1 (not 0)
21 //--- for n customers, consider n+1 the depot node
22 //---
23 
24 // --------------------------------------------------------------------- //
25 #include "cnstrmgr.h"
26 #include "capsep.h"
27 
28 // --------------------------------------------------------------------- //
29 #include "VRP_GSECCut.h"
30 #include "VRP_Instance.h"
31 
32 // --------------------------------------------------------------------- //
33 // --------------------------------------------------------------------- //
35 public:
36  int nEdges;
37  double * EdgeX;
38  int * EdgeTail;
39  int * EdgeHead;
40 
41 public:
43  nEdges (0),
44  EdgeX (0),
45  EdgeTail(0),
46  EdgeHead(0)
47  {};
48 
49  void clear(){
53  }
54 
55  void init(const int n){
56  nEdges = n;
57  if(nEdges > 0){
58  clear(); //TODO: doing this each time is inefficient
59  EdgeX = new double[nEdges+1];
60  EdgeTail = new int[nEdges+1];
61  EdgeHead = new int[nEdges+1];
62  CoinAssertHint(EdgeX && EdgeTail && EdgeHead, "Error: Out of Memory");
63  EdgeX[0] = 0.0;
64  EdgeTail[0] = 0;
65  EdgeHead[0] = 0;
66  }
67  }
68 
70  {
71  clear();
72  };
73 };
74 
75 
76 
77 // --------------------------------------------------------------------- //
78 // --------------------------------------------------------------------- //
79 class VRP_CVRPsep {
80 public:
81  const VRP_Instance * m_vrp; //ptr to vrp instance
82  CVRPsep_LPSol m_lpSol; //storage of current lp solution
83  CnstrMgrPointer m_newCuts; //my new CVRPsep cuts
84  CnstrMgrPointer m_oldCuts; //my old CVRPsep cuts
85 
86 
87 public:
88  VRP_CVRPsep(const int maxCuts = 500) :
89  m_vrp (0),
90  m_lpSol (),
91  m_newCuts (),
92  m_oldCuts ()
93  {
94  CMGR_CreateCMgr(&m_newCuts, maxCuts);
95  CMGR_CreateCMgr(&m_oldCuts, 10*maxCuts);
96  }
98  CMGR_FreeMemCMgr(&m_newCuts);
99  CMGR_FreeMemCMgr(&m_oldCuts);
100  }
101 
102 public:
103 
105  void init(const VRP_Instance * vrp) {
106  m_vrp = vrp;
107  //TODO: could alloc cuts here and send in param for size
108  }
109 
110 
111  void buildLpSol(const double * x,
112  const int nNzs,
113  const double etol = 1.0e-8){
114  int e;
115  int ind = 1;
116  int nEdges = m_vrp->m_graphLib.n_edges;
117  int nVerts = m_vrp->m_graphLib.n_vertices;
118 
119  //---
120  //--- free old memory, open new memory of size nszs
121  //--- TODO: would be more efficient if we did not
122  //--- do this every time - just create lpsol
123  //--- vecs of max size (nEdges) and don't
124  //--- bother clearing
125  //---
126  m_lpSol.init(nNzs);//allocates nNsz+1
127  for(e = 0; e < nEdges; e++){
128  if(x[e] > etol){
129  pair<int,int> uv = UtilBothEndsU(e);
130 
131  //---
132  //--- CVRPSEP convention:
133  //--- 1.) edgelist is 1 to NoOfEdges
134  //????????? nodes start from - so does ours...
135  //--- 2.) depot is numbered nCustomers+1=nVerts
136  //---
137  m_lpSol.EdgeX[ind] = x[e];
138  m_lpSol.EdgeTail[ind]
139  = uv.second == 0 ? nVerts : uv.second;
140  m_lpSol.EdgeHead[ind]
141  = uv.first == 0 ? nVerts : uv.first;
142 #if 0
143  printf("XLP[%d,%d -> %d,%d] = %g\n",
144  uv.first, uv.second,
145  m_lpSol.EdgeTail[ind],
146  m_lpSol.EdgeHead[ind], x[e]);
147  UTIL_DEBUG(m_appParam.Log, 5,
148  (*m_osLog) << "XLP[" << uv.first << "," << uv.second;
149  (*m_osLog) << " -> " << m_lpSol.EdgeTail[ind] << ",";
150  (*m_osLog) << m_lpSol.EdgeHead[ind] << "]";
151  (*m_osLog) << " = " << x[e] << endl;
152  );
153 #endif
154  assert(ind <= nNzs);
155  ind++;
156  }
157  }
158  }
159 
160 
161 
162  int sepCapacityCuts(const int maxCuts = 500){
163 
164  const UtilGraphLib & graphLib = m_vrp->m_graphLib;
165  const int nVerts = graphLib.n_vertices;
166  const int * demand = graphLib.vertex_wt;
167  const int capacity = graphLib.capacity;
168 
169  //---
170  //--- check to make sure m_newCuts is big enough for max size
171  //---
172  //CMGR_ExpandCMgr(m_newCuts, maxCuts);//??
173 
174  char IntegerAndFeasible;
175  double MaxViolation;
176 
177  m_newCuts->Size = 0; //need to do?
178  CAPSEP_SeparateCapCuts(nVerts - 1,
179  const_cast<int*>(demand),
180  capacity,
181  m_lpSol.nEdges,
183  m_lpSol.EdgeHead,
184  m_lpSol.EdgeX,
185  m_oldCuts,
186  maxCuts,
187  0.001, //EpsForIntegrality
188  &IntegerAndFeasible,
189  &MaxViolation,
190  m_newCuts);
191 #if 0
192  printf("Found %d capacity cuts. MaxViolation=%g\n",
193  m_newCuts->Size, MaxViolation);
194 #endif
195  return m_newCuts->Size;
196  }
197 
198 
199  void createVrpCuts(DecompCutList & newCuts, double infinity){
200  int i, j;
201  const UtilGraphLib & graphLib = m_vrp->m_graphLib;
202  const int nVerts = graphLib.n_vertices;
203  const int * demand = graphLib.vertex_wt;
204  const int capacity = graphLib.capacity;
205 
206 
207  for(i = 0; i < m_newCuts->Size; i++){
208  CnstrPointer CP = m_newCuts->CPL[i];
209 
210  switch(CP->CType){
211  case CMGR_CT_CAP:
212  {
213  dynamic_bitset<> inS(nVerts);
214  for(j = 1; j <= CP->IntListSize; j++){
215  if(CP->IntList[j] == nVerts)//depot
216  inS.set(0);
217  else
218  inS.set(CP->IntList[j]);
219  }
220  VRP_GSECCut * cut = new VRP_GSECCut(inS, demand, capacity,
221  infinity);
222  //cut->print();
223  //double lb = cut->getLowerBound();
224  double ub = cut->getUpperBound();
225  //printf("CUT lb=%g ub=%g\n", lb, ub);
226  //printf("CVRPSEP RHS=%g\n", CP->RHS);
227  assert(UtilIsZero(CP->RHS - ub));
228  newCuts.push_back(cut);
229  }
230  break;
231  default:
232  CoinAssert(0);
233  }
234  }
235 
236  //---
237  //--- move new cuts into old cut pool
238  //---
239  //--- NOTE: if the framework decides that some cut sould not
240  //--- be entered (exceeds max number per pass or something)
241  //--- then we don't really want this to go into old cuts yet
242  //---
243  for(i = 0; i < m_newCuts->Size; i++)
244  CMGR_MoveCnstr(m_newCuts, m_oldCuts, i, 0);
245  //cout << "After Move m_newCuts size = " << m_newCuts->Size << endl;
246  //cout << "After Move m_oldCuts size = " << m_oldCuts->Size << endl;
247  }
248 };
249 
250 #endif
void buildLpSol(const double *x, const int nNzs, const double etol=1.0e-8)
Definition: VRP_CVRPsep.h:111
std::list< DecompCut * > DecompCutList
Definition: Decomp.h:93
bool UtilIsZero(const double x, const double etol=1.0e-8)
Definition: UtilMacros.h:272
double getUpperBound() const
Definition: DecompCut.h:50
pair< int, int > UtilBothEndsU(const int index)
void init(const int n)
Definition: VRP_CVRPsep.h:55
void init(const VRP_Instance *vrp)
Definition: VRP_CVRPsep.h:105
#define UTIL_DELARR(x)
Definition: UtilMacros.h:29
VRP_CVRPsep(const int maxCuts=500)
Definition: VRP_CVRPsep.h:88
#define CoinAssertHint(expression, hint)
Definition: CoinError.hpp:184
int sepCapacityCuts(const int maxCuts=500)
Definition: VRP_CVRPsep.h:162
void clear()
Definition: VRP_CVRPsep.h:49
int * EdgeHead
Definition: VRP_CVRPsep.h:39
void createVrpCuts(DecompCutList &newCuts, double infinity)
Definition: VRP_CVRPsep.h:199
int * EdgeTail
Definition: VRP_CVRPsep.h:38
UtilGraphLib m_graphLib
Data for an instance from VRPLIB.
Definition: VRP_Instance.h:31
CVRPsep_LPSol m_lpSol
Definition: VRP_CVRPsep.h:82
CnstrMgrPointer m_oldCuts
Definition: VRP_CVRPsep.h:84
#define UTIL_DEBUG(param, level, x)
Definition: UtilMacros.h:34
double * EdgeX
Definition: VRP_CVRPsep.h:37
const VRP_Instance * m_vrp
Definition: VRP_CVRPsep.h:81
int * vertex_wt
Definition: UtilGraphLib.h:61
#define CoinAssert(expression)
Definition: CoinError.hpp:183
CnstrMgrPointer m_newCuts
Definition: VRP_CVRPsep.h:83