SCIP

    Solving Constraint Integer Programs

    heur_trivialnegation.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2026 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file heur_trivialnegation.c
    26 * @ingroup DEFPLUGINS_HEUR
    27 * @brief trivialnegation primal heuristic
    28 * @author Jakob Witzig
    29 */
    30
    31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    32
    34#include "scip/pub_heur.h"
    35#include "scip/pub_message.h"
    36#include "scip/pub_sol.h"
    37#include "scip/pub_var.h"
    38#include "scip/scip_heur.h"
    39#include "scip/scip_message.h"
    40#include "scip/scip_numerics.h"
    41#include "scip/scip_prob.h"
    42#include "scip/scip_sol.h"
    43#include "scip/scip_solve.h"
    45
    46
    47#define HEUR_NAME "trivialnegation"
    48#define HEUR_DESC "negate solution entries if an objective coefficient changes the sign, enters or leaves the objective."
    49#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_PROP
    50#define HEUR_PRIORITY 39990
    51#define HEUR_FREQ 0
    52#define HEUR_FREQOFS 0
    53#define HEUR_MAXDEPTH 0
    54#define HEUR_TIMING SCIP_HEURTIMING_BEFORENODE
    55#define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
    56
    57/*
    58 * Local methods
    59 */
    60
    61/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
    62static
    63SCIP_DECL_HEURCOPY(heurCopyTrivialnegation)
    64{ /*lint --e{715}*/
    65 assert(scip != NULL);
    66 assert(heur != NULL);
    67
    69
    70 /* call inclusion method of primal heuristic */
    72
    73 return SCIP_OKAY;
    74}
    75
    76
    77/** execution method of primal heuristic */
    78static
    79SCIP_DECL_HEUREXEC(heurExecTrivialnegation)
    80{ /*lint --e{715}*/
    81 SCIP_SOL* lastbestsol; /* best solution from last run */
    82 SCIP_SOL* allchanged; /* solution with all entries negated */
    83 SCIP_SOL* feasiblechanged; /* solution with all feasible entries negated */
    84 SCIP_SOL* singlenegatedsol; /* solution with exactly one negated entry */
    85 SCIP_VAR** vars;
    86 int nbinvars;
    87 int i;
    88
    89 SCIP_Real solval;
    90
    91 vars = SCIPgetVars(scip);
    92 nbinvars = SCIPgetNBinVars(scip);
    93
    94 *result = SCIP_DIDNOTRUN;
    95
    97 return SCIP_OKAY;
    98
    99 if( nbinvars < SCIPgetNVars(scip) )
    100 return SCIP_OKAY;
    101
    102 *result = SCIP_DIDNOTFIND;
    103
    104 /* get best solution from the run */
    105 lastbestsol = SCIPgetReoptLastOptSol(scip);
    106
    107 if( lastbestsol == NULL )
    108 return SCIP_OKAY;
    109
    110 /* initialize data structure */
    111 SCIP_CALL( SCIPcreateSol(scip, &allchanged, heur) );
    112 SCIP_CALL( SCIPcreateSol(scip, &feasiblechanged, heur) );
    113 SCIP_CALL( SCIPcreateSol(scip, &singlenegatedsol, heur) );
    114
    115 /* copy the solutions */
    116 for( i = 0; i < nbinvars; i++ )
    117 {
    118 solval = SCIPgetSolVal(scip, lastbestsol, vars[i]);
    119 SCIP_CALL( SCIPsetSolVal(scip, allchanged, vars[i], solval) );
    120 SCIP_CALL( SCIPsetSolVal(scip, feasiblechanged, vars[i], solval) );
    121 SCIP_CALL( SCIPsetSolVal(scip, singlenegatedsol, vars[i], solval) );
    122 }
    123
    124 assert(SCIPsolGetHeur(allchanged) == heur);
    125 assert(SCIPsolGetHeur(feasiblechanged) == heur);
    126 assert(SCIPsolGetHeur(singlenegatedsol) == heur);
    127
    128 /* change the entries */
    129 for( i = 0; i < nbinvars; i++ )
    130 {
    131 SCIP_VAR* transvar;
    132
    133 assert(SCIPvarIsActive(vars[i]));
    134
    135 transvar = vars[i];
    136
    137 if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_BINARY && !SCIPvarIsImpliedIntegral(vars[i]) )
    138 {
    139 SCIP_Real obj;
    140 SCIP_Real newcoef;
    141 SCIP_Real oldcoef;
    142 SCIP_Bool changed;
    143
    144 /* perform negation only on variables that are not globally fixed */
    145 if( SCIPvarGetLbGlobal(vars[i]) > 0.5 || SCIPvarGetUbGlobal(vars[i]) < 0.5 )
    146 continue;
    147
    149 SCIP_CALL( SCIPgetReoptOldObjCoef(scip, transvar, SCIPgetNReoptRuns(scip)-1, &newcoef) );
    150
    151 /* check if variable entered or left the objective, or if its objective coefficient changed sign */
    152 changed = FALSE;
    153 if( !SCIPisFeasEQ(scip, oldcoef, newcoef) )
    154 {
    155 changed = SCIPisZero(scip, oldcoef) != SCIPisZero(scip, newcoef);
    156 changed |= SCIPisPositive(scip, oldcoef) == SCIPisNegative(scip, newcoef); /*lint !e514*/
    157 }
    158
    159 SCIPdebugMsg(scip, "check variable <%s> which has %schanged from %g to %g\n", SCIPvarGetName(transvar), changed ? "" : "not ", oldcoef, newcoef);
    160
    161 if( changed )
    162 {
    163 SCIP_Bool success;
    164
    165 solval = SCIPgetSolVal(scip, lastbestsol, vars[i]);
    166
    167 /* change solution value */
    168 SCIP_CALL( SCIPsetSolVal(scip, allchanged, vars[i], 1 - solval) );
    169 SCIP_CALL( SCIPsetSolVal(scip, feasiblechanged, vars[i], 1 - solval) );
    170 SCIP_CALL( SCIPsetSolVal(scip, singlenegatedsol, vars[i], 1 - solval) );
    171
    172 /* try solution with all changes */
    173 success = FALSE;
    174 obj = SCIPgetSolTransObj(scip, allchanged);
    176 {
    177 SCIPdebugMsg(scip, "try solution with all negations\n");
    178#ifdef SCIP_DEBUG
    179 SCIP_CALL( SCIPtrySol(scip, allchanged, TRUE, FALSE, TRUE, FALSE, TRUE, &success) );
    180#else
    181 SCIP_CALL( SCIPtrySol(scip, allchanged, FALSE, FALSE, TRUE, FALSE, TRUE, &success) );
    182#endif
    183
    184 if( success )
    185 {
    186 SCIPdebugMsg(scip, "found feasible solution solution:\n");
    187 SCIPdebug( SCIP_CALL( SCIPprintSol(scip, allchanged, NULL, FALSE) ) );
    188
    189 *result = SCIP_FOUNDSOL;
    190 }
    191 }
    192
    193 /* try solution with feasible changes */
    194 success = FALSE;
    195 obj = SCIPgetSolTransObj(scip, feasiblechanged);
    197 {
    198 SCIPdebugMsg(scip, "try solution with feasible negations\n");
    199#ifdef SCIP_DEBUG
    200 SCIP_CALL( SCIPtrySol(scip, feasiblechanged, TRUE, FALSE, TRUE, FALSE, TRUE, &success) );
    201#else
    202 SCIP_CALL( SCIPtrySol(scip, feasiblechanged, FALSE, FALSE, TRUE, FALSE, TRUE, &success) );
    203#endif
    204 if( success )
    205 {
    206 SCIPdebugMsg(scip, "found feasible solution solution:\n");
    207 SCIPdebug( SCIP_CALL( SCIPprintSol(scip, feasiblechanged, NULL, FALSE) ) );
    208
    209 *result = SCIP_FOUNDSOL;
    210 }
    211 }
    212
    213 if( !success )
    214 {
    215 /* reset solution with feasible changes */
    216 SCIP_CALL( SCIPsetSolVal(scip, feasiblechanged, vars[i], solval) );
    217 }
    218
    219 /* try solution with exactly one changed value */
    220 obj = SCIPgetSolTransObj(scip, singlenegatedsol);
    222 {
    223 success = FALSE;
    224 SCIPdebugMsg(scip, "try solution with a single negation\n");
    225#ifdef SCIP_DEBUG
    226 SCIP_CALL( SCIPtrySol(scip, singlenegatedsol, TRUE, FALSE, TRUE, FALSE, TRUE, &success) );
    227#else
    228 SCIP_CALL( SCIPtrySol(scip, singlenegatedsol, FALSE, FALSE, TRUE, FALSE, TRUE, &success) );
    229#endif
    230 if( success )
    231 {
    232 SCIPdebugMsg(scip, "found feasible solution:\n");
    233 SCIPdebug( SCIP_CALL( SCIPprintSol(scip, singlenegatedsol, NULL, FALSE) ) );
    234
    235 *result = SCIP_FOUNDSOL;
    236 }
    237 }
    238
    239 /* reset solution with exactly one changed value */
    240 SCIP_CALL( SCIPsetSolVal(scip, singlenegatedsol, vars[i], solval) );
    241 }
    242 }
    243 }
    244
    245 /* free solutions */
    246 SCIP_CALL( SCIPfreeSol(scip, &allchanged) );
    247 SCIP_CALL( SCIPfreeSol(scip, &feasiblechanged) );
    248 SCIP_CALL( SCIPfreeSol(scip, &singlenegatedsol) );
    249
    250 return SCIP_OKAY;
    251}
    252
    253
    254/*
    255 * primal heuristic specific interface methods
    256 */
    257
    258/** creates the trivialnegation primal heuristic and includes it in SCIP */
    260 SCIP* scip /**< SCIP data structure */
    261 )
    262{
    263 SCIP_HEUR* heur;
    264
    265 /* include heuristic */
    268 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecTrivialnegation, NULL) );
    269
    270 assert(heur != NULL);
    271
    272 /* primal heuristic is safe to use in exact solving mode */
    273 SCIPheurMarkExact(heur);
    274
    275 /* set non fundamental callbacks via setter functions */
    276 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyTrivialnegation) );
    277
    278 return SCIP_OKAY;
    279}
    #define NULL
    Definition: def.h:257
    #define SCIP_Bool
    Definition: def.h:100
    #define SCIP_STRINGEQ(name, reference, retcode)
    Definition: def.h:454
    #define SCIP_Real
    Definition: def.h:165
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define SCIP_CALL(x)
    Definition: def.h:364
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    int SCIPgetNBinVars(SCIP *scip)
    Definition: scip_prob.c:2293
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_RETCODE SCIPincludeHeurTrivialnegation(SCIP *scip)
    SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
    Definition: scip_heur.c:167
    SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
    Definition: scip_heur.c:122
    void SCIPheurMarkExact(SCIP_HEUR *heur)
    Definition: heur.c:1457
    const char * SCIPheurGetName(SCIP_HEUR *heur)
    Definition: heur.c:1467
    SCIP_SOL * SCIPgetReoptLastOptSol(SCIP *scip)
    Definition: scip_solve.c:3261
    SCIP_RETCODE SCIPgetReoptOldObjCoef(SCIP *scip, SCIP_VAR *var, int run, SCIP_Real *objcoef)
    Definition: scip_solve.c:3288
    SCIP_Bool SCIPisReoptEnabled(SCIP *scip)
    Definition: scip_solve.c:3629
    SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
    Definition: scip_sol.c:514
    SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
    Definition: scip_sol.c:1250
    SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
    Definition: scip_sol.c:2351
    SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
    Definition: sol.c:4274
    SCIP_RETCODE SCIPtrySol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
    Definition: scip_sol.c:4017
    SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
    Definition: scip_sol.c:1569
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1763
    SCIP_Real SCIPgetSolTransObj(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:2003
    int SCIPgetNReoptRuns(SCIP *scip)
    SCIP_Real SCIPgetCutoffbound(SCIP *scip)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23674
    SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23530
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23485
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24174
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23299
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24152
    static SCIP_DECL_HEURCOPY(heurCopyTrivialnegation)
    #define HEUR_TIMING
    #define HEUR_FREQOFS
    #define HEUR_DESC
    #define HEUR_DISPCHAR
    #define HEUR_MAXDEPTH
    #define HEUR_PRIORITY
    #define HEUR_NAME
    static SCIP_DECL_HEUREXEC(heurExecTrivialnegation)
    #define HEUR_FREQ
    #define HEUR_USESSUBSCIP
    trivialnegation primal heuristic
    public methods for primal heuristics
    public methods for message output
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    public methods for primal CIP solutions
    public methods for problem variables
    public methods for primal heuristic plugins and divesets
    public methods for message handling
    public methods for numerical tolerances
    public methods for global and local (sub)problems
    public methods for solutions
    public solving methods
    public methods for querying solving statistics
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_FOUNDSOL
    Definition: type_result.h:56
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64