I’m trying to specify a warehouse location problem that allows the optimizer to pick the warehouse locations rather than provide candidate locations. The problem is (1) when trying to register a function and solve the problem I receive the error “key :calcDist not found” (this has been commented out), and when specifying the problem without registering a function I receive the error “Error” with no further message to debug. Anyone have any thoughts on where I have gone wrong?
using JuMP
using AmplNLWriter
#constants
num_clust = 2
min_lon =-125
max_lon = -66
min_lat = 24
max_lat = 50
op = pi / 180
r = 3959
#setup data
#customer latitudes, longitudes and revenue
olat = [42.37677 42.42025 42.05986 42.35515 42.21233 42.29128 42.31948 42.30205 42.15362 42.10354 42.09483 42.45941]
olon = [-72.46219 -72.10606 -72.4986 -72.56976 -72.64103 -72.87646 -72.63147 -72.2722 -72.77072 -72.59028 -72.48754 -73.28961]
orev = [225.4 123.48 252.84 146.02 439.04 314.58 319.48 108.78 100.94 467.46 464.52 242.06]
num_locs = size(olon)[2] #number of customer locations
#user defined functions
function calcDist(lon1, lat1, lon2, lat2)
#calculates distance between customer and warehouse
p = pi / 180
a = 0.5 - cos((lat2 - lat1) * p)/2 +
cos(lat1 * p) * cos(lat2 * p) * (1 - cos((lon2 - lon1) * p)) / 2
dist = (3959 * 2) * asin(sqrt(a))
dist
end
#setup model
m = Model(solver=CouenneNLSolver())
@variable(m, min_lon <= wh_lon[1:num_clust] <= max_lon, start = (min_lon + max_lon) /2) #warehouse longitudes
@variable(m, min_lat <= wh_lat[1:num_clust] <= max_lat, start = (min_lat + max_lat) /2) #warehouse latittudes
@variable(m, wh_choice[1:num_locs, 1:num_clust], Bin) #choose 1 warehouse for each customers
#each location must be mapped to a warehouse
for i in 1:num_locs
@constraint(m, sum(wh_choice[i, :]) == 1)
end
#setup non-linear paramters of current customer points
@NLparameter(m, lon[i = 1:num_locs] == olon[i])
@NLparameter(m, lat[i = 1:num_locs] == olat[i])
@NLparameter(m, rev[i = 1:num_locs] == orev[i]) #customer revenue
@NLparameter(m, p == op) #pi
# JuMP.register(m, :calcDist, 4, calcDist, autodiff = true)
# @NLobjective(m, Min, sum(calcDist(lon[i], lat[i], wh_lon[n], wh_lat[n]) *
# wh_choice[i,n] * rev[i] for i = 1:num_locs, n = 1:num_clust))
#minimize revenue weighted distances to warehoues
@NLobjective(m, Min, sum((3959 * 2) * asin(sqrt(0.5 - cos((wh_lat[n] - lat[i]) * p) / 2 + cos(lat[i] * p) * cos(wh_lat[n] * p) * (1 - cos((wh_lon[n] - lon[i]) * p)) / 2)) *
wh_choice[i,n] * rev[i] for i = 1:num_locs, n = 1:num_clust))
status = solve(m)