Vessel Scheduling

https://img.shields.io/badge/AIMMS_24.5-ZIP:_Vessel_Scheduling-blue https://img.shields.io/badge/AIMMS_24.5-Github:_Vessel_Scheduling-blue https://img.shields.io/badge/AIMMS_Community-Forum-yellow ../../_images/project-1920-high7.gif

Story

In this practical example, an efficient plan is developed for delivering large cargoes using oil tankers.

The model assumes each ship can carry only one cargo at a time, and once the time horizon begins, all vessels head directly to the loading port. Upon loading, each vessel proceeds directly to the delivery location within its designated time window.

Constraints include ensuring each cargo is loaded inside the determined time window, each cargo being transported by only one vessel, and each charter vessels being assigned to only one route at a time.

The objective is to minimize costs associated to combinations of cargoes and routes.

Mathematical Model

To appreciate the complexity of the below mathematical formulation, it is important to note that the number of routes grows combinatorially with the number of cargos. For instance, with 7 vessels and 20 cargos, the number of routes can exceed half a million.

Vessel Scheduling Model

Sets and indices:

\(v\), \(v \in Vessels\)

Vessels

\(c\), \(c \in Cargos\)

Cargos

\(r\), \(r \in Routes\)

Routes

Parameters:

\(D_{v,r} \in \{ 0, 1 \}\)

Route \(r\) used by vessel \(v\): p_def_domainAllocateVesselToRoute

\(CR_{c,r} \in \{ 0, 1 \}\)

Cargo \(c\) on route \(r\): p_def_cargoesOnRoute

\(IC_{v} \in \mathbb{R_{+}}\)

Idle cost for vessel \(v\): p_def_idleCostVesselNotUsed

\(SC_{c} \in \mathbb{R_{+}}\)

Cost cargo \(c\) handled on spot market: p_spotCostVessel

\(T_{r} \in \mathbb{R_{+}}\)

Cost executing route \(r\): p_def_operationalCostPerRoute

Variables:

\(a_{(v,r)|D_{v,r}} \in \{ 0, 1 \}\)

allocate vessel \(v\) to route \(r\): v_allocateVesselToRoute

\(s_{c} \in \{0..1\}\)

cargo \(c\) is left to the spot market: bv_cargoOnCharteredVessel

\(i_{v} \in \{0..1\}\)

vessel \(v\) remains idle: v_idleVessel

Constraints:

1

\(\forall c: \sum_r a_{v,r} * CR_{c,r} + s_{c} = 1\)

Cargo on a single vessel, or left to spot market

2

\(\forall v: \sum_r a_{v,r} + i_{v} = 1\)

Each vessel can take only one route, or is idle

Minimize:

\(\sum_{v,r} T_{r} * a_{v,r} +\)

Operational cost

\(\sum_{v} IC_{v} * i_{v} +\)

Unused vessel cost

\(\sum_{c} SC_{p,c} * S_{c}\)

Total cost of cargos left to the spot market

Language

Route Generation

Before optimization, all possible routes are generated after data import, taking into account each cargo’s loading window to ensure timely delivery.

During the mathematical optimization process, each cargo is then assigned to either a time-chartered or voyage-chartered vessel within the model.

In this example, the vessel scheduling problem is solved by first generating the routes, followed by the mathematical optimization. The majority of the time is spent on route generation.

Example

A single vessel, vessel1, located at Caracas, is to handle two cargos, labeled: a1 and a2.

  1. a1 load in Paramaribo, deliver in Sao Paolo

  2. a2 load in Montevideo, deliver in Rio de Janeiro.

