Skip to content

Commit

Permalink
Dual sol pool matrix is dynamic sparse (#272)
Browse files Browse the repository at this point in the history
  • Loading branch information
guimarqu authored Feb 28, 2020
1 parent e7c051c commit fd1ba2e
Show file tree
Hide file tree
Showing 8 changed files with 23 additions and 290 deletions.
3 changes: 1 addition & 2 deletions src/Algorithm/benders.jl
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,8 @@ function record_solutions!(
if insertion_status
push!(recorded_dual_solution_ids, dual_sol_id)
else
@warn string("dual sol already exists as ", dual_sol_id)
@warn string("dual sol already exists as ", getname(spform, dual_sol))
end

end
end

Expand Down
2 changes: 1 addition & 1 deletion src/Containers/Containers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export MembersMatrix

# To be deleted :
export ElemDict,
MembersVector, OldMembersMatrix
MembersVector

export getelements, getelement, rows, cols, columns, getrecords

Expand Down
80 changes: 0 additions & 80 deletions src/Containers/members.jl
Original file line number Diff line number Diff line change
Expand Up @@ -90,83 +90,3 @@ function Base.getindex(m::MembersMatrix, row_id, col_id)
# TODO : check number of rows & cols
return m.cols_major[row_id, col_id]
end

######## DELETE BELOW THIS LINE #########

struct OldMembersMatrix{I,K,J,L,T} <: AbstractMembersContainer
#matrix_csc::DynamicSparseArrays.MappedPackedCSC{}
#matrix_csr::DynamicSparseArrays.MappedPackedCSC{}
cols::MembersVector{I,K,MembersVector{J,L,T}} # to rm
rows::MembersVector{J,L,MembersVector{I,K,T}} # to rm
end

"""
OldMembersMatrix{T}(columns_elems::Dict{I,K}, rows_elems::Dict{J,L})
Construct a matrix that contains records of type `T`. Rows have indices of type
`J` and elements of type `L`, and columns have indices of type `I` and elements
of type `K`.
`OldMembersMatrix` supports julia set and get operations.
"""
function OldMembersMatrix{T}(
col_elems::Dict{I,K}, row_elems::Dict{J,L}
) where {I,K,J,L,T}
cols = MembersVector{MembersVector{J,L,T}}(col_elems)
rows = MembersVector{MembersVector{I,K,T}}(row_elems)
OldMembersMatrix{I,K,J,L,T}(cols, rows)
end

function OldMembersMatrix{T}(
col_elems::ElemDict{VC1}, row_elems::ElemDict{VC2}
) where {VC1,VC2,T}
return OldMembersMatrix{T}(col_elems.elements, row_elems.elements)
end

function _getrecordvector!(
vec::MembersVector{I,K,MembersVector{J,L,T}}, key::I, elems::Dict{J,L},
create = true
) where {I,K,J,L,T}
if !haskey(vec, key)
membersvec = MembersVector{T}(elems)
if create
vec[key] = membersvec
end
return membersvec
end
vec[key]
end

function Base.setindex!(m::OldMembersMatrix, val, row_id, col_id)
col = _getrecordvector!(m.cols, col_id, m.rows.elements)
col[row_id] = val
row = _getrecordvector!(m.rows, row_id, m.cols.elements)
row[col_id] = val
m
end

function Base.getindex(
m::OldMembersMatrix{I,K,J,L,T}, row_id::J, ::Colon
) where {I,K,J,L,T}
_getrecordvector!(m.rows, row_id, m.cols.elements, false)
end

function Base.getindex(
m::OldMembersMatrix{I,K,J,L,T}, ::Colon, col_id::I
) where {I,K,J,L,T}
_getrecordvector!(m.cols, col_id, m.rows.elements, false)
end

"""
columns(membersmatrix)
Return a `MembersVector` that contains the columns.
When the matrix stores the coefficients of a formulation, the method returns
a `MembersVector` that contains `Variable` as elements. For each
`Variable`, the record is the `MembersVector` that contains the coefficients of
the `Variable` in each `Constraint`.
"""
function columns(m::OldMembersMatrix)
return m.cols
end
43 changes: 15 additions & 28 deletions src/MathProg/formulation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -200,46 +200,33 @@ function setdualsol!(
new_dual_sol::DualSolution{S}
)::Tuple{Bool,ConstrId} where {S<:Coluna.AbstractSense}
### check if dualsol exists take place here along the coeff update

prev_dual_sols = getdualsolmatrix(form)

for (prev_dual_sol_id, prev_dual_sol) in columns(prev_dual_sols)
rhs = getdualsolrhss(form)[prev_dual_sol_id]
dual_sols = getdualsolmatrix(form)
dual_sol_rhss = getdualsolrhss(form)

for (cur_sol_id, cur_rhs) in dual_sol_rhss
factor = 1.0
if new_dual_sol.bound < rhs
factor = rhs / new_dual_sol.bound

else
if new_dual_sol.bound > rhs
factor = rhs / new_dual_sol.bound
end
if getbound(new_dual_sol) != cur_rhs
factor = cur_rhs / getbound(new_dual_sol)
end


# TODO : implement broadcasting for PMA in DynamicSparseArrays
is_identical = true
for (constr_id, constr_val) in getrecords(prev_dual_sol)
if new_dual_sol[constr_id] == 0
cur_dual_sol = dual_sols[cur_sol_id, :]
for (constr_id, constr_val) in cur_dual_sol
if factor * getsol(new_dual_sol)[constr_id] != constr_val
is_identical = false
break
end
end
if !is_identical
continue
end

for (constr_id, constr_val) in new_dual_sol
if prev_dual_sol[constr_id] == 0
is_identical = false
break
end

if prev_dual_sol[constr_id] != factor * constr_val
for (constr_id, constr_val) in getsol(new_dual_sol)
if factor * constr_val != cur_dual_sol[constr_id]
is_identical = false
break
end
end
if is_identical
return (false, prev_dual_sol_id)
end

is_identical && return (false, cur_sol_id)
end

### else not identical to any existing dual sol
Expand Down
10 changes: 4 additions & 6 deletions src/MathProg/manager.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ const ConstrDict = ElemDict{Id{Constraint}, Constraint}
const ConstrDataDict = Dict{Id{Constraint}, ConstrData}
const VarMembership = MembersVector{VarId,Variable,Float64}
const ConstrMembership = MembersVector{ConstrId,Constraint,Float64}

const ConstrConstrMatrix = MembersMatrix{ConstrId,ConstrId,Float64}
const ConstrVarMatrix = MembersMatrix{ConstrId,VarId,Float64}
const VarVarMatrix = MembersMatrix{VarId,VarId,Float64}

# Define the semaphore of the dynamic sparse matrix using MathProg.Id as index
DynamicSparseArrays.semaphore_key(::Type{I}) where {I <: Id} = zero(I)

const ConstrConstrMatrix = OldMembersMatrix{ConstrId,Constraint,ConstrId,Constraint,Float64}
const PrimalSolution{S} = Solution{Primal, S, Id{Variable}, Float64}
const DualSolution{S} = Solution{Dual, S, Id{Constraint}, Float64}
const PrimalBound{S} = Bound{Primal, S}
Expand All @@ -29,7 +28,7 @@ struct FormulationManager
primal_sols::VarVarMatrix # cols = primal solutions with varid, rows = variables
primal_sol_costs::DynSparseVector{VarId} # primal solutions with varid map to their cost
dual_sols::ConstrConstrMatrix # cols = dual solutions with constrid, rows = constrs
dual_sol_rhss::ConstrMembership # dual solutions with constrid map to their rhs
dual_sol_rhss::DynSparseVector{ConstrId} # dual solutions with constrid map to their rhs
end

function FormulationManager()
Expand All @@ -44,8 +43,8 @@ function FormulationManager()
VarVarMatrix(),
VarVarMatrix(),
dynamicsparsevec(VarId[], Float64[]),
OldMembersMatrix{Float64}(constrs,constrs),
MembersVector{Float64}(constrs)
ConstrConstrMatrix(),
dynamicsparsevec(ConstrId[], Float64[])
)
end

Expand All @@ -59,7 +58,6 @@ function _addvar!(m::FormulationManager, var::Variable)
return
end


function _addconstr!(m::FormulationManager, constr::Constraint)
haskey(m.constrs, constr.id) && error(string("Constraint of id ", constr.id, " exists"))
m.constrs[constr.id] = constr
Expand Down
118 changes: 0 additions & 118 deletions test/unit/containers/members.jl

This file was deleted.

4 changes: 2 additions & 2 deletions test/unit/unit_tests.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
include("containers/members.jl")
include("containers/nestedenum.jl")
include("containers/solsandbounds.jl")

Expand Down Expand Up @@ -43,7 +42,6 @@ function unit_tests()
nestedenum_unit()
bound_unit()
solution_unit()
members_unit()
end

@testset "MathProg submodule" begin
Expand All @@ -60,9 +58,11 @@ function unit_tests()
@testset "counters.jl" begin
counters_unit_tests()
end

@testset "vcids.jl" begin
vcids_unit_tests()
end

@testset "variable.jl" begin
variable_unit_tests()
end
Expand Down
Loading

0 comments on commit fd1ba2e

Please sign in to comment.