Scippy

GCG

Branch-and-Price & Column Generation for Everyone

clscons_gamssymbol.cpp
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program */
4 /* GCG --- Generic Column Generation */
5 /* a Dantzig-Wolfe decomposition based extension */
6 /* of the branch-cut-and-price framework */
7 /* SCIP --- Solving Constraint Integer Programs */
8 /* */
9 /* Copyright (C) 2010-2021 Operations Research, RWTH Aachen University */
10 /* Zuse Institute Berlin (ZIB) */
11 /* */
12 /* This program is free software; you can redistribute it and/or */
13 /* modify it under the terms of the GNU Lesser General Public License */
14 /* as published by the Free Software Foundation; either version 3 */
15 /* of the License, or (at your option) any later version. */
16 /* */
17 /* This program is distributed in the hope that it will be useful, */
18 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
19 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
20 /* GNU Lesser General Public License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with this program; if not, write to the Free Software */
24 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.*/
25 /* */
26 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
27 
28 /**@file clscons_gamssymbol.cpp
29  * @ingroup CLASSIFIERS
30  * @brief gamssymbol constraint classifier (classifies by corresponding GAMS symbol)
31  * @author Stefanie Koß
32  */
33 
34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35 #define SCIP_DEBUG
36 
37 #include "clscons_gamssymbol.h"
38 #include "cons_decomp.h"
39 #include "cons_decomp.hpp"
40 #include <vector>
41 #include <string>
42 #include <map>
43 #include <stdio.h>
44 #include <sstream>
45 
46 #include "class_detprobdata.h"
47 
48 #include "class_conspartition.h"
49 #include "scip_misc.h"
50 
51 /* classifier properties */
52 #define DEC_CLASSIFIERNAME "gamssymbol" /**< name of classifier */
53 #define DEC_DESC "symbol in GAMS file" /**< short description of classification*/
54 #define DEC_PRIORITY 0
55 
56 #define DEC_ENABLED TRUE
57 
58 
59 /*
60  * Data structures
61  */
62 struct DEC_ClassifierData
63 {
64  std::map<std::string, int>* constosymbol; /**< maps constraint name to the corresponding symbol index */
65 };
66 
67 /*
68  * Local methods
69  */
70 
71 /* put your local methods here, and declare them static */
72 
73 
74 /*
75  * classifier callback methods
76  */
77 
78 /** destructor of classifier to free user data (called when GCG is exiting) */
79 static
81 {
82  DEC_CLASSIFIERDATA* classifierdata;
83 
84  assert(scip != NULL);
85 
86  classifierdata = DECconsClassifierGetData(classifier);
87  assert(classifierdata != NULL);
88  assert(strcmp(DECconsClassifierGetName(classifier), DEC_CLASSIFIERNAME) == 0);
89 
90  delete classifierdata->constosymbol;
91 
92  SCIPfreeMemory(scip, &classifierdata);
93 
94  return SCIP_OKAY;
95 }
96 
97 static
98 DEC_DECL_CONSCLASSIFY(classifierClassify) {
99  gcg::DETPROBDATA* detprobdata;
100  if( transformed )
101  {
102  detprobdata = GCGconshdlrDecompGetDetprobdataPresolved(scip);
103  }
104  else
105  {
106  detprobdata = GCGconshdlrDecompGetDetprobdataOrig(scip);
107  }
108 
109  int ncons = detprobdata->getNConss();
110  std::vector<int> nconssForClass( 0 ); // [i] holds number of constraints for class i
111  std::vector<int> symbolidxForClass( 0 ); // [i] holds symbol index for class i
112  std::vector<int> classForCons( ncons, - 1 ); // [i] holds class index for constraint i -> indexing over detection internal constraint array!
113  int counterClasses = 0;
114 
116  assert(classifier != NULL);
117 
118  DEC_CLASSIFIERDATA* classdata = DECconsClassifierGetData(classifier);
119  assert(classdata != NULL);
120 
121  /* firstly, assign all constraints to classindices */
122  // iterate over constraints in detection and lookup in classdata->constosymbol
123  // iterating over classdata->constosymbol and lookup constraints with getIndexForCons fails with assertion if constraint is not found -> should return error value?
124  for( int consid = 0; consid < detprobdata->getNConss(); ++ consid )
125  {
126  // int consid = detprobdata->getIndexForCons(iter.second);
127  SCIP_CONS* cons = detprobdata->getCons(consid);
128  std::string consname = std::string( SCIPconsGetName( cons ) );
129 
130  auto symbolidxiter = classdata->constosymbol->find(consname);
131  int symbolidx;
132  if( symbolidxiter != classdata->constosymbol->end() )
133  {
134  symbolidx = symbolidxiter->second;
135  }
136  else
137  {
138  symbolidx = -1;
139  }
140 
141  bool classfound = false;
142 
143  /* check if class for symbol index exists */
144  for( size_t classid = 0; classid < symbolidxForClass.size(); ++classid )
145  {
146  if( symbolidx == symbolidxForClass[classid] )
147  {
148  classfound = true;
149  classForCons[consid] = classid;
150  ++nconssForClass[classid];
151  break;
152  }
153  }
154 
155  /* if not, create a new class index */
156  if( !classfound )
157  {
158  classForCons[consid] = counterClasses;
159  ++counterClasses;
160  symbolidxForClass.push_back( symbolidx );
161  nconssForClass.push_back( 1 );
162  }
163  }
164  assert( counterClasses == (int) symbolidxForClass.size() );
165 
166  /* secondly, use these information to create a ConsPartition */
167  gcg::ConsPartition* partition = new gcg::ConsPartition(scip, "gamssymbols", counterClasses, detprobdata->getNConss() );
168 
169  /* set class names and descriptions of every class */
170  for( int c = 0; c < partition->getNClasses(); ++ c )
171  {
172  std::stringstream text;
173  text << symbolidxForClass[c];
174  partition->setClassName( c, text.str().c_str() );
175  text.str( "" );
176  text.clear();
177  text << "This class contains all constraints with gams symbol index" << symbolidxForClass[c] << ".";
178  partition->setClassDescription( c, text.str().c_str() );
179  }
180 
181  /* copy the constraint assignment information found in first step */
182  for( int i = 0; i < partition->getNConss(); ++ i )
183  {
184  partition->assignConsToClass( i, classForCons[i] );
185  }
186  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, " Consclassifier \"%s\" yields a classification with %d different constraint classes \n", partition->getName(), partition->getNClasses() );
187 
188  detprobdata->addConsPartition(partition);
189  return SCIP_OKAY;
190 }
191 
192 /*
193  * classifier specific interface methods
194  */
195 
196 /** adds an entry to clsdata->constosymbol */
198  DEC_CONSCLASSIFIER* classifier,
199  SCIP_CONS* cons,
200  int symbolIdx
201 )
202 {
203  assert(classifier != NULL);
204  DEC_CLASSIFIERDATA* classdata = DECconsClassifierGetData(classifier);
205  assert(classdata != NULL);
206 
207  std::string consname = SCIPconsGetName( cons );
208  classdata->constosymbol->insert({consname, symbolIdx});
209 
210  return SCIP_OKAY;
211 }
212 
213 /** creates the handler for gamssymbol classifier and includes it in SCIP */
215  SCIP* scip /**< SCIP data structure */
216 )
217 {
218  DEC_CLASSIFIERDATA* classifierdata = NULL;
219 
220  SCIP_CALL( SCIPallocMemory(scip, &classifierdata) );
221  assert(classifierdata != NULL);
222  classifierdata->constosymbol = new std::map<std::string, int>();
223 
224  SCIP_CALL( DECincludeConsClassifier(scip, DEC_CLASSIFIERNAME, DEC_DESC, DEC_PRIORITY, DEC_ENABLED, classifierdata, classifierFree, classifierClassify) );
225 
226  return SCIP_OKAY;
227 }
int getNConss()
returns the number of variables considered in the detprobdata
DEC_CONSCLASSIFIER * DECfindConsClassifier(SCIP *scip, const char *name)
searches for the consclassifier with the given name and returns it or NULL if classifier is not found
constraint handler for structure detection
#define DEC_PRIORITY
class representing a partition of a set of constraints
DETPROBDATA * GCGconshdlrDecompGetDetprobdataOrig(SCIP *scip)
help method to access detprobdata for unpresolved problem
DEC_CLASSIFIERDATA * DECconsClassifierGetData(DEC_CONSCLASSIFIER *classifier)
returns the data of the provided consclassifier
SCIP_RETCODE SCIPincludeConsClassifierGamssymbol(SCIP *scip)
#define DEC_DESC
Constraints which have the same symbol are put into same class.
various SCIP helper methods
static DEC_DECL_CONSCLASSIFY(classifierClassify)
#define classifierFree
std::map< std::string, int > * constosymbol
static DEC_DECL_FREECONSCLASSIFIER(classifierFree)
static SCIP_RETCODE partition(SCIP *scip, SCIP_VAR **J, int *Jsize, SCIP_Longint *priority, SCIP_VAR **F, int Fsize, SCIP_VAR **origvar, SCIP_Real *median)
SCIP_CONS * getCons(int consIndex)
returns the SCIP constraint related to a constraint index
#define DEC_ENABLED
SCIP_RETCODE DECconsClassifierGamssymbolAddEntry(DEC_CONSCLASSIFIER *classifier, SCIP_CONS *cons, int symbolIdx)
C++ interface of cons_decomp.
#define DEC_CLASSIFIERNAME
DETPROBDATA * GCGconshdlrDecompGetDetprobdataPresolved(SCIP *scip)
help method to access detprobdata for transformed problem
const char * DECconsClassifierGetName(DEC_CONSCLASSIFIER *classifier)
returns the name of the provided classifier
void addConsPartition(ConsPartition *partition)
adds a constraint partition if it is no duplicate of an existing constraint partition
SCIP_RETCODE DECincludeConsClassifier(SCIP *scip, const char *name, const char *description, int priority, SCIP_Bool enabled, DEC_CLASSIFIERDATA *classifierdata, DEC_DECL_FREECONSCLASSIFIER((*freeClassifier)),)
class storing partialdecs and the problem matrix