Then there are five potential routes:

  1. vessel1_a1_a2: with actions:

    1. Sail to Caracas to Paramaribo

    2. Load Cargo a1

    3. Sail to Sao Paolo

    4. Deliver Cargo a1

    5. Sail to Montevideo

    6. Load Cargo a2

    7. Sail to Rio de Janeiro

    8. Deliver Cargo a2

  2. vessel1_a2_a1: similar as vessel1_a1_a2, just a different order of locations; and thus also different vessel sailing times and cargo pickup moments.

  3. vessel1_a1: vessel1 only handles cargo a1

  4. vessel1_a2: vessel1 only handles cargo a2

  5. vessel1 Remains at port Caracas

The route generation procedure is as follows:

  1. For each vessel i, the idle route is generated: vessel<i>. Together they initialize the set of just generated routes, JG.

  2. Move the set of just generated routes JG, to the set of input routes IR.

  3. For each r in IR, all cargos c are considered to be appended for a new route r'. A route r' = r_c is accepted if:

    • c is not a part of r,

    • c is picked up in its time window, and

    • c is delivered before the end of the horizon.

    All routes r' just generated, form the new set of just generated routes JG. If the set JG is empty, stop, otherwise continue with step 2.

Because a route r' ends later than route r, this procedure is finite.

In order to determine the cost of a route, careful administration of each leg needs to be done (sailing to the loading location, perhaps waiting, sailing to the delivery location).

WebUI Features

On input page, if you click around the graphs, a highlighted cell will appear identifying the last clicked element. The results are displayed in a combination chart (stacked bar chart).

The following WebUI features are used:

UI Styling

Below there are the css files you will find with comments on what they change.

 1:root {
 2   --primaryDark: #DA2063;
 3   --primaryDarker: #FF4940;
 4   --secondary90Transparent: #ff4a4023;
 5   --secondary: #2E324F;
 6
 7   --bg_app-logo: 15px 50% / 40px 40px no-repeat url(/app-resources/resources/images/schedule.png); /*app logo*/
 8   --spacing_app-logo_width: 60px;
 9   --color_border_app-header-divider: var(--secondary); /*line color after header*/
10
11   --color_workflow-item-divider: var(--secondary90Transparent); /*workflow step divider color*/
12   --color_bg_workflow_current: var(--primaryDark); /*bg color when step is selected*/
13   --color_workflow_active: var(--primaryDark); /*font and icon color when step is active*/
14   --color_workflow-icon-border: var(--primaryDark); /*round border of the step*/
15   --color_bg_workflow_active: #ff4a400e;;
16
17   --color_bg_app-canvas: url(/app-resources/resources/images/RightBackground.png) rgb(249, 249, 249) no-repeat left/contain; /*background color*/
18   --color_bg_widget-header: linear-gradient(90deg, rgba(255,73,64,0.75) 0%, rgba(218,32,99,0.75)  100%); /*widget header background color*/
19   --border_widget-header: 2px solid var(--secondary); /*line color after widget header*/
20
21   --color_text_widget-header: var(--secondary);
22   --color_text_edit-select-link: var(--primaryDark);
23
24   --color_bg_button_primary: var(--primaryDark);
25   --color_bg_button_primary_hover: var(--primaryDarker);
26}
 1/*Hide checkbox contents of delete and edit annotations*/
 2.annotation-edit-element input.boolean-cell-editor-contents,
 3.annotation-delete-element input.boolean-cell-editor-contents{
 4   visibility: hidden;
 5   display: block;
 6}
 7
 8.annotation-edit-element {
 9   background: white url(img/pencil.png) no-repeat 50%/contain;
10   background-size: auto 70% ;
11}
12
13.annotation-delete-element {
14   background: white url(img/minus.png) no-repeat 50%/contain;
15   background-size: auto 50% ;
16
17}
18
19.annotation-NotInUse,
20.annotation-DeliveringPort,
21.annotation-VisibleLocations{
22   fill: #FE493F;
23   background: #FE493F !important;
24}
25
26.annotation-InUse,
27.annotation-LoadingPort{
28   fill: #9E3869;
29   background: #9E3869 !important;
30}
31
32.annotation-not-fulfilled{
33   background: #ffc21b2c;
34}
35
36.annotation-highlight-cell {
37   background: var(--secondary90Transparent);
38}
 1/*Centering cells*/
 2.tag-table .cell.flag-string .cell-wrapper,
 3.tag-table .cell.flag-number input,
 4.tag-table .cell.flag-string input{
 5   text-align: center;
 6}
 7
 8.tag-slider .slider-value {
 9   color: var(--color_text_edit-select-link);
10}
11
12.widget-menu__item .title {
13   color: var(--color_text_app-footer);
14}
15
16.ql-snow a {
17   color: var(--color_text_edit-select-link) !important;
18}
19
20input.boolean-cell-editor-contents {
21   accent-color: var(--primaryDark) /*boolean color*/
22}
23
24.react-contextmenu .react-contextmenu-item .display-text {
25   color: inherit;
26}
27
28.aimms-widget[data-widget\.uri="scl_EditAddElements"] .awf-dock.top,
29.aimms-widget[data-widget\.uri="msl_selecRoutes"] .awf-dock.top,
30.aimms-widget[data-widget\.uri="MappingCargoesWithCollors_1"] .awf-dock.top,
31.aimms-widget[data-widget\.uri="Vessel loading_1"] .awf-dock.top{
32   display: none;
33}
34
35.status-message:hover,
36.status-message.clickable:hover .status-display-text {
37   background-color: #ffcdcb2d;
38   color: #505767;
39}

