Skip to content

Commit c83e166

Browse files
Improve presolve (#85)
* kept rows/cols * add passes * unconstrained reductions lp * up doc
1 parent 90d6f20 commit c83e166

File tree

8 files changed

+260
-165
lines changed

8 files changed

+260
-165
lines changed

src/presolve/empty_rows.jl

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,7 @@
1-
function row_cnt!(Arows, row_cnt::Vector{Int})
2-
for k = 1:length(Arows)
3-
i = Arows[k]
4-
row_cnt[i] += 1
5-
end
6-
end
7-
8-
find_empty_rows(row_cnt::Vector{Int}) = findall(isequal(0), row_cnt)
9-
101
"""
11-
new_ncon = empty_rows!(Arows, lcon, ucon, ncon, row_cnt, empty_rows, Arows_s)
2+
new_ncon = empty_rows!(Arows, lcon, ucon, ncon, row_cnt, empty_rows)
123
134
Removes the empty rows of A, and the corresponding elements in lcon and ucon that are in `empty_rows`.
14-
`Arows_s` is a view of `Arows` sorted in ascending order.
155
`row_cnt` is a vector of the number of elements per row.
166
177
Returns the new number of constraints `new_ncon` and updates in-place `Arows`, `lcon`, `ucon`.
@@ -23,7 +13,6 @@ function empty_rows!(
2313
ncon,
2414
row_cnt::Vector{Int},
2515
empty_rows::Vector{Int},
26-
Arows_s,
2716
) where {T}
2817
new_ncon = 0
2918
for i = 1:ncon
@@ -38,13 +27,25 @@ function empty_rows!(
3827
resize!(lcon, new_ncon)
3928
resize!(ucon, new_ncon)
4029

41-
c_rm = 1
42-
nrm = length(empty_rows)
43-
for k = 1:length(Arows)
44-
while c_rm nrm && Arows_s[k] empty_rows[c_rm]
45-
c_rm += 1
30+
# assume Acols is sorted
31+
Annz = length(Arows)
32+
nempty = length(empty_rows)
33+
34+
for idxempty = 1:nempty
35+
currentiempty = empty_rows[idxempty]
36+
# index of the current singleton row that takes the number of
37+
# already removed variables into account:
38+
newcurrentiempty = currentiempty - idxempty + 1
39+
40+
# remove singleton rows in A rows
41+
Awritepos = 1
42+
k = 1
43+
while k <= Annz
44+
Ai = Arows[k]
45+
Arows[Awritepos] = (Ai < newcurrentiempty) ? Ai : Ai - 1
46+
Awritepos += 1
47+
k += 1
4648
end
47-
Arows_s[k] -= c_rm - 1
4849
end
4950
return new_ncon
5051
end

src/presolve/postsolve_utils.jl

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
function restore_ifix!(ifix, xrm, x, xout)
2-
# put x and xrm inside xout
3-
cfix, cx = 1, 1
4-
nfix = length(ifix)
5-
for i = 1:length(xout)
6-
if cfix <= nfix && i == ifix[cfix]
7-
xout[i] = xrm[cfix]
8-
cfix += 1
9-
else
10-
xout[i] = x[cx]
1+
function restore_ifix!(kept_cols, xps, x, xout)
2+
# put x and xps inside xout according to kept_cols
3+
nvar = length(xout)
4+
cx = 0
5+
for i=1:nvar
6+
if kept_cols[i]
117
cx += 1
8+
xout[i] = x[cx]
9+
else
10+
xout[i] = xps[i]
1211
end
1312
end
1413
end
@@ -25,24 +24,23 @@ function restore_y!(y::Vector{T}, yout::Vector{T}, kept_rows::Vector{Bool}, ncon
2524
end
2625
end
2726

28-
function restore_ilow_iupp!(ilow, iupp, ifix)
29-
c_fix = 1
30-
nfix = length(ifix)
31-
27+
function restore_ilow_iupp!(ilow, iupp, kept_cols)
28+
offset = 0
29+
nvar = length(kept_cols)
3230
nlow = length(ilow)
33-
for i = 1:nlow
34-
while c_fix nfix && ilow[i] ifix[c_fix]
35-
c_fix += 1
36-
end
37-
ilow[i] += c_fix - 1
38-
end
39-
40-
c_fix = 1
4131
nupp = length(iupp)
42-
for i = 1:nupp
43-
while c_fix nfix && iupp[i] ifix[c_fix]
44-
c_fix += 1
32+
c_low, c_upp = 1, 1
33+
for i = 1:nvar
34+
if kept_cols[i] == false
35+
offset += 1
36+
end
37+
if c_low nlow && ilow[c_low] + offset == i
38+
ilow[c_low] += 1
39+
c_low += 1
40+
end
41+
if c_upp nupp && iupp[c_upp] + offset == i
42+
iupp[c_upp] += 1
43+
c_upp += 1
4544
end
46-
iupp[i] += c_fix - 1
4745
end
4846
end

0 commit comments

Comments
 (0)