Skip to content

Commit

Permalink
pmedian returns a PMedianResult object rather than a Dict{String, Any}
Browse files Browse the repository at this point in the history
  • Loading branch information
jbytecode committed Apr 18, 2024
1 parent 1ec1c69 commit db053d2
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 24 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
### 0.1.8 (Upcoming release)

- pmedian now returns a PMedianResult object rather than a Dict{String, Any}.

### 0.1.7

Expand Down
5 changes: 3 additions & 2 deletions src/OperationsResearchModels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import .MaximumFlow: MaximumFlowResult
import .Assignment: AssignmentProblem, AssignmentResult
import .Game: game, GameResult
import .MinimumSpanningTree: hasloop, mst, MstResult
import .PMedian: pmedian, pmedian_with_distances
import .PMedian: pmedian, pmedian_with_distances, PMedianResult
import .CPM: cpm, CpmActivity, earliestfinishtime, longestactivity, CpmResult
import .CPM: pert, PertActivity, PertResult
import .Latex: latex
Expand All @@ -51,13 +51,14 @@ export ShortestPathProblem, MaximumFlowProblem
export AssignmentProblem, AssignmentResult
export game, GameResult
export hasloop, mst, MstResult
export pmedian, pmedian_with_distances
export pmedian, pmedian_with_distances, PMedianResult
export cpm, CpmActivity, earliestfinishtime, longestactivity, CpmResult
export pert, PertActivity, PertResult
export Simplex
export Utility
export latex


"""
solve(t)
Expand Down
65 changes: 48 additions & 17 deletions src/pmedian.jl
Original file line number Diff line number Diff line change
@@ -1,29 +1,57 @@
module PMedian

export pmedian
export pmedian_with_distances

using JuMP, HiGHS

"""
PMedianResult
# Fields
- `centers::Vector`: Indices of selected centers.
- `model::JuMP.Model`: JuMP model.
- `objective::Float64`: Objective value.
- `z::Matrix`: Binary matrix of assignments. If z[i, j] = 1 then ith point is connected to the jth point.
- `y::Vector`: Binary vector. If y[i] is 1 then ith point is a depot.
"""
struct PMedianResult
centers::Vector
model::JuMP.Model
objective::Float64
z::Matrix
y::Vector
end




function euclidean(u, v)::Float64
d = (u .- v)
return (d .* d) |> sum |> sqrt
end




"""
pmedian(data, ncenters)
# Arguments
- `data::Matrix`: Coordinates of locations
- `ncenters::Int`: Number of centers
# Descriptions
The function calculates Euclidean distances between all possible rows of the matrix data.
`ncenters` locations are then selected that minimizes the total distances to the nearest rows.
# Output
- `Dict{String, Any}`: The dictionary object that holds the results.
- `PMedianResult`: PMedianResult object.
# Example
Expand All @@ -36,17 +64,20 @@ julia> data3 = rand(10, 2) .+ 100;
julia> data = vcat(data1, data2, data3);
julia> result = pmedian(data, 3)
Dict{String, Any} with 5 entries:
"centers" => [6, 13, 25]
"model" => A JuMP Model…
"objective" => 10.5921
"z" => [-0.0 -0.0 … 0.0 0.0; -0.0 -0.0 … 0.0 0.0; … ; 0.0 0.0 … -0.0 0.0; 0.0 0.0 … 0.0 -0.0]
"y" => [0.0, -0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, -0.0, 0.0 … 0.0, 0.0, 0.0, -0.0, 1.0, 0.0, -0.0,…
julia> result = pmedian(data, 3);
julia> result.centers
3-element Vector{Int64}:
1
16
21
julia> result.objective
11.531012240599605
```
"""
function pmedian(data::Matrix, ncenters::Int)
function pmedian(data::Matrix, ncenters::Int)::PMedianResult

n, p = size(data)

Expand Down Expand Up @@ -77,9 +108,9 @@ end
`ncenters` locations are selected that minimizes the total distances to the nearest rows.
# Output
- `Dict{String, Any}`: The dictionary object that holds the results.
- `PMedianResult`: PMedianResult object.
"""
function pmedian_with_distances(distancematrix::Matrix, ncenters::Int)
function pmedian_with_distances(distancematrix::Matrix, ncenters::Int)::PMedianResult

n, _ = size(distancematrix)

Expand Down Expand Up @@ -108,12 +139,12 @@ function pmedian_with_distances(distancematrix::Matrix, ncenters::Int)

optimize!(model)

return Dict(
"z" => value.(z),
"y" => value.(y),
"centers" => findall(x -> x == 1, value.(y)),
"objective" => JuMP.objective_value(model),
"model" => model,
return PMedianResult(
findall(x -> x == 1, value.(y)),
model,
JuMP.objective_value(model),
value.(z),
value.(y),
)
end

Expand Down
10 changes: 5 additions & 5 deletions test/testpmedian.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
]

result = pmedian(coords, 2)
y = result["y"]
y = result.y

@test sort(result["centers"]) == [2, 6]
@test sort(result.centers) == [2, 6]

@test iszero(y[1])
@test isone(y[2])
Expand All @@ -30,8 +30,8 @@

result = pmedian_with_distances(distance_matrix, number_of_depots)

@test sort(result["centers"]) == [1, 2]
@test result["objective"] == 5.0
@test result["z"] [1 0 0 0; 0 1 0 0; 1 0 0 0; 1 0 0 0]
@test sort(result.centers) == [1, 2]
@test result.objective == 5.0
@test result.z [1 0 0 0; 0 1 0 0; 1 0 0 0; 1 0 0 0]
end
end

0 comments on commit db053d2

Please sign in to comment.