As a service

In the above, the algorithm of this app is presented that generates a set of potential routes, and optimizes a mathematical program to find an optimal selection of those routes.

A service can be defined around this algorithm facilitating its use by other applications via REST API.

A service in an AIMMS model is easily defined by associating the name of a service to an AIMMS procedure. More interestingly, is that there are several data formats available for providing input (request body) and output (response body) to a request on such a service.

In the following sections, we will detail:

  1. Defining a service

  2. Implementing a service

  3. Testing such a service using a Python script with the requests python library

  4. Developing and testing such a service on AIMMS Cloud using the

Defining and implementing a a service

Coding the service

A service is defined by naming it and associating it with a procedure. For instance in the following example code:

 1rocedure pr_solveVesselSchedulingExcel {
 2    Body: {
 3        block
 4
 5            pr_initTask();
 6
 7            _sp_inp := dex::api::RequestAttribute( 'request-data-path'  ) ;
 8            _sp_out := dex::api::RequestAttribute( 'response-data-path' ) ;
 9
10            pr_actuallySolveVesselSchedulingExcel( _sp_inp, _sp_out );
11
12        onerror _ep_err do
13
14            _sp_msg := errh::Message( _ep_err );
15            display _sp_msg ;
16
17        endblock ;
18
19        return 1 ;
20    }
21    dex::ServiceName: solveVesselSchedulingExcel;
22    StringParameter _sp_inp;
23    StringParameter _sp_out;
24    ElementParameter _ep_err {
25        Range: errh::PendingErrors;
26    }
27    StringParameter _sp_msg;
28}

Remarks:

  • Line 1: The name of the procedure that will be executed when the service is called.

  • Line 21: The name of the service, that will be available for execution.

  • Lines 7,8: The filename of the request and response.

Whereby pr_initTask

The procedure pr_initTask is run when a task is started; it is intended to make the “Business model” of the application stateless; such that tasks can be run independently from each other.

Here “Business model” refers to identifiers (sets, parameters, variables, and constraints) that represent objects in the reality being modeled. This is contrasted with application management identifiers such as such as user filenames, time of day, profiling information, and so forth. The sets and parameters in the libraries WebUI and PRO are all examples of management identifiers; and should not be altered by a procedure such as pr_initTask.

 1Procedure pr_initTask {
 2    Body: {
 3        ! Reset the Business model
 4        empty s_cargoes, s_vessels, s_locations, s_calc_feasibleRoutes ;
 5
 6        ! Clean the generated mathematical programs.
 7        _ep_gmp := first( AllGeneratedMathematicalPrograms );
 8        while _ep_gmp do
 9            gmp::Instance::Delete( _ep_gmp );
10        endwhile ;
11
12        ! Other cleanups
13        StringGarbageCollect();
14        CleanDependents();
15    }
16    ElementParameter _ep_gmp {
17        Range: AllGeneratedMathematicalPrograms;
18    }
19}

