Lotka Volterra fishing problem (APMonitor)

From mintOC
Jump to: navigation, search

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 x_2(t_f) = 1.36. 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.

Volterra fishing APMonitor.png

 ----------------------------------------------------------------
 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
 ---------------------------------------------------