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