and pr_actuallySolveVesselSchedulingExcel

 1Procedure pr_actuallySolveVesselSchedulingExcel {
 2    Arguments: (sp_inp,sp_out);
 3    Body: {
 4        dex::AddMapping(
 5            mappingName : "ImportDataSet",
 6            mappingFile : "Mappings/Generated/ImportDataSet-Excel.xml");
 7
 8        p_vesselVelocity := 37.04 [km/hour];
 9
10        if dex::ReadFromFile(
11            dataFile    : sp_inp,
12            mappingName : "Generated/ImportDataSet-Excel") then
13
14            !Activate all master data
15            bp_activeCargoes(i_cargo):= 1;
16            bp_activeVessels(i_vessel) := 1;
17            bp_activeLocations(i_loc) := 1;
18        endif ;
19
20        pr_calculateRoutesAndCost(ep_routeCalculationImplementation: ep_selectedRouteCalculationImplementation );
21
22        solve mm::mp_vesselScheduling;
23
24        !Post Execution
25        mm::pr_post_vesselResults();
26        mm::pr_post_cargoResults();
27        mm::pr_post_routeResults();
28
29        dex::WriteToFile(
30            dataFile    :  sp_out,
31            mappingName :  "Generated/ExportDataSet-Excel",
32            pretty      :  1);
33    }
34    DeclarationSection Argument_declarations {
35        StringParameter sp_inp {
36            Property: Input;
37        }
38        StringParameter sp_out {
39            Property: Input;
40        }
41    }
42}

Remarks:

  • Line 10-12: The request data is read in.

  • Line 29-31: The response data is written out.

Starting and stopping the service

When using the AIMMS IDE, you can manually start and stop the service using the procedures:

When using AimmsCMD, or AIMMS inside a docker container, the service is better started using the procedure dex::api::RESTServiceHandler. This will stop execution after timeout or after exceeding the maximum number of requests. Fine control is provided via the parameters:

  • dex::api::RESTServiceMaxRequests

  • dex::api::RestServiceMinTimeout

  • dex::api::RESTServiceTimeout

When using the AIMMS cloud, the service is automatically started when a task is posted; no need to manually start the service.

Vessel Scheduling Headless execution

Headless execution is available in several ways, depending on your software environment, you can choose what is best for you.

The headless execution can take place:

  1. on your laptop,

  2. inside a docker container, or

  3. in the AIMMS Cloud.

Headless execution on your laptop

Directly using AimmsCmd

When project and data are both available on the same Windows machine, directly using AimmsCmd is perhaps the easiest way.

AimmsCmd command lines follow the structure:

AimmsCmd [options for AimmsCmd] projectName.aimms [options for aimms application] < aimmscmdfile > logfile 2> errfile

There is a clear ordering in this command line:

  1. First, the options to AimmsCmd itself. These options are optional, but a typical example is --run-only <run only procedure>.

  2. Second, the name of the project. This is mandatory and

  3. Third, the arguments to the AIMMS project, which can be retrieved using SessionArgument

  4. Fourth, input/output redirection. Often used as an alternative to the run only procedure.

Three examples:

Example a: A single run procedure with session arguments.

A .bat file demonstrating the use:

 1echo on
 2
 3rem Use AimmsCMD to start Vessel Scheduling with session arguments.
 4
 5set AIMMS_VERSION=25.3.2.6-x64-VS2022
 6set AIMMS_EXECUTABLE=%localappdata%\AIMMS\IFA\Aimms\%AIMMS_VERSION%\Bin\AimmsCMD.exe
 7
 8pushd ..\AIMMSProject
 9
