Skip to content

Commit 3323615

Browse files
authored
[FileFormats] Fix free variables in LP writer (#1006)
1 parent 57fc52c commit 3323615

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

src/FileFormats/LP/LP.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,16 +209,26 @@ function Base.write(io::IO, model::Model)
209209
end
210210
end
211211
println(io, "Bounds")
212+
free_variables = Set(keys(variable_names))
212213
for S in SCALAR_SETS
213214
for index in MOI.get(
214215
model,
215216
MOI.ListOfConstraintIndices{MOI.SingleVariable, S}()
216217
)
218+
delete!(free_variables, MOI.VariableIndex(index.value))
217219
write_constraint(
218220
io, model, index, variable_names; write_name = false
219221
)
220222
end
221223
end
224+
for index in MOI.get(
225+
model, MOI.ListOfConstraintIndices{MOI.SingleVariable, MOI.ZeroOne}()
226+
)
227+
delete!(free_variables, MOI.VariableIndex(index.value))
228+
end
229+
for variable in sort(collect(free_variables), by = x -> x.value)
230+
println(io, variable_names[variable], " free")
231+
end
222232
for (S, str_S) in [(MOI.Integer, "General"), (MOI.ZeroOne, "Binary")]
223233
indices = MOI.get(
224234
model, MOI.ListOfConstraintIndices{MOI.SingleVariable, S}()

test/FileFormats/LP/LP.jl

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const LP_TEST_FILE = "test.lp"
3939
"x >= -1\n" *
4040
"y = 3\n" *
4141
"4 <= z <= 5\n" *
42+
"a free\n" *
4243
"General\n" *
4344
"y\n" *
4445
"Binary\n" *
@@ -69,6 +70,7 @@ const LP_TEST_FILE = "test.lp"
6970
"subject to\n" *
7071
"_$(starting_letter)c1: 1 _$(starting_letter)x >= -1\n" *
7172
"Bounds\n" *
73+
"_$(starting_letter)x free\n" *
7274
"End\n"
7375
end
7476
end
@@ -91,6 +93,7 @@ const LP_TEST_FILE = "test.lp"
9193
"subject to\n" *
9294
"c_d: 1 x_y >= -1\n" *
9395
"Bounds\n" *
96+
"x_y free\n" *
9497
"End\n"
9598
end
9699
end
@@ -112,6 +115,10 @@ const LP_TEST_FILE = "test.lp"
112115
"subject to\n" *
113116
"c1: 1 a_ + 1 a__1 + 1 a__2 + 1 a__3 >= -1\n" *
114117
"Bounds\n" *
118+
"a_ free\n" *
119+
"a__1 free\n" *
120+
"a__2 free\n" *
121+
"a__3 free\n" *
115122
"End\n"
116123
end
117124
@testset "Length sanitisation" begin
@@ -130,6 +137,7 @@ const LP_TEST_FILE = "test.lp"
130137
"obj: abc\n" *
131138
"subject to\n" *
132139
"Bounds\n" *
140+
"abc free\n" *
133141
"End\n"
134142
end
135143
@testset "Too long duplicate names after sanitization" begin
@@ -146,6 +154,8 @@ const LP_TEST_FILE = "test.lp"
146154
"subject to\n" *
147155
"c1: 1 abc + 1 abc_1 >= -1\n" *
148156
"Bounds\n" *
157+
"abc free\n" *
158+
"abc_1 free\n" *
149159
"End\n"
150160
end
151161
end
@@ -161,6 +171,29 @@ const LP_TEST_FILE = "test.lp"
161171
"obj: -1 + 2 x\n" *
162172
"subject to\n" *
163173
"Bounds\n" *
174+
"x free\n" *
175+
"End\n"
176+
end
177+
@testset "free variables" begin
178+
model = LP.Model()
179+
MOIU.loadfromstring!(model, """
180+
variables: x, y, z
181+
maxobjective: x
182+
c1: x in ZeroOne()
183+
c2: y in Integer()
184+
""")
185+
MOI.write_to_file(model, LP_TEST_FILE)
186+
@test read(LP_TEST_FILE, String) ==
187+
"maximize\n" *
188+
"obj: x\n" *
189+
"subject to\n" *
190+
"Bounds\n" *
191+
"y free\n" *
192+
"z free\n" *
193+
"General\n" *
194+
"y\n" *
195+
"Binary\n" *
196+
"x\n" *
164197
"End\n"
165198
end
166199
end

0 commit comments

Comments
 (0)