Google OR-Tools v9.12
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
glpk_formatters.cc
Go to the documentation of this file.
1// Copyright 2010-2025 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
15
16#include <cstddef>
17#include <sstream>
18#include <string>
19#include <string_view>
20
21#include "absl/strings/ascii.h"
22#include "absl/strings/str_cat.h"
24
25extern "C" {
26#include <glpk.h>
27}
28
29namespace operations_research {
30
31std::string SolutionStatusString(const int status) {
32 switch (status) {
33 case GLP_UNDEF:
34 return "undefined (UNDEF)";
35 case GLP_FEAS:
36 return "feasible (FEAS)";
37 case GLP_INFEAS:
38 return "infeasible (INFEAS)";
39 case GLP_NOFEAS:
40 return "no feasible solution (NOFEAS)";
41 case GLP_OPT:
42 return "optimal (OPT)";
43 case GLP_UNBND:
44 return "unbounded (UNBND)";
45 default:
46 return absl::StrCat("? (", status, ")");
47 }
48}
49
50std::string BasisStatusString(const int stat) {
51 switch (stat) {
52 case GLP_BS:
53 return "basic (BS)";
54 case GLP_NL:
55 return "lower bound (NL)";
56 case GLP_NU:
57 return "upper bound (NU)";
58 case GLP_NF:
59 return "unbounded (NF)";
60 case GLP_NS:
61 return "fixed (NS)";
62 default:
63 return absl::StrCat("? (", stat, ")");
64 }
65}
66
67std::string ReturnCodeString(const int rc) {
68 switch (rc) {
69 case GLP_EBADB:
70 return "[GLP_EBADB] invalid basis";
71 case GLP_ESING:
72 return "[GLP_ESING] singular matrix";
73 case GLP_ECOND:
74 return "[GLP_ECOND] ill-conditioned matrix";
75 case GLP_EBOUND:
76 return "[GLP_EBOUND] invalid bounds";
77 case GLP_EFAIL:
78 return "[GLP_EFAIL] solver failed";
79 case GLP_EOBJLL:
80 return "[GLP_EOBJLL] objective lower limit reached";
81 case GLP_EOBJUL:
82 return "[GLP_EOBJUL] objective upper limit reached";
83 case GLP_EITLIM:
84 return "[GLP_EITLIM] iteration limit exceeded";
85 case GLP_ETMLIM:
86 return "[GLP_ETMLIM] time limit exceeded";
87 case GLP_ENOPFS:
88 return "[GLP_ENOPFS] no primal feasible solution";
89 case GLP_ENODFS:
90 return "[GLP_ENODFS] no dual feasible solution";
91 case GLP_EROOT:
92 return "[GLP_EROOT] root LP optimum not provided";
93 case GLP_ESTOP:
94 return "[GLP_ESTOP] search terminated by application";
95 case GLP_EMIPGAP:
96 return "[GLP_EMIPGAP] relative mip gap tolerance reached";
97 case GLP_ENOFEAS:
98 return "[GLP_ENOFEAS] no primal/dual feasible solution";
99 case GLP_ENOCVG:
100 return "[GLP_ENOCVG] no convergence";
101 case GLP_EINSTAB:
102 return "[GLP_EINSTAB] numerical instability";
103 case GLP_EDATA:
104 return "[GLP_EDATA] invalid data";
105 case GLP_ERANGE:
106 return "[GLP_ERANGE] result out of range";
107 default:
108 return absl::StrCat("[?] unknown return code ", rc);
109 }
110}
111
112std::string TruncateAndQuoteGLPKName(const std::string_view original_name) {
113 std::ostringstream oss;
114 std::size_t current_size = 0;
115 for (const char c : original_name) {
116 // We use \ for escape sequences; thus we must escape it too.
117 if (c == '\\') {
118 if (current_size + 2 > kMaxGLPKNameLen) {
119 break;
120 }
121 oss << "\\\\";
122 current_size += 2;
123 continue;
124 }
125
126 // Simply insert non-control characters (that are not the escape character
127 // above).
128 if (!absl::ascii_iscntrl(c)) {
129 if (current_size + 1 > kMaxGLPKNameLen) {
130 break;
131 }
132 oss << c;
133 ++current_size;
134 continue;
135 }
136
137 // Escape control characters.
138 const std::string escaped_c =
139 absl::StrCat("\\x", absl::Hex(c, absl::kZeroPad2));
140 if (current_size + escaped_c.size() > kMaxGLPKNameLen) {
141 break;
142 }
143 oss << escaped_c;
144 current_size += escaped_c.size();
145 }
146
147 const std::string ret = oss.str();
148 DCHECK_EQ(ret.size(), current_size);
149
150 return ret;
151}
152
153} // namespace operations_research
In SWIG mode, we don't want anything besides these top-level includes.
std::string BasisStatusString(const int stat)
Formats a linear constraint or variable basis status (GLP_BS,...).
std::string TruncateAndQuoteGLPKName(const std::string_view original_name)
constexpr std::size_t kMaxGLPKNameLen
std::string ReturnCodeString(const int rc)
std::string SolutionStatusString(const int status)
Formats a solution status (GLP_OPT,...).