10%AIMMS_EXECUTABLE% --run-only pr_solveModelSessionArguments  "VesselScheduling.aimms" data\VS_7Vessel_20Cargo.xlsx data\VS_7Vessel_20Cargo_Results.xlsx
11
12popd
13
14echo Current time: %time%
15
16pause

Remarks:

  • Lines 5 and 6 is to facilitate easy switching between AIMMS Versions / executables.

  • Line 10: A run only procedure is used, and this procedure accepts two arguments to do the actual run.

  • The pushd and popd commands ensure the current working folder during the AIMMS session is the project folder of the application.

  • Subsequently, both the input and output of the AIMMS Session are in the subfolder data.

  • And also, the logs of what happened during the AIMMS Session are in the subfolder log

Example b: with file redirection and AimmsCmd scripts.

In some environments, such a script is known as a properties file.

 1echo on
 2
 3rem Use AimmsCMD to start Vessel Scheduling via an AimmsCmd script
 4
 5set AIMMS_VERSION=25.3.2.6-x64-VS2022
 6set AIMMS_EXECUTABLE=%localappdata%\AIMMS\IFA\Aimms\%AIMMS_VERSION%\Bin\AimmsCMD.exe
 7
 8pushd ..\AIMMSProject
 9
10%AIMMS_EXECUTABLE% "VesselScheduling.aimms" < single-run.properties > log/single-run.log 2> log/single-run.err
11
12popd
13
14echo Current time: %time%
15
16pause

The AimmsCmd script single-run.properties in above contains a series of AimmsCmd commands, for instance the following:

let sp_theExcelInput := "data/VS_7Vessel_20Cargo.xlsx" ;
let sp_theExcelOutput := "data/VS_7Vessel_20Cargo_Results.xlsx" ;
run pr_solveTheModel ;
quit ;

This achieves the same result.

Example c: starting the application as a service
 1echo on
 2
 3rem Use AimmsCMD to start Vessel Scheduling as a service.
 4
 5set AIMMS_VERSION=25.3.2.6-x64-VS2022
 6set AIMMS_EXECUTABLE=%localappdata%\AIMMS\IFA\Aimms\%AIMMS_VERSION%\Bin\AimmsCMD.exe
 7
 8set VS_ROOT=C:\u\s\examples\application-examples\vessel-scheduling
 9set VS_PROJECT=%VS_ROOT%\AIMMSProject
10
11pushd %VS_PROJECT%
12
13%AIMMS_EXECUTABLE% --run-only dex::api::RESTServiceHandler "VesselScheduling.aimms"  --dex::serviceTimeOut 30000
14
15popd
16
17echo Current time: %time%
18
19pause

Remarks:

  • Line 10 is the interesting one, we use

    • --run-only dex::api::RESTServiceHandler to start the service, and

    • the session arguments --dex::serviceTimeOut and 30000 the set the default timeout to 30 seconds (as opposed to 5 minutes).

Headless execution in a docker container

To execute AIMMS inside a docker container, first a docker image needs to be prepared with the necessary components, and subsequently, AIMMS needs to be executed by completing the missing information and starting the executable. Both for preparing the image, and for the choice on how to run there are several options. These will be detailed below.

Preparing an image for the docker container

To execute an AIMMS session in a docker container, a setup needs to be prepared. This setup consists of four components:

  1. The AIMMS Executable / installation

  2. The AIMMS License to be used

  3. The AIMMS Application

  4. The data for the AIMMS Application

We will discuss the choices available for each of the components below.

Including the AIMMS Executable to the docker image

The docker image is based on the aimms-eo docker image. This docker image is parameterized for the AIMMS version, and includes the materials from the Linux AIMMS installation and necessary other software components to execute.

