1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//! Parse MPS format
//!
//! ```no_run
//! # fn main() -> anyhow::Result<()> {
//! let instance: ommx::Instance = ommx::mps::load("data/directory/data.mps.gz")?;
//! # Ok(()) }
//! ```
//!
//! Differences from the original format
//! -------------------------------------
//! MPS format is very old format, and there are some differences between the original format and the actual data.
//! Some modification has been made to load the benchmark dataset in MIPLIB:
//!
//! - The original format is fixed format, but we parse it as space-separated format.
//! - `LI` as lower (negative) integer and `UI` as upper (positive) integer in `BOUNDS` section
//! - `PL` is treated as `FR` in the `BOUNDS` section.
//!
//! Original fixed format
//! ----------------------
//! ```text
//! │1 │2(5─12) ││3(15─22)││4(25─36) │││5(40─47)││6(50─61) │
//! ├──┼────────┼┼────────┼┼────────────┼┼┼────────┼┼────────────┤
//! NAME TESTPROB < MPS file starts
//! ROWS────────┬┬────────┬┬────────────┬┬┬────────┬┬────────────┤
//! │N │COST ││ ││ │││ ││ │
//! │L │LIM1 ││ ││ │││ ││ │
//! │G │LIM2 ││ ││ │││ ││ │
//! │E │MYEQN ││ ││ │││ ││ │
//! COLUMNS─────┼┼────────┼┼────────────┼┼┼────────┼┼────────────┤
//! │ │XONE ││COST ││ 1│││LIM1 ││ 1│
//! │ │XONE ││LIM2 ││ 1│││ ││ │
//! │ │YTWO ││COST ││ 4│││LIM1 ││ 1│
//! │ │YTWO ││MYEQN ││ ─1│││ ││ │
//! │ │ZTHREE ││COST ││ 9│││LIM2 ││ 1│
//! │ │ZTHREE ││MYEQN ││ 1│││ ││ │
//! RHS─────────┼┼────────┼┼────────────┼┼┼────────┼┼────────────┤
//! │ │RHS1 ││LIM1 ││ 5│││LIM2 ││ 10│
//! │ │RHS1 ││MYEQN ││ 7│││ ││ │
//! BOUNDS──────┼┼────────┼┼────────────┼┼┼────────┼┼────────────┤
//! │UP│BND1 ││XONE ││ 4│││ ││ │
//! │LO│BND1 ││YTWO ││ ─1│││ ││ │
//! │UP│BND1 ││YTWO ││ 1│││ ││ │
//! ENDATA──────┴┴────────┴┴────────────┴┴┴────────┴┴────────────┘
//! ```
//!
//! Links
//! ------
//! - <https://plato.asu.edu/ftp/mps_format.txt>
//! - [MPS (format) -- Wikipedia](https://en.wikipedia.org/wiki/MPS_(format))
//! - [CPLEX](https://www.ibm.com/docs/en/icos/22.1.1?topic=extensions-integer-variables-in-mps-files)
//! - [GUROBI](https://docs.gurobi.com/projects/optimizer/en/current/reference/fileformats/modelformats.html#formatmps)
//!
pub use is_gzipped;
pub use ;
use *;
use ;
/// Reads and parses the MPS file from the given [`Read`] source with automatic gzipped detection.
/// Reads and parses the file at the given path. Gzipped files are automatically detected and decompressed.
//
// Note: the caller's path is intentionally not recorded as a span field to
// avoid leaking local directory structure through exported telemetry.
/// Writes out the instance as an MPS file to the specified path with compression control.
///
/// If `compress` is true, the output will be gzipped. If false, it will be written as plain text.
///
/// Limitation
/// ----------
/// Only linear problems are supported. See [`format()`] for detailed information about information loss,
/// removed constraints handling, and variable filtering behavior.
// Note: the caller's output path is intentionally not recorded as a span
// field to avoid leaking local directory structure through exported telemetry.