SCIP-SDP  2.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
branch_sdpmostfrac.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 programms based on SCIP. */
5 /* */
6 /* Copyright (C) 2011-2013 Discrete Optimization, TU Darmstadt */
7 /* EDOM, FAU Erlangen-Nürnberg */
8 /* 2014-2016 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-2016 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 
40 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
41 
42 /* #define SCIP_DEBUG */
43 
44 #include <assert.h>
45 #include <string.h>
46 
47 #include "branch_sdpmostfrac.h"
48 
49 /* turn off lint warnings for whole file: */
50 /*lint --e{788,818}*/
51 
52 #define BRANCHRULE_NAME "sdpmostfrac"
53 #define BRANCHRULE_DESC "branch on the most fractional variable of the SDP"
54 #define BRANCHRULE_PRIORITY 500000
55 #define BRANCHRULE_MAXDEPTH -1
56 #define BRANCHRULE_MAXBOUNDDIST 1.0
57 
58 
59 /*
60  * Data structures
61  */
62 
63 /*
64  * Local methods
65  */
66 
67 /* put your local methods here, and declare them static */
68 
69 
70 /*
71  * Callback methods of branching rule
72  */
73 
75 static
76 SCIP_DECL_BRANCHCOPY(branchCopySdpmostfrac)
77 { /*lint --e{715}*/
78  assert(scip != NULL);
79  assert(branchrule != NULL);
80  assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
81 
82  /* call inclusion method of branchrule */
83  SCIP_CALL( SCIPincludeBranchruleSdpmostfrac(scip) );
84 
85  return SCIP_OKAY;
86 }
87 
89 static
90 SCIP_DECL_BRANCHEXECEXT(branchExecextSdpmostfrac)
91 {/*lint --e{715}*/
92  int i;
93  int ncands;
94  SCIP_VAR** cands = NULL;
95  SCIP_Real* candssol; /* solution values of all candidates */
96  SCIP_Real* candsscore; /* scores of all candidates */
97  SCIP_Real mostfracfrac; /* fractionality of the current most fractional variable */
98  SCIP_Real mostfracscore; /* score of the current most fractional variable */
99  SCIP_Real mostfracobj; /* objective of the current most fractional variable */
100  SCIP_Real mostfracval; /* value of the current most fractional variable */
101  SCIP_VAR* mostfracvar = NULL; /* variable with the highest current fractionality */
102 
103 
104  assert( scip != NULL );
105  assert( result != NULL );
106 
107  SCIPdebugMessage("Executing External Branching method of SDP-mostfrac!\n");
108 
109  /* get the external candidates, as we use the score only as a tiebreaker, we aren't interested in the number of
110  * variables of different types with maximal score, so these return values are set to NULL */
111  SCIP_CALL( SCIPgetExternBranchCands(scip, &cands, &candssol, &candsscore, &ncands, NULL, NULL, NULL, NULL) );
112 
113  assert( ncands > 0 ); /* branchExecext should only be called if the list of extern branching candidate is non-empty */
114 
115 #ifdef SCIP_DEBUG
116  SCIPdebugMessage("branching candidates for SDP-mostfrac:\n");
117  for (i = 0; i < ncands; i++)
118  SCIPdebugMessage("%s, value = %f, score = %f\n", SCIPvarGetName(cands[i]), candssol[i], candsscore[i]);
119 #endif
120 
121  mostfracfrac = -1.0;
122  mostfracscore = 0.0;
123  mostfracval = 0.0;
124  mostfracobj = -1.0;
125 
126  /* iterate over all solution candidates to find the one with the highest fractionality */
127  for (i = 0; i < ncands; i++)
128  {
129  /* a candidate is better than the current one if:
130  * - the fractionality is (feastol-)bigger than before or
131  * - the fractionality is (feastol-)equal and the score is (epsilon-)bigger or
132  * - the fractionality and score are (feastol-/epsilon-)equal and the objective is (epsilon) bigger or
133  * - all three are (feastol-/epsilon-)bigger and the index is smaller */
134  if ( SCIPisFeasGT(scip, SCIPfeasFrac(scip, candssol[i]), mostfracfrac) ||
135  (SCIPisFeasEQ(scip, SCIPfeasFrac(scip, candssol[i]), mostfracfrac) && SCIPisGT(scip, candsscore[i], mostfracscore)) ||
136  (SCIPisFeasEQ(scip, SCIPfeasFrac(scip, candssol[i]), mostfracfrac) && SCIPisEQ(scip, candsscore[i], mostfracscore)
137  && SCIPisGT(scip, SCIPvarGetObj(cands[i]), mostfracobj)) ||
138  (SCIPisFeasEQ(scip, SCIPfeasFrac(scip, candssol[i]), mostfracfrac) && SCIPisEQ(scip, candsscore[i], mostfracscore)
139  && SCIPisEQ(scip, SCIPvarGetObj(cands[i]), mostfracobj) && SCIPvarGetIndex(cands[i]) < SCIPvarGetIndex(mostfracvar)) )
140  {
141  /* update the current best candidate */
142  mostfracfrac = SCIPfeasFrac(scip, candssol[i]);
143  mostfracscore = candsscore[i];
144  mostfracobj = REALABS(SCIPvarGetObj(cands[i]));
145  mostfracval = candssol[i];
146  mostfracvar = cands[i];
147  }
148  }
149 
150  assert( mostfracvar != NULL );
151  assert( SCIPisFeasGT(scip, mostfracfrac, 0.0) ); /* otherwise all variables are fixed and there is nothing to branch */
152 
153  /* branch */
154  SCIPdebugMessage("branching on variable %s with value %f and score %f\n", SCIPvarGetName(mostfracvar), mostfracval, mostfracscore);
155  SCIP_CALL( SCIPbranchVarVal(scip, mostfracvar, mostfracval, NULL, NULL, NULL) );
156 
157  *result = SCIP_BRANCHED;
158 
159  return SCIP_OKAY;
160 }
161 
162 /*
163  * branching rule specific interface methods
164  */
165 
168  SCIP* scip
169  )
170 {
171  SCIP_BRANCHRULEDATA* branchruledata;
172  SCIP_BRANCHRULE* branchrule;
173 
174  /* create empty branching rule data */
175  branchruledata = NULL;
176 
177  branchrule = NULL;
178 
179  /* include branching rule */
180  SCIP_CALL( SCIPincludeBranchruleBasic(scip, &branchrule, BRANCHRULE_NAME, BRANCHRULE_DESC, BRANCHRULE_PRIORITY,
181  BRANCHRULE_MAXDEPTH, BRANCHRULE_MAXBOUNDDIST, branchruledata) );
182 
183  assert(branchrule != NULL);
184 
185  /* set non fundamental callbacks via setter functions */
186  SCIP_CALL( SCIPsetBranchruleCopy(scip, branchrule, branchCopySdpmostfrac) );
187  SCIP_CALL( SCIPsetBranchruleExecExt(scip, branchrule, branchExecextSdpmostfrac) );
188 
189  return SCIP_OKAY;
190 }
#define BRANCHRULE_MAXBOUNDDIST
#define BRANCHRULE_DESC
most fractional branching rule for SCIP-SDP
SCIP_RETCODE SCIPincludeBranchruleSdpmostfrac(SCIP *scip)
#define BRANCHRULE_PRIORITY
#define BRANCHRULE_NAME
#define BRANCHRULE_MAXDEPTH
static SCIP_DECL_BRANCHCOPY(branchCopySdpmostfrac)
static SCIP_DECL_BRANCHEXECEXT(branchExecextSdpmostfrac)