1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2 /* */ 3 /* This file is part of the program and library */ 4 /* SCIP --- Solving Constraint Integer Programs */ 5 /* */ 6 /* Copyright (c) 2002-2023 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 reader_sol.c 26 * @ingroup DEFPLUGINS_READER 27 * @brief file reader for primal solutions 28 * @author Tobias Achterberg 29 * @author Timo Berthold 30 * @author Marc Pfetsch 31 * 32 */ 33 34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/ 35 36 #include <ctype.h> 37 #include "scip/pub_fileio.h" 38 #include "scip/pub_message.h" 39 #include "scip/pub_misc.h" 40 #include "scip/pub_reader.h" 41 #include "scip/pub_sol.h" 42 #include "scip/reader_sol.h" 43 #include "scip/scip_general.h" 44 #include "scip/scip_message.h" 45 #include "scip/scip_param.h" 46 #include "scip/scip_reader.h" 47 #include "scip/scip_sol.h" 48 #include <string.h> 49 50 #define READER_NAME "solreader" 51 #define READER_DESC "file reader for primal solutions" 52 #define READER_EXTENSION "sol" 53 54 55 /* 56 * Local methods of reader 57 */ 58 59 /** reads a given SCIP solution file, problem has to be transformed in advance */ 60 static 61 SCIP_RETCODE readSol( 62 SCIP* scip, /**< SCIP data structure */ 63 const char* fname, /**< name of the input file */ 64 SCIP_Bool xml /**< true, iff the given file is XML */ 65 ) 66 { 67 SCIP_SOL* sol; 68 SCIP_Bool error; 69 SCIP_Bool partial; 70 SCIP_Bool stored; 71 SCIP_Bool usevartable; 72 73 assert(scip != NULL); 74 assert(fname != NULL); 75 76 SCIP_CALL( SCIPgetBoolParam(scip, "misc/usevartable", &usevartable) ); 77 78 if( !usevartable ) 79 { 80 SCIPerrorMessage("Cannot read solution file if vartable is disabled. Make sure parameter 'misc/usevartable' is set to TRUE.\n"); 81 return SCIP_READERROR; 82 } 83 84 /* create zero solution */ 85 SCIP_CALL( SCIPcreateSol(scip, &sol, NULL) ); 86 87 SCIP_CALL( SCIPreadSolFile(scip, fname, sol, xml, &partial, &error) ); 88 89 if( !error ) 90 { 91 /* add and free the solution */ 92 if( SCIPisTransformed(scip) ) 93 { 94 SCIP_Bool completely; 95 96 assert(!partial); 97 assert(!SCIPsolIsPartial(sol)); 98 99 /* use display/allviols to decide whether to print all violations or just the first one */ 100 SCIP_CALL( SCIPgetBoolParam(scip, "display/allviols", &completely) ); 101 102 SCIP_CALL( SCIPtrySolFree(scip, &sol, TRUE, completely, TRUE, TRUE, TRUE, &stored) ); 103 104 /* display result */ 105 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "primal solution from solution file <%s> was %s\n", 106 fname, stored ? "accepted" : "rejected - solution is infeasible or objective too poor"); 107 } 108 else 109 { 110 /* add primal solution to solution candidate storage, frees the solution afterwards */ 111 SCIP_CALL( SCIPaddSolFree(scip, &sol, &stored) ); 112 113 /* display result */ 114 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "%sprimal solution from solution file <%s> was %s\n", 115 partial ? "partial " : "", fname, stored ? "accepted as candidate, will be checked when solving starts" : "rejected - solution objective too poor"); 116 } 117 118 return SCIP_OKAY; 119 } 120 else 121 { 122 /* free solution */ 123 SCIP_CALL( SCIPfreeSol(scip, &sol) ); 124 125 return SCIP_READERROR; 126 } 127 } 128 129 /* 130 * Callback methods of reader 131 */ 132 133 /** copy method for reader plugins (called when SCIP copies plugins) */ 134 static 135 SCIP_DECL_READERCOPY(readerCopySol) 136 { /*lint --e{715}*/ 137 assert(scip != NULL); 138 assert(reader != NULL); 139 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0); 140 141 /* call inclusion method of reader */ 142 SCIP_CALL( SCIPincludeReaderSol(scip) ); 143 144 return SCIP_OKAY; 145 } 146 147 148 /** problem reading method of reader 149 * 150 * In order to determine the type of the file, we have to open it. Thus, it has to be opened 151 * twice. This might be removed, but is likely to not hurt the performance too much. 152 */ 153 static 154 SCIP_DECL_READERREAD(readerReadSol) 155 { /*lint --e{715}*/ 156 SCIP_FILE* file; 157 char buffer[SCIP_MAXSTRLEN]; 158 159 assert(reader != NULL); 160 assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0); 161 assert(result != NULL); 162 163 *result = SCIP_DIDNOTRUN; 164 165 if( SCIPgetStage(scip) < SCIP_STAGE_PROBLEM ) 166 { 167 SCIPerrorMessage("reading of solution file is only possible after a problem was created\n"); 168 return SCIP_READERROR; 169 } 170 171 if( SCIPgetStage(scip) == SCIP_STAGE_SOLVED ) 172 { 173 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, 174 "primal solution from solution file <%s> was ignored - problem is already solved to optimality\n", 175 filename); 176 *result = SCIP_SUCCESS; 177 return SCIP_OKAY; 178 } 179 180 /* open input file in order to determine type */ 181 file = SCIPfopen(filename, "r"); 182 if( file == NULL ) 183 { 184 SCIPerrorMessage("cannot open file <%s> for reading\n", filename); 185 SCIPprintSysError(filename); 186 return SCIP_NOFILE; 187 } 188 189 /* get next line */ 190 if( SCIPfgets(buffer, (int) sizeof(buffer), file) == NULL ) 191 { 192 SCIPerrorMessage("cannot parse file.\n"); 193 SCIPfclose(file); 194 return SCIP_READERROR; 195 } 196 /* close file */ 197 SCIPfclose(file); 198 199 /* decide whether it is xml */ 200 if( SCIPstrAtStart(buffer, "<?xml", (size_t) 5) ) 201 { 202 /* read XML solution and add it to the solution pool */ 203 SCIP_CALL( readSol(scip, filename, TRUE) ); 204 } 205 else 206 { 207 /* read the solution and add it to the solution pool */ 208 SCIP_CALL( readSol(scip, filename, FALSE) ); 209 } 210 211 *result = SCIP_SUCCESS; 212 213 return SCIP_OKAY; 214 } 215 216 217 /* 218 * sol file reader specific interface methods 219 */ 220 221 /** includes the sol file reader in SCIP */ 222 SCIP_RETCODE SCIPincludeReaderSol( 223 SCIP* scip /**< SCIP data structure */ 224 ) 225 { 226 SCIP_READER* reader; 227 228 /* include reader */ 229 SCIP_CALL( SCIPincludeReaderBasic(scip, &reader, READER_NAME, READER_DESC, READER_EXTENSION, NULL) ); 230 231 assert(reader != NULL); 232 233 /* set non fundamental callbacks via setter functions */ 234 SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopySol) ); 235 SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadSol) ); 236 237 return SCIP_OKAY; 238 } 239 240