Including or mounting the AIMMS License to the docker image

The AIMMS License must be available in the /data folder, which can be either mounted or included in the image definition. The folder structure should be as follows:

../../_images/license-structure-network-license.png

Here the license.cfg file may contain a network license - which is a license of the following contents: 1     network     <your license server>:3400

Including or mounting the AIMMS Application to the docker image

Also the AIMMS application can be stored in the image, or be made accessible via a mount.

The folder /model is used inside the Docker image for this purpose, and execution of AIMMS needs to start in this folder.

You can achieve this by adding /w model to your docker run command.

When adding the project to the image, please copy the essential contents of the project to the subfolder model in the aimms-eo folder (build context).

Here the essential contents are the contents without folders such as backup and log.

Optionally a, you can add a LoggerConfig.xml to the model folder for logging execution. Redirect the output to a mounted folder for inspection.

For example, if your LoggerConfig.xml is taken from this how-to, change line 44 from:

<param name="File" value="log/aimms-log.txt" />

to

<param name="File" value="/outputs/aimms-log.txt" />

Where /outputs is a mounted volume (see also below).

Optionally b, You can also add a bash script, aimmscmdrun.sh, to steer execution:

The contents of this aimmscmdrun.sh bash script:

#!/bin/sh

/usr/local/Aimms/Bin/AimmsCmd VesselScheduling.aimms </inputs/single-run.properties >/outputs/single-run.log 2>/outputs/single-run.err

The contents of this bash script clearly depend on the AIMMS project name and on other name choices for mounting volumes.

Mounting the data for the AIMMS application

The data, both input and output, are not typically included in the image, as this data varies per run.

Assuming files are used to exchange data, use the /inputs and /outputs folders:

In the example I used, there are two folders used: /inputs and /outputs:

  • /inputs contains input files and possibly single-run.properties.

  • /outputs contains the results and execution logs.

In my example I mount these volumes. An alternative, when the /model folder is mounted, they can also be sub folders of the /model folder.

Building the image
 1echo on
 2
 3rem Builds a docker image with:
 4rem 1. license info in sub-folder "data" of aimms-eo checkout
 5rem 2. AIMMS application in sub-folder "model" of aimms-eo checkout
 6rem 3. AIMMS 25.2.3.1 installation
 7
 8set VS_ROOT=C:\u\s\examples\application-examples\vessel-scheduling
 9
10pushd %VS_ROOT%\aimms-eo
11
12docker build -f Dockerfile.WithLicenseAndModel -t vesselscheduling:1.0.2.1 --build-arg AIMMS_VERSION_MAJOR=25.3 --build-arg AIMMS_VERSION_MINOR=1.0 .
13
14popd
15
16pause

Running AIMMS inside the image

Information used when running AIMMS in a docker container can either be in the Docker container, or on the host on which the docker container runs.

In this example:

  • the AIMMS installation is on the image,

  • the AIMMS license is on the image,

  • the AIMMS model is on the image, but

  • the input and output data of the AIMMS application is stored in mounted volumes.

This setup for docker containers permits the following three ways of executing headless:

Using AimmsCmd in a container and just running a single procedure
echo on

rem Script to execute a single procedure in an AIMMS app stored in a docker image.

set VS_ROOT=C:\u\s\examples\application-examples\vessel-scheduling
set VS_INPUTS=%VS_ROOT%\inputs
set VS_OUTPUTS=%VS_ROOT%\outputs

docker run --rm -i -v "%VS_INPUTS%:/inputs" -v "%VS_OUTPUTS%:/outputs" -w /model vesselscheduling:1.0.2.1 AimmsCmd --run-only pr_solveModelSessionArguments "VesselScheduling.aimms" /inputs/VS_70Vessel_100Cargo.xlsx /outputs/VS_70Vessel_100Cargo_results.xlsx

