Lotka Volterra fishing problem (APMonitor)
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 APOPT with an objective function value of . APOPT requires 50 NLP solutions to find an integer solution (111 seconds of processing time). Each NLP solution in the branch and bound method requires an average of 2.2 seconds to complete with a range between 12.99 and 0.57 seconds.
---------------------------------------------------------------- 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 ---------------------------------------------------