Skip to content

Commit 4129b21

Browse files
committed
implement least cost method for transportation problems
1 parent 40fa470 commit 4129b21

File tree

5 files changed

+87
-9
lines changed

5 files changed

+87
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
- Add new tests for CPM
44
- Feed an initial feasible solution (with North-West Corner Method) to a Transportation Problem. That makes it 10x faster
5+
- Implement least cost method for constructing a feasible initial solution to the transportation problems.
56

67

78
### 0.2.4

src/OperationsResearchModels.jl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,12 @@ import .TravelingSalesman
4242

4343

4444
import .Transportation:
45-
TransportationProblem, TransportationResult, balance, isbalanced, northwestcorner
45+
TransportationProblem,
46+
TransportationResult,
47+
balance, isbalanced,
48+
northwestcorner,
49+
leastcost
50+
4651
import .ShortestPath: ShortestPathResult, ShortestPathProblem
4752

4853
import .Network: Connection, nodes
@@ -60,7 +65,7 @@ import .RandomKeyGA: Chromosome, run_ga
6065
import .TravelingSalesman: TravelinSalesmenResult, travelingsalesman
6166
import .Simplex: SimplexProblem, simplexiterations, createsimplexproblem, gaussjordan
6267

63-
export TransportationProblem, TransportationResult, balance, isbalanced, northwestcorner
68+
export TransportationProblem, TransportationResult, balance, isbalanced, northwestcorner, leastcost
6469
export Connection, ShortestPathResult, MaximumFlowResult, nodes
6570
export ShortestPathProblem, MaximumFlowProblem
6671
export AssignmentProblem, AssignmentResult

src/transportation.jl

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ using JuMP, HiGHS
66

77
export TransportationProblem
88
export TransportationResult
9+
export northwestcorner
10+
export leastcost
11+
export isbalanced
12+
export balance
913

1014
import ..OperationsResearchModels: solve
1115

@@ -151,7 +155,7 @@ function solve(t::TransportationProblem)::TransportationResult
151155
@constraint(model, sum(x[1:n, j] for j = 1:p) .== newt.supply)
152156
@constraint(model, sum(x[i, 1:p] for i = 1:n) .== newt.demand)
153157

154-
initial_solution = northwestcorner(newt).solution
158+
initial_solution = northwestcorner(newt).solution
155159
JuMP.set_start_value.(x, initial_solution)
156160

157161
optimize!(model)
@@ -198,6 +202,33 @@ function northwestcorner(t::TransportationProblem)::TransportationResult
198202
return result
199203
end
200204

205+
function leastcost(t::TransportationProblem)::TransportationResult
206+
problem = t
207+
if !isbalanced(t)
208+
problem = balance(t)
209+
end
210+
supply = Base.copy(problem.supply)
211+
demand = Base.copy(problem.demand)
212+
n, m = size(problem.costs)
213+
asgnmatrix = zeros(Float64, n, m)
214+
cost = 0.0
215+
while (sum(supply) > 0) && (sum(demand) > 0)
216+
mincost = minimum(problem.costs)
217+
mincostrow, mincostcol = argmin(problem.costs).I
218+
amount = min(supply[mincostrow], demand[mincostcol])
219+
asgnmatrix[mincostrow, mincostcol] = amount
220+
supply[mincostrow] -= amount
221+
demand[mincostcol] -= amount
222+
if supply[mincostrow] == 0
223+
problem.costs[mincostrow, :] .= Inf
224+
elseif demand[mincostcol] == 0
225+
problem.costs[:, mincostcol] .= Inf
226+
end
227+
cost += amount * mincost
228+
end
229+
result = TransportationResult(t, problem, asgnmatrix, cost)
230+
return result
231+
end
201232

202233

203234
end # end of module

test/runtests.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ using OperationsResearchModels
33
using OperationsResearchModels.Simplex
44

55

6+
include("testtransportation.jl")
67
include("testrandomkeyga.jl")
78
include("testtravelingsalesman.jl")
89
include("testjohnsons.jl")
910
include("testutility.jl")
1011
include("testjump.jl")
11-
include("testtransportation.jl")
1212
include("testassignment.jl")
1313
include("testshortestpath.jl")
1414
include("testmaximumflow.jl")
@@ -21,3 +21,4 @@ include("testlatex.jl")
2121
include("testknapsack.jl")
2222
include("testsimplex.jl")
2323

24+

test/testtransportation.jl

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
]
7878
end
7979

80-
@testset "Solution - 2" begin
80+
@testset "Solution - 2" begin
8181
t = TransportationProblem(
8282
Float64[10 20 25; 12 15 7],
8383
Float64[190, 40, 20],
@@ -87,7 +87,7 @@
8787

8888
@test result.cost == 2720.0
8989
@test result.solution == [150.0 0.0 0.0; 40.0 40.0 20.0]
90-
end
90+
end
9191

9292
@testset "North-West Corner" begin
9393
@testset "Example 1" begin
@@ -134,9 +134,49 @@
134134
@test result.cost == 3510
135135
end
136136
end
137-
137+
138+
139+
140+
141+
@testset "Least Cost Method" begin
142+
@testset "Example 1" begin
143+
t = TransportationProblem(
144+
Float64[1 2 8 10; 7 3 4 5; 12 11 9 6],
145+
Float64[50, 60, 30, 130],
146+
Float64[90, 110, 70]
147+
)
148+
result = leastcost(t)
149+
expected = Float64[
150+
50 40 0 0;
151+
0 20 30 60;
152+
0 0 0 70
153+
]
154+
@test result.solution == expected
155+
@test result.cost == 1030
156+
end
157+
158+
@testset "Example 2" begin
159+
t = TransportationProblem(
160+
Float64[10 2 20 11; 12 7 9 20; 4 14 16 18],
161+
Float64[5, 15, 15, 15],
162+
Float64[15, 25, 10]
163+
)
164+
165+
result = leastcost(t)
166+
167+
expected = Float64[0 15 0 0; 0 0 15 10; 5 0 0 5]
168+
169+
@test result.solution == expected
170+
171+
@test result.cost == 475
172+
end
173+
end
174+
175+
176+
177+
138178
@testset "Big Example - Check if it is solved in reasonable times" verbose = true begin
139-
179+
140180
t = TransportationProblem(
141181
rand(10:1000, 350, 450) * 1.0,
142182
rand(1:100, 450) * 1.0,
@@ -145,7 +185,7 @@
145185

146186

147187
result = solve(t)
148-
188+
149189
@test result.cost > 0
150190

151191
end

0 commit comments

Comments
 (0)