Skip to content

Commit

Permalink
add latex support for simplex iterations
Browse files Browse the repository at this point in the history
  • Loading branch information
jbytecode committed Nov 22, 2023
1 parent f0ccdf1 commit caea221
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 19 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
### 0.1.5 (Upcoming release)
### 0.1.6 (Upcoming release)

### 0.1.5

- Add objective value in Simplex iterations
- $\LaTeX$ support for outputting simplex iterations

### 0.1.4

Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "OperationsResearchModels"
uuid = "8042aa49-e599-49ec-a8f7-b5b80cc82a88"
authors = ["Mehmet Hakan Satman <mhsatman@gmail.com>"]
version = "0.1.4"
version = "0.1.5"

[deps]
HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b"
Expand Down
93 changes: 76 additions & 17 deletions src/simplex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export simplexiterations
export simplexpretty
export createsimplexproblem
export solve!
export latex


@enum OptimizationType begin
Expand Down Expand Up @@ -39,6 +40,7 @@ mutable struct SimplexProblem
biggestvalue::Float64
isinstandardform::Bool
converged::Bool
objective_value::Float64
end

function SimplexProblem()::SimplexProblem
Expand All @@ -56,6 +58,7 @@ function SimplexProblem()::SimplexProblem
-Inf64, # Biggest value for M - Method
false, # is it in standard form?
false, # Converged?
0.0, # Objective Value
)
end

Expand All @@ -74,13 +77,18 @@ function Base.copy(source::SimplexProblem)
s.surplusvariableindices = copy(source.surplusvariableindices)
s.varnames = copy(source.varnames)
s.z = copy(source.z)
s.objective_value = copy(source.objective_value)
return s
end

function Base.copy(source::OptimizationType)
return source
end

function numround(x)
return round(x, digits = 3)
end

function updatebiggestvalue(s::SimplexProblem)
ms = []

Expand Down Expand Up @@ -136,7 +144,7 @@ function sumproduct(io::IO, coefs::Vector, varnames::Vector)
@assert length(coefs) == length(varnames)
l = length(coefs)
for i in 1:l
print(io, round(coefs[i], digits = 3), varnames[i])
print(io, numround(coefs[i]), varnames[i])
if i < l
print(io, " + ")
end
Expand All @@ -147,6 +155,7 @@ function Base.show(io::IO, s::SimplexProblem)
n, p = size(s.lhs)
print(s.opttype, " -> ")
sumproduct(io, s.z, s.varnames)
print(" = ", numround(s.objective_value))
println(io)
println(io, "S.t:")
for i in 1:n
Expand All @@ -156,7 +165,7 @@ function Base.show(io::IO, s::SimplexProblem)
print(io, bis, ": ")
end
sumproduct(io, s.lhs[i, :], s.varnames)
println(io, " ", s.directions[i], " ", round(s.rhs[i], digits = 3))
println(io, " ", s.directions[i], " ", numround(s.rhs[i]))
end
if !isempty(s.slackvariableindices)
println(io, "Slack: ", s.slackvariableindices)
Expand Down Expand Up @@ -300,8 +309,10 @@ function mmethodcorrection(s::SimplexProblem)
if idx in s.artificialvariableindices
if s.opttype == Maximize
s.z .= s.z .+ M * s.lhs[i, :]
s.objective_value = s.objective_value - M * s.rhs[i]
else
s.z .= s.z .- M * s.lhs[i, :]
s.objective_value = s.objective_value + M * s.rhs[i]
end
end
end
Expand Down Expand Up @@ -330,6 +341,8 @@ function update!(s::SimplexProblem, enteringvarindex::Int, exitingvarindex::Int)
pp = s.z[enteringvarindex]
s.z = s.z .- pp * s.lhs[rowindex, :]

s.objective_value = s.objective_value + pp * s.rhs[rowindex]

s.basicvariableindex[rowindex] = enteringvarindex

return nothing
Expand Down Expand Up @@ -459,22 +472,68 @@ function simplexpretty(s::SimplexProblem; maxiter::Int = 1000)::Nothing
end

function createsimplexproblem(
obj::Vector,
amat::Matrix,
rhs::Vector,
dir::Vector,
opttype::OptimizationType)::SimplexProblem
obj::Vector,
amat::Matrix,
rhs::Vector,
dir::Vector,
opttype::OptimizationType)::SimplexProblem

s = SimplexProblem()
setobjectivecoefs(s, obj)
setlhs(s, amat)
setrhs(s, rhs)
setdirections(s, dir)
setopttype(s, opttype)
setautomaticvarnames(s)

return s
end

s = SimplexProblem()
setobjectivecoefs(s, obj)
setlhs(s, amat)
setrhs(s, rhs)
setdirections(s, dir)
setopttype(s, opttype)
setautomaticvarnames(s)

return s
end
function formatruler(s::SimplexProblem)
formatter = "|c|"
L = length(s.varnames) + 1
for i in 1:L
formatter *= "c|"
end
return formatter
end

function tableheader(s::SimplexProblem)
return " & " * join(s.varnames, " & ") * " & Solution \\\\"
end

function tablerows(s::SimplexProblem)
trow = "z & " * join(-1.0 .* numround.(s.z), " & ") * " & " * string(numround(s.objective_value)) * "\\\\"
trow *= "\n \\hline"
n, _ = size(s.lhs)
for i in 1:n
c = s.lhs[i, :]
vname = s.varnames[s.basicvariableindex[i]]
trow *= "\n" * vname * " & " * join(numround.(c), " & ") * " & " * string(numround.(s.rhs[i])) * "\\\\"
trow *= "\n \\hline"
end
return trow
end

function latex(s::SimplexProblem)
formatter = formatruler(s)
header = tableheader(s)
trows = tablerows(s)
latex = """
\\begin{table}[H]
\\centering
\\begin{tabular}{$formatter}
\\hline
$header
\\hline
$trows
\\end{tabular}
\\label{}
\\caption{}
\\end{table}
"""
return latex
end

end # end of module Simplex
end # end of module Simplex
4 changes: 4 additions & 0 deletions test/testsimplex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ using OperationsResearchModels.Simplex
@test isapprox(s.rhs[1], 16.666666666666664, atol = eps)
@test isapprox(s.rhs[2], 66.66666666666667, atol = eps)

@test isapprox(s.objective_value, 183.33333, atol = eps)

end


Expand All @@ -40,6 +42,8 @@ using OperationsResearchModels.Simplex
@test isapprox(s.rhs[1], 0.3333333333, atol = eps)
@test isapprox(s.rhs[2], 1.3333333333, atol = eps)

@test isapprox(s.objective_value, 183.33333, atol = eps)

end

end # end of test set Simplex

2 comments on commit caea221

@jbytecode
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/95811

Tip: Release Notes

Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.

@JuliaRegistrator register

Release notes:

## Breaking changes

- blah

To add them here just re-invoke and the PR will be updated.

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.1.5 -m "<description of version>" caea22192cda556749bef6d00802aa6e6d42a5fb
git push origin v0.1.5

Please sign in to comment.