SCIP-SDP  3.1.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
branch_sdpmostinf.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of SCIPSDP - a solving framework for mixed-integer */
4 /* semidefinite programs based on SCIP. */
5 /* */
6 /* Copyright (C) 2011-2013 Discrete Optimization, TU Darmstadt */
7 /* EDOM, FAU Erlangen-Nürnberg */
8 /* 2014-2018 Discrete Optimization, TU Darmstadt */
9 /* */
10 /* */
11 /* This program is free software; you can redistribute it and/or */
12 /* modify it under the terms of the GNU Lesser General Public License */
13 /* as published by the Free Software Foundation; either version 3 */
14 /* of the License, or (at your option) any later version. */
15 /* */
16 /* This program is distributed in the hope that it will be useful, */
17 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
19 /* GNU Lesser General Public License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with this program; if not, write to the Free Software */
23 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.*/
24 /* */
25 /* */
26 /* Based on SCIP - Solving Constraint Integer Programs */
27 /* Copyright (C) 2002-2018 Zuse Institute Berlin */
28 /* SCIP is distributed under the terms of the SCIP Academic Licence, */
29 /* see file COPYING in the SCIP distribution. */
30 /* */
31 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
32 
42 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
43 
44 /*#define SCIP_DEBUG*/
45 
46 #include <assert.h>
47 #include <string.h>
48 
49 #include "branch_sdpmostinf.h"
50 
51 /* turn off lint warnings for whole file: */
52 /*lint --e{788,818}*/
53 
54 #define BRANCHRULE_NAME "sdpmostinf"
55 #define BRANCHRULE_DESC "branch on the most infeasible variable of the SDP"
56 #define BRANCHRULE_PRIORITY 1000000
57 #define BRANCHRULE_MAXDEPTH -1
58 #define BRANCHRULE_MAXBOUNDDIST 1.0
59 
60 
61 /*
62  * Data structures
63  */
64 
65 /*
66  * Local methods
67  */
68 
69 /* put your local methods here, and declare them static */
70 
71 
72 /*
73  * Callback methods of branching rule
74  */
75 
77 static
78 SCIP_DECL_BRANCHCOPY(branchCopySdpmostinf)
79 { /*lint --e{715}*/
80  assert(scip != NULL);
81  assert(branchrule != NULL);
82  assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
83 
84  /* call inclusion method of branchrule */
85  SCIP_CALL( SCIPincludeBranchruleSdpmostinf(scip) );
86 
87  return SCIP_OKAY;
88 }
89 
91 static
92 SCIP_DECL_BRANCHEXECEXT(branchExecextSdpmostinf)
93 {/*lint --e{715}*/
94  int i;
95  int ncands;
96  SCIP_VAR** cands = NULL;
97  SCIP_Real* candssol; /* solution values of all candidates */
98  SCIP_Real* candsscore; /* scores of all candidates */
99  SCIP_Real currentfrac; /* fractionality of the current candidate */
100  SCIP_Real currentinf; /* infeasibility of the current candidate */
101  SCIP_Real mostinfinf; /* infeasibility of the current most infeasible variable */
102  SCIP_Real mostinfscore; /* score of the current most infeasible variable */
103  SCIP_Real mostinfobj; /* objective of the current most infeasible variable */
104  SCIP_Real mostinfval; /* value of the current most infeasible variable */
105  SCIP_VAR* mostinfvar = NULL; /* variable with the highest current infeasibility */
106 
107 
108  assert( scip != NULL );
109  assert( result != NULL );
110 
111  SCIPdebugMessage("Executing External Branching method of SDP-mostinf!\n");
112 
113  /* get the external candidates, as we use the score only as a tiebreaker, we aren't interested in the number of
114  * variables of different types with maximal score, so these return values are set to NULL */
115  SCIP_CALL( SCIPgetExternBranchCands(scip, &cands, &candssol, &candsscore, &ncands, NULL, NULL, NULL, NULL) );
116 
117  assert( ncands > 0 ); /* branchExecext should only be called if the list of external branching candidates is non-empty */
118 
119 #ifdef SCIP_DEBUG
120  SCIPdebugMessage("branching candidates for SDP-mostinf:\n");
121  for (i = 0; i < ncands; i++)
122  SCIPdebugMessage("%s, value = %f, score = %f\n", SCIPvarGetName(cands[i]), candssol[i], candsscore[i]);
123 #endif
124 
125  mostinfinf = -1.0;
126  mostinfscore = 0.0;
127  mostinfval = 0.0;
128  mostinfobj = -1.0;
129 
130  /* iterate over all solution candidates to find the one with the highest infeasibility */
131  for (i = 0; i < ncands; i++)
132  {
133  /* we skip all continuous variables, since we first want to branch on integral variables */
134  if ( SCIPvarGetType(cands[i]) == SCIP_VARTYPE_CONTINUOUS )
135  {
136  SCIPdebugMessage("skipping continuous variable %s\n", SCIPvarGetName(cands[i]));
137  continue;
138  }
139 
140  currentfrac = SCIPfeasFrac(scip, candssol[i]);
141  currentinf = (currentfrac <= 0.5) ? currentfrac : 1 - currentfrac;
142  /* a candidate is better than the current one if:
143  * - the infeasibility is (feastol-)bigger than before or
144  * - the infeasibility is (feastol-)equal and the score is (epsilon-)bigger or
145  * - the infeasibility and score are (feastol-/epsilon-)equal and the objective is (epsilon-)bigger than before
146  * - add three above are (feastol-/epsilon-)equal and the index is smaller */
147  if ( SCIPisFeasGT(scip, currentinf, mostinfinf) ||
148  (SCIPisFeasEQ(scip, currentinf, mostinfinf) && SCIPisGT(scip, candsscore[i], mostinfscore)) ||
149  (SCIPisFeasEQ(scip, currentinf, mostinfinf) && SCIPisEQ(scip, candsscore[i], mostinfscore) && SCIPisGT(scip, SCIPvarGetObj(cands[i]), mostinfobj)) ||
150  (SCIPisFeasEQ(scip, currentinf, mostinfinf) && SCIPisEQ(scip, candsscore[i], mostinfscore) && SCIPisEQ(scip, SCIPvarGetObj(cands[i]), mostinfobj) &&
151  SCIPvarGetIndex(cands[i]) < SCIPvarGetIndex(mostinfvar)) )
152  {
153  /* update the current best candidate */
154  mostinfinf = currentinf;
155  mostinfval = candssol[i];
156  mostinfobj = REALABS(SCIPvarGetObj(cands[i]));
157  mostinfscore = candsscore[i];
158  mostinfvar = cands[i];
159  }
160  }
161 
162  /* if all variables were continuous, we return DIDNOTRUN and let one of the SCIP branching rules decide */
163  if ( mostinfinf == -1.0 )
164  {
165  SCIPdebugMessage("Skipping SDP-mostinf branching rule since all branching variables are continuous\n");
166  *result = SCIP_DIDNOTFIND;
167  return SCIP_OKAY;
168  }
169 
170  assert( mostinfvar != NULL );
171  assert( SCIPisFeasGT(scip, mostinfinf, 0.0) ); /* otherwise all variables are fixed and there is nothing to branch */
172 
173  /* branch */
174  SCIPdebugMessage("branching on variable %s with value %f and score %f\n", SCIPvarGetName(mostinfvar), mostinfval, mostinfscore);
175  SCIP_CALL( SCIPbranchVarVal(scip, mostinfvar, mostinfval, NULL, NULL, NULL) );
176 
177  *result = SCIP_BRANCHED;
178 
179  return SCIP_OKAY;
180 }
181 
182 /*
183  * branching rule specific interface methods
184  */
185 
188  SCIP* scip
189  )
190 {
191  SCIP_BRANCHRULEDATA* branchruledata;
192  SCIP_BRANCHRULE* branchrule;
193 
194  /* create empty branching rule data */
195  branchruledata = NULL;
196 
197  branchrule = NULL;
198 
199  /* include branching rule */
200  SCIP_CALL( SCIPincludeBranchruleBasic(scip, &branchrule, BRANCHRULE_NAME, BRANCHRULE_DESC, BRANCHRULE_PRIORITY,
201  BRANCHRULE_MAXDEPTH, BRANCHRULE_MAXBOUNDDIST, branchruledata) );
202 
203  assert(branchrule != NULL);
204 
205  /* set non fundamental callbacks via setter functions */
206  SCIP_CALL( SCIPsetBranchruleCopy(scip, branchrule, branchCopySdpmostinf) );
207  SCIP_CALL( SCIPsetBranchruleExecExt(scip, branchrule, branchExecextSdpmostinf) );
208 
209  return SCIP_OKAY;
210 }
#define BRANCHRULE_MAXBOUNDDIST
SCIP_RETCODE SCIPincludeBranchruleSdpmostinf(SCIP *scip)
most infeasible branching rule for SCIP-SDP
#define BRANCHRULE_PRIORITY
static SCIP_DECL_BRANCHEXECEXT(branchExecextSdpmostinf)
#define BRANCHRULE_NAME
#define BRANCHRULE_MAXDEPTH
static SCIP_DECL_BRANCHCOPY(branchCopySdpmostinf)
#define BRANCHRULE_DESC