Lotka Volterra fishing problem (APMonitor)
Appearance
This page contains a solution of the MIOCP Lotka Volterra fishing problem in APMonitor Python format. A MATLAB version is also available from the Dynamic Optimization Course as Example 3 (lotka_volterra_fishing.zip).
APMonitor
The model in Python code for a fixed control discretization grid using orthogonal collocation and a simultaneous optimization method. The APMonitor package is available with pip install APMonitor or from the APMonitor Python Github repository.
import numpy as np
import matplotlib.pyplot as plt
# retrieve apm.py from
# https://raw.githubusercontent.com/APMonitor/apm_python/master/apm.py
# or
# http://apmonitor.com/wiki/index.php/Main/PythonApp
# from apm import *
# pip install with 'pip install APMonitor'
from APMonitor.apm import *
# local APMonitor servers are available for Windows or Linux
# http://apmonitor.com/wiki/index.php/Main/APMonitorServer
# with clients in Python, MATLAB, and Julia
# write model
model = '''
! apopt MINLP solver options (see apopt.com)
File apopt.opt
minlp_maximum_iterations 1000 ! minlp iterations
minlp_max_iter_with_int_sol 50 ! minlp iterations if integer solution is found
minlp_as_nlp 0 ! treat minlp as nlp
nlp_maximum_iterations 200 ! nlp sub-problem max iterations
minlp_branch_method 1 ! 1 = depth first, 2 = breadth first
minlp_gap_tol 0.001 ! covergence tolerance
minlp_integer_tol 0.001 ! maximum deviation from whole number to be considered an integer
minlp_integer_leaves 0 ! create soft (1) integer leaves or hard (2) integer leaves with branching
End File
Constants
c0 = 0.4
c1 = 0.2
Parameters
last
Variables
x0 = 0.5 , >= 0
x1 = 0.7 , >= 0
x2 = 0.0 , >= 0
int_w = 0 , >= 0 , <= 1
Intermediates
w = int_w
Equations
minimize last * x2
$x0 = x0 - x0*x1 - c0*x0*w
$x1 = - x1 + x0*x1 - c1*x1*w
$x2 = (x0-1)^2 + (x1-1)^2
'''
fid = open('lotka_volterra.apm','w')
fid.write(model)
fid.close()
# write data file
time = np.linspace(0,12,121)
time = np.insert(time, 1, 0.01)
last = np.zeros(122)
last[-1] = 1.0
data = np.vstack((time,last))
np.savetxt('data.csv',data.T,delimiter=',',header='time,last',comments='')
# specify server and application name
s = 'http://byu.apmonitor.com'
#s = 'http://127.0.0.1/' # for local APMonitor server
a = 'lotka'
apm(s,a,'clear all')
apm_load(s,a,'lotka_volterra.apm')
csv_load(s,a,'data.csv')
apm_option(s,a,'nlc.imode',6) # Nonlinear control / dynamic optimization
apm_option(s,a,'nlc.nodes',3)
apm_info(s,a,'MV','int_w') # M or MV = Manipulated variable - independent variable over time horizon
apm_option(s,a,'int_w.status',1) # Status: 1=ON, 0=OFF
apm_option(s,a,'int_w.mv_type',0) # MV Type = Zero Order Hold
apm_option(s,a,'nlc.solver',1) # 1 = APOPT
# solve
output = apm(s,a,'solve')
print(output)
# retrieve solution
y = apm_sol(s,a)
plt.figure(1)
plt.step(y['time'],y['int_w'],'r-',label='w (0/1)')
plt.plot(y['time'],y['x0'],'b-',label=r'$x_0$')
plt.plot(y['time'],y['x1'],'k-',label=r'$x_1$')
plt.plot(y['time'],y['x2'],'g-',label=r'$x_2$')
plt.xlabel('Time')
plt.ylabel('Variables')
plt.legend(loc='best')
plt.show()
Results with APOPT (MINLP)
An MINLP solution is calculated with [1] with an objective function value of . APOPT requires 52 NLP solutions to find an integer solution (111.0 seconds of processing time).
---------------------------------------------------------------- APMonitor, Version 0.7.9 APMonitor Optimization Suite ---------------------------------------------------------------- --------- APM Model Size ------------ Each time step contains Objects : 0 Constants : 2 Variables : 5 Intermediates: 1 Connections : 0 Equations : 5 Residuals : 4 Number of state variables: 2178 Number of total equations: - 2057 Number of slack variables: - 0 --------------------------------------- Degrees of freedom : 121 ---------------------------------------------- Dynamic Control with APOPT Solver ---------------------------------------------- Iter: 1 I: 0 Tm: 12.99 NLPi: 93 Dpth: 0 Lvs: 2 Obj: 1.34E+00 Gap: NaN Iter: 2 I: 0 Tm: 2.82 NLPi: 18 Dpth: 1 Lvs: 3 Obj: 1.34E+00 Gap: NaN Iter: 3 I: 0 Tm: 3.39 NLPi: 30 Dpth: 2 Lvs: 4 Obj: 1.34E+00 Gap: NaN Iter: 4 I: 0 Tm: 10.37 NLPi: 131 Dpth: 3 Lvs: 5 Obj: 1.34E+00 Gap: NaN Iter: 5 I: 0 Tm: 1.81 NLPi: 10 Dpth: 4 Lvs: 6 Obj: 1.34E+00 Gap: NaN Iter: 6 I: 0 Tm: 7.93 NLPi: 102 Dpth: 5 Lvs: 7 Obj: 1.34E+00 Gap: NaN Iter: 7 I: 0 Tm: 3.22 NLPi: 28 Dpth: 6 Lvs: 8 Obj: 1.34E+00 Gap: NaN Iter: 8 I: 0 Tm: 1.85 NLPi: 12 Dpth: 7 Lvs: 9 Obj: 1.34E+00 Gap: NaN Iter: 9 I: 0 Tm: 10.24 NLPi: 140 Dpth: 8 Lvs: 10 Obj: 1.34E+00 Gap: NaN Iter: 10 I: 0 Tm: 2.04 NLPi: 9 Dpth: 9 Lvs: 11 Obj: 1.35E+00 Gap: NaN Iter: 11 I: 0 Tm: 6.50 NLPi: 86 Dpth: 10 Lvs: 12 Obj: 1.35E+00 Gap: NaN Iter: 12 I: 0 Tm: 1.94 NLPi: 17 Dpth: 11 Lvs: 13 Obj: 1.35E+00 Gap: NaN Iter: 13 I: 0 Tm: 2.17 NLPi: 18 Dpth: 12 Lvs: 14 Obj: 1.35E+00 Gap: NaN Iter: 14 I: 0 Tm: 3.56 NLPi: 44 Dpth: 13 Lvs: 15 Obj: 1.35E+00 Gap: NaN Iter: 15 I: 0 Tm: 2.34 NLPi: 23 Dpth: 14 Lvs: 16 Obj: 1.35E+00 Gap: NaN Iter: 16 I: 0 Tm: 2.46 NLPi: 26 Dpth: 15 Lvs: 17 Obj: 1.35E+00 Gap: NaN Iter: 17 I: 0 Tm: 2.72 NLPi: 26 Dpth: 16 Lvs: 18 Obj: 1.35E+00 Gap: NaN Iter: 18 I: 0 Tm: 3.99 NLPi: 60 Dpth: 17 Lvs: 19 Obj: 1.35E+00 Gap: NaN Iter: 19 I: 0 Tm: 1.91 NLPi: 10 Dpth: 18 Lvs: 20 Obj: 1.35E+00 Gap: NaN Iter: 20 I: 0 Tm: 1.23 NLPi: 7 Dpth: 19 Lvs: 21 Obj: 1.35E+00 Gap: NaN Iter: 21 I: 0 Tm: 1.37 NLPi: 8 Dpth: 20 Lvs: 22 Obj: 1.35E+00 Gap: NaN Iter: 22 I: 0 Tm: 1.37 NLPi: 12 Dpth: 21 Lvs: 23 Obj: 1.35E+00 Gap: NaN Iter: 23 I: 0 Tm: 1.34 NLPi: 11 Dpth: 22 Lvs: 24 Obj: 1.36E+00 Gap: NaN Iter: 24 I: 0 Tm: 1.30 NLPi: 8 Dpth: 23 Lvs: 25 Obj: 1.36E+00 Gap: NaN Iter: 25 I: 0 Tm: 1.33 NLPi: 14 Dpth: 24 Lvs: 26 Obj: 1.36E+00 Gap: NaN Iter: 26 I: 0 Tm: 1.13 NLPi: 7 Dpth: 25 Lvs: 27 Obj: 1.36E+00 Gap: NaN Iter: 27 I: 0 Tm: 0.97 NLPi: 7 Dpth: 26 Lvs: 28 Obj: 1.36E+00 Gap: NaN Iter: 28 I: 0 Tm: 0.99 NLPi: 6 Dpth: 27 Lvs: 29 Obj: 1.36E+00 Gap: NaN Iter: 29 I: 0 Tm: 0.93 NLPi: 6 Dpth: 28 Lvs: 30 Obj: 1.36E+00 Gap: NaN Iter: 30 I: 0 Tm: 0.66 NLPi: 5 Dpth: 29 Lvs: 31 Obj: 1.36E+00 Gap: NaN Iter: 31 I: 0 Tm: 0.73 NLPi: 5 Dpth: 30 Lvs: 32 Obj: 1.36E+00 Gap: NaN Iter: 32 I: 0 Tm: 0.66 NLPi: 5 Dpth: 31 Lvs: 33 Obj: 1.36E+00 Gap: NaN Iter: 33 I: 0 Tm: 0.70 NLPi: 5 Dpth: 32 Lvs: 34 Obj: 1.36E+00 Gap: NaN Iter: 34 I: 0 Tm: 0.67 NLPi: 5 Dpth: 33 Lvs: 35 Obj: 1.36E+00 Gap: NaN Iter: 35 I: 0 Tm: 0.82 NLPi: 9 Dpth: 34 Lvs: 36 Obj: 1.36E+00 Gap: NaN Iter: 36 I: 0 Tm: 0.77 NLPi: 8 Dpth: 35 Lvs: 37 Obj: 1.36E+00 Gap: NaN Iter: 37 I: 0 Tm: 0.75 NLPi: 8 Dpth: 36 Lvs: 38 Obj: 1.36E+00 Gap: NaN Iter: 38 I: 0 Tm: 0.69 NLPi: 6 Dpth: 37 Lvs: 39 Obj: 1.36E+00 Gap: NaN Iter: 39 I: 0 Tm: 0.71 NLPi: 6 Dpth: 38 Lvs: 40 Obj: 1.36E+00 Gap: NaN Iter: 40 I: 0 Tm: 0.81 NLPi: 9 Dpth: 39 Lvs: 41 Obj: 1.36E+00 Gap: NaN Iter: 41 I: 0 Tm: 0.70 NLPi: 8 Dpth: 40 Lvs: 42 Obj: 1.36E+00 Gap: NaN Iter: 42 I: 0 Tm: 0.69 NLPi: 6 Dpth: 41 Lvs: 43 Obj: 1.36E+00 Gap: NaN Iter: 43 I: 0 Tm: 0.67 NLPi: 5 Dpth: 42 Lvs: 44 Obj: 1.36E+00 Gap: NaN Iter: 44 I: 0 Tm: 0.60 NLPi: 4 Dpth: 43 Lvs: 45 Obj: 1.36E+00 Gap: NaN Iter: 45 I: 0 Tm: 0.71 NLPi: 6 Dpth: 44 Lvs: 46 Obj: 1.36E+00 Gap: NaN Iter: 46 I: 0 Tm: 0.59 NLPi: 4 Dpth: 45 Lvs: 47 Obj: 1.36E+00 Gap: NaN Iter: 47 I: 0 Tm: 0.69 NLPi: 6 Dpth: 46 Lvs: 48 Obj: 1.36E+00 Gap: NaN Iter: 48 I: 0 Tm: 0.65 NLPi: 5 Dpth: 47 Lvs: 49 Obj: 1.36E+00 Gap: NaN --Integer Solution: 1.36E+00 Lowest Leaf: 1.34E+00 Gap: 1.35E-02 Iter: 49 I: 0 Tm: 0.57 NLPi: 3 Dpth: 48 Lvs: 48 Obj: 1.36E+00 Gap: 1.35E-02 Iter: 50 I: 0 Tm: 1.29 NLPi: 8 Dpth: 48 Lvs: 47 Obj: 1.36E+00 Gap: 1.35E-02 Warning: best integer solution returned after maximum MINLP iterations Adjust minlp_max_iter_with_int_sol 50 in apopt.opt to change limit Successful solution --------------------------------------------------- Solver : APOPT (v1.0) Solution time : 111.364099999999 sec Objective : 1.36258198934523 Successful solution ---------------------------------------------------