pause
Using AimmsCmd in a container and executing a aimmscmd script

Here AimmsCmd is called with redirected input and output. To ensure that the input/output redirection is applied to the command executing in the docker container, and not the docker command that is running on the host, the AimmsCmd call in encapsulated in a shell call.

echo on

rem run vessel-scheduling by redirecting the AimmsCmd command file /inputs/single-run.properties as input to AimmsCmd in a docker container.

set VS_ROOT=C:\u\s\examples\application-examples\vessel-scheduling
set VS_INPUTS=%VS_ROOT%\inputs
set VS_OUTPUTS=%VS_ROOT%\outputs

docker run -i -v "%VS_INPUTS%:/inputs" -v "%VS_OUTPUTS%:/outputs" -w /model vesselscheduling:1.0.2.1 /bin/bash -c "/usr/local/Aimms/Bin/AimmsCmd VesselScheduling.aimms </inputs/single-run.properties >/outputs/single-run.log 2>/outputs/single-run.err"

pause

Alternatively, you can put the bash command in a bash script file, for instance aimmscmdrun.sh as detailed above.

echo on

rem run vessel-scheduling by redirecting the AimmsCmd command file /inputs/single-run.properties as input to AimmsCmd in a docker container.

set VS_ROOT=C:\u\s\examples\application-examples\vessel-scheduling
set VS_INPUTS=%VS_ROOT%\inputs
set VS_OUTPUTS=%VS_ROOT%\outputs

docker run -i -v "%VS_INPUTS%:/inputs" -v "%VS_OUTPUTS%:/outputs" -w /model vesselscheduling:1.0.2.1 /bin/bash -c /model/aimmscmdrun.sh

pause

whereby aimmscmdrun.sh is as above.

the reason for using aimmscmdrun.sh is to apply the redirection to AimmsCmd and not to docker.

Using AimmsCmd in a container and running a service
echo on

rem Start the VesselScheduling app with a REST API Service, handling tasks to solve the VesselScheduling problem.

set VS_ROOT=C:\u\s\examples\application-examples\vessel-scheduling
set VS_INPUTS=%VS_ROOT%\inputs
set VS_OUTPUTS=%VS_ROOT%\outputs

docker run --rm -i -v "%VS_INPUTS%:/inputs" -v "%VS_OUTPUTS%:/outputs"  -p 12003:12003 -w /model vesselscheduling:1.0.2.1 AimmsCmd --run-only dex::api::RESTServiceHandler "VesselScheduling.aimms"

pause

Remarks:

You can subsequently use a REST API client to use the service exposed.

Running AIMMS headless inside the AIMMS Cloud

The handling of AIMMS and docker containers on the AIMMS Cloud is fully automated; hence this section is very brief.

Once an AIMMS application is published, its services are automatically available. No need to start the service explicitly; when a task for an application is posted, the corresponding AIMMS project is started and the task is handled.

More information can be found here.

Minimal Requirements

AIMMS Community license is sufficient for working with this example. To run the Python client, you will need to have Python installed, for this example we used Python 3.11.

To deploy the application on AIMMS Cloud, a commercial license is needed.

References

#. Gustavo Diz, Luiz Felipe Scavarda, Roger Rocha, Silvio Hamacher (2014) Decision Support System for PETROBRAS Ship Scheduling. Interfaces 44(6):555-566.

  1. Develop an AIMMS Service

  2. A Python library to make it really easy to use AIMMS Cloud REST services

  3. AIMMS command line options

Release Notes

v1.3 (07/10/2024)

Fixing integration problems (import and export) when using the project on AIMMS PRO Portal.

v1.2 (23/09/2024)

Added support for AimmsCmd, the task output now has three sheets, and the python now reads from the data folder inside the AIMMS Project.

v1.1 (19/09/2024)

Performance of the route generation procedure was updated. Now you are able to solve using a Python call.

v1.0 (15/08/2024)

First version of this application.