Scippy

GCG

Branch-and-Price & Column Generation for Everyone

clsvar_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 clsvar_gamssymbol.cpp
29  * @ingroup CLASSIFIERS
30  * @brief variables which have the same symbol are put into same class
31  * @author Stefanie Koß
32  */
33 
34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35 
36 #include "clsvar_gamssymbol.h"
37 #include "cons_decomp.h"
38 #include "cons_decomp.hpp"
39 #include <vector>
40 #include <stdio.h>
41 #include <sstream>
42 
43 #include "class_detprobdata.h"
44 
45 #include "class_varpartition.h"
46 #include "scip_misc.h"
47 
48 /* classifier properties */
49 #define DEC_CLASSIFIERNAME "gamssymbol" /**< name of classifier */
50 #define DEC_DESC "symbol in gams file" /**< short description of classification */
51 #define DEC_PRIORITY 0 /**< priority of this classifier */
52 
53 #define DEC_ENABLED TRUE
54 
55 
56 /*
57  * Data structures
58  */
59 
60 /** classifier handler data */
61 struct DEC_ClassifierData
62 {
63  std::map<std::string, int>* vartosymbol; /**< maps variable name to the corresponding symbol index */
64 };
65 
66 /*
67  * Local methods
68  */
69 
70 /* put your local methods here, and declare them static */
71 
72 
73 /*
74  * classifier callback methods
75  */
76 
77 /** destructor of classifier to free user data (called when GCG is exiting) */
78 static
80 {
81  assert(scip != NULL);
82 
83  DEC_CLASSIFIERDATA* classifierdata = DECvarClassifierGetData(classifier);
84  assert(classifierdata != NULL);
85  assert(strcmp(DECvarClassifierGetName(classifier), DEC_CLASSIFIERNAME) == 0);
86 
87  delete classifierdata->vartosymbol;
88 
89  SCIPfreeMemory(scip, &classifierdata);
90 
91  return SCIP_OKAY;
92 }
93 
94 static
95 DEC_DECL_VARCLASSIFY(classifierClassify)
96 {
97  gcg::DETPROBDATA* detprobdata;
98  if( transformed )
99  {
100  detprobdata = GCGconshdlrDecompGetDetprobdataPresolved(scip);
101  }
102  else
103  {
104  detprobdata = GCGconshdlrDecompGetDetprobdataOrig(scip);
105  }
106 
107  int nvar = detprobdata->getNVars();
108  std::vector<int> nvarsForClass( 0 ); // [i] holds number of variables for class i
109  std::vector<int> symbolidxForClass( 0 ); // [i] holds symbol index for class i
110  std::vector<int> classForVar( nvar, - 1 ); // [i] holds class index for variable i -> indexing over detection internal variable array!
111  int counterClasses = 0;
112 
114  assert(classifier != NULL);
115 
116  DEC_CLASSIFIERDATA* classdata = DECvarClassifierGetData(classifier);
117  assert(classdata != NULL);
118 
119  /* firstly, assign all variables to classindices */
120  // iterate over variables in detection and lookup in classdata->vartosymbol
121  // iterating over classdata->vartosymbol and lookup variables with getIndexForVar fails with assertion if variable is not found -> should return error value?
122  for( int varid = 0; varid < detprobdata->getNVars(); ++ varid )
123  {
124  SCIP_VAR* var = detprobdata->getVar(varid);
125  std::string varname = std::string( SCIPvarGetName( var ) );
126  auto symbolidxiter = classdata->vartosymbol->find(varname);
127  int symbolidx;
128  if( symbolidxiter != classdata->vartosymbol->end() )
129  {
130  symbolidx = symbolidxiter->second;
131  }
132  else
133  {
134  symbolidx = -1;
135  }
136 
137  bool classfound = false;
138 
139  /* check if class for symbol index exists */
140  for( size_t classid = 0; classid < symbolidxForClass.size(); ++classid )
141  {
142  if( symbolidx == symbolidxForClass[classid] )
143  {
144  classfound = true;
145  classForVar[varid] = classid;
146  ++nvarsForClass[classid];
147  break;
148  }
149  }
150 
151  /* if not, create a new class index */
152  if( !classfound )
153  {
154  classForVar[varid] = counterClasses;
155  ++counterClasses;
156  symbolidxForClass.push_back( symbolidx );
157  nvarsForClass.push_back( 1 );
158  }
159  }
160  assert( counterClasses == (int) symbolidxForClass.size() );
161 
162  /* secondly, use these information to create a ConsPartition */
163  gcg::VarPartition* partition = new gcg::VarPartition(scip, "gamssymbols", counterClasses, detprobdata->getNVars() );
164 
165  /* set class names and descriptions of every class */
166  for( int c = 0; c < partition->getNClasses(); ++ c )
167  {
168  std::stringstream text;
169  text << symbolidxForClass[c];
170  partition->setClassName( c, text.str().c_str() );
171  text.str( "" );
172  text.clear();
173  text << "This class contains all variables with gams symbol index" << symbolidxForClass[c] << ".";
174  partition->setClassDescription( c, text.str().c_str() );
175  }
176 
177  /* copy the constraint assignment information found in first step */
178  for( int i = 0; i < partition->getNVars(); ++ i )
179  {
180  partition->assignVarToClass( i, classForVar[i] );
181  }
182  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, " Varclassifier \"%s\" yields a classification with %d different variable classes \n", partition->getName(), partition->getNClasses() );
183 
184  detprobdata->addVarPartition(partition);
185  return SCIP_OKAY;
186 }
187 
188 /*
189  * classifier specific interface methods
190  */
191 
192 // SHOW
193 /** adds an entry to clsdata->vartosymbol */
195  DEC_VARCLASSIFIER* classifier,
196  SCIP_VAR* var,
197  int symbolIdx
198 )
199 {
200  assert(classifier != NULL);
201  DEC_CLASSIFIERDATA* classdata = DECvarClassifierGetData(classifier);
202  assert(classdata != NULL);
203 
204  std::string varname = SCIPvarGetName( var );
205  char varnametrans[SCIP_MAXSTRLEN];
206  (void) SCIPsnprintf(varnametrans, SCIP_MAXSTRLEN, "t_%s", varname.c_str());
207  std::string nametrans(varnametrans);
208  classdata->vartosymbol->insert({varname, symbolIdx});
209  classdata->vartosymbol->insert({varnametrans, symbolIdx});
210 
211  return SCIP_OKAY;
212 }
213 
214 /** creates the handler for gamssymbol classifier and includes it in SCIP */
216  SCIP* scip /**< SCIP data structure */
217 )
218 {
219  DEC_CLASSIFIERDATA* classifierdata = NULL;
220 
221  SCIP_CALL( SCIPallocMemory(scip, &classifierdata) );
222  assert(classifierdata != NULL);
223  classifierdata->vartosymbol = new std::map<std::string, int>();
224 
225  SCIP_CALL( DECincludeVarClassifier(scip, DEC_CLASSIFIERNAME, DEC_DESC, DEC_PRIORITY, DEC_ENABLED, classifierdata, classifierFree, classifierClassify) );
226 
227  return SCIP_OKAY;
228 }
class representing a partition of a set of variables
constraint handler for structure detection
static DEC_DECL_VARCLASSIFY(classifierClassify)
DETPROBDATA * GCGconshdlrDecompGetDetprobdataOrig(SCIP *scip)
help method to access detprobdata for unpresolved problem
SCIP_RETCODE DECincludeVarClassifier(SCIP *scip, const char *name, const char *description, int priority, SCIP_Bool enabled, DEC_CLASSIFIERDATA *classifierdata, DEC_DECL_FREEVARCLASSIFIER((*freeClassifier)),)
DEC_CLASSIFIERDATA * DECvarClassifierGetData(DEC_VARCLASSIFIER *classifier)
returns the data of the provided varclassifier
various SCIP helper methods
SCIP_RETCODE DECvarClassifierGamssymbolAddEntry(DEC_VARCLASSIFIER *classifier, SCIP_VAR *var, int symbolIdx)
#define 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)
int getNVars()
return the number of variables considered in the detprobdata
std::map< std::string, int > * vartosymbol
static DEC_DECL_FREEVARCLASSIFIER(classifierFree)
C++ interface of cons_decomp.
#define DEC_ENABLED
const char * DECvarClassifierGetName(DEC_VARCLASSIFIER *classifier)
returns the name of the provided classifier
SCIP_RETCODE SCIPincludeVarClassifierGamssymbol(SCIP *scip)
void addVarPartition(VarPartition *partition)
adds a variable partition if it is no duplicate of an existing variable partition
#define DEC_DESC
DETPROBDATA * GCGconshdlrDecompGetDetprobdataPresolved(SCIP *scip)
help method to access detprobdata for transformed problem
#define DEC_PRIORITY
variables which have the same symbol are put into same class
SCIP_VAR * getVar(int varIndex)
returns SCIP variable related to a variable index
#define DEC_CLASSIFIERNAME
DEC_VARCLASSIFIER * DECfindVarClassifier(SCIP *scip, const char *name)
searches for the varclassifier with the given name and returns it or NULL if classifier is not found
class storing partialdecs and the problem matrix