1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /*                                                                       */
3 /*    This file is part of the HiGHS linear optimization suite           */
4 /*                                                                       */
5 /*    Written and engineered 2008-2021 at the University of Edinburgh    */
6 /*                                                                       */
7 /*    Available as open-source under the MIT License                     */
8 /*                                                                       */
9 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
10 /**@file io/HMpsFF.h
11  * @brief
12  * @author Julian Hall, Ivet Galabova, Qi Huangfu and Michael Feldmeier
13  */
14 #ifndef IO_HMPSFF_H_
15 #define IO_HMPSFF_H_
16 
17 #include <algorithm>
18 #include <cassert>
19 #include <chrono>
20 #include <cmath>
21 #include <cstdio>
22 #include <cstring>
23 #include <fstream>
24 #include <iostream>
25 #include <iterator>
26 #include <limits>
27 #include <map>
28 #include <memory>
29 #include <tuple>
30 #include <unordered_map>
31 #include <utility>
32 #include <vector>
33 
34 #include "io/HighsIO.h"
35 #include "lp_data/HighsLp.h"  // for OBJSENSE_MINIMIZE and OBJSENSE_MAXIMIZE
36 #include "util/stringutil.h"
37 
38 using Triplet = std::tuple<int, int, double>;
39 
40 enum class FreeFormatParserReturnCode {
41   SUCCESS,
42   PARSERERROR,
43   FILENOTFOUND,
44   FIXED_FORMAT,
45   TIMEOUT,
46 };
47 
48 namespace free_format_parser {
49 
50 // private:
51 using wall_clock = std::chrono::high_resolution_clock;
52 using time_point = wall_clock::time_point;
53 
54 double getWallTime();
55 
56 class HMpsFF {
57  public:
HMpsFF()58   HMpsFF() {}
59   FreeFormatParserReturnCode loadProblem(FILE* logfile,
60                                          const std::string filename,
61                                          HighsLp& lp);
62 
63   double time_limit = HIGHS_CONST_INF;
64 
65  private:
66   double start_time;
67 
68   int numRow;
69   int numCol;
70   int nnz;
71   std::string mpsName;
72 
73   ObjSense objSense = ObjSense::MINIMIZE;  // Minimization by default
74   double objOffset = 0;
75 
76   std::vector<int> Astart;
77   std::vector<int> Aindex;
78   std::vector<double> Avalue;
79   std::vector<double> colCost;
80   std::vector<double> colLower;
81   std::vector<double> colUpper;
82   std::vector<double> rowLower;
83   std::vector<double> rowUpper;
84 
85   std::vector<std::string> rowNames;
86   std::vector<std::string> colNames;
87 
88   std::vector<HighsVarType> col_integrality;
89 
90   // Keep track of columns that are binary by default, being columns
91   // that are defined as integer by markers in the column section, or
92   // as binary by having a BV flag in the BOUNDS section, and without
93   // any LI or UI flags in the BOUNDS section
94   std::vector<bool> col_binary;
95 
96   /// load LP from MPS file as transposed triplet matrix
97   int parseFile(std::string filename);
98   int fillMatrix();
99 
100   const bool any_first_non_blank_as_star_implies_comment = false;
101   const bool handle_bv_in_bounds = false;
102 
103   enum class parsekey {
104     NAME,
105     OBJSENSE,
106     MAX,
107     MIN,
108     ROWS,
109     COLS,
110     RHS,
111     BOUNDS,
112     RANGES,
113     NONE,
114     END,
115     FAIL,
116     COMMENT,
117     FIXED_FORMAT,
118     TIMEOUT
119   };
120 
121   enum class boundtype { LE, EQ, GE, FR };
122   std::vector<boundtype> row_type;
123   std::vector<int> integer_column;
124 
125   std::vector<Triplet> entries;
126   std::vector<std::pair<int, double>> coeffobj;
127 
128   std::unordered_map<std::string, int> rowname2idx;
129   std::unordered_map<std::string, int> colname2idx;
130 
131   FreeFormatParserReturnCode parse(FILE* logfile, const std::string& filename);
132   /// checks first word of strline and wraps it by it_begin and it_end
133   HMpsFF::parsekey checkFirstWord(std::string& strline, int& start, int& end,
134                                   std::string& word) const;
135 
136   HMpsFF::parsekey parseDefault(std::ifstream& file);
137   HMpsFF::parsekey parseObjsense(FILE* logfile, std::ifstream& file);
138   HMpsFF::parsekey parseRows(FILE* logfile, std::ifstream& file);
139   HMpsFF::parsekey parseCols(FILE* logfile, std::ifstream& file);
140   HMpsFF::parsekey parseRhs(FILE* logfile, std::ifstream& file);
141   HMpsFF::parsekey parseRanges(FILE* logfile, std::ifstream& file);
142   HMpsFF::parsekey parseBounds(FILE* logfile, std::ifstream& file);
143 };
144 
145 }  // namespace free_format_parser
146 #endif /* IO_HMPSFF_H_ */
147