22
Logistics Optimization of the distribution of containerized freight moving to/from the Cagliari port in the regional network. JUNE – JULY 2016 INTERNSHIP REPORT Asâad AZOUR Supervisor Professor Paola ZUDDAS

Logistics Optimization of the distribution of ...dipartimenti.unica.it/.../files/2016/09/report-zuddas.pdfLogistics Optimization of the distribution of containerized freight moving

Embed Size (px)

Citation preview

Logistics Optimization of the distribution of containerized freight moving to/from the Cagliari

port in the regional network.

JUNE – JULY 2016

INTERNSHIP REPORT

Asâad AZOUR

Supervisor

Professor Paola ZUDDAS

1

Acknowledgement

Before starting, I want to thank Professor Paola ZUDDAS for giving me the opportunity

of doing the internship among her team, and for her help during the internship.

I also want to thank all the team working on the project CagliariPort2020 at the University of

Cagliari for their support and their heartwarming welcome.

I also thank Mr. Alessandro GIUA for the proposal of the internship.

Thanks to them and to the people I met in Cagliari, I will keep a good memory of Cagliari, and

how Italian people are friendly and nice.

2

Summary

Introduction ...................................................................................................... 3

The shipper planning problem in maritime urban areas ............................... 4

The optimization model of the shipper planning problem ............................. 5

Work done ........................................................................................................ 7

Conclusion and perspectives .......................................................................... 14

Sources ............................................................................................................ 15

3

Introduction

Students at the Industrial and computing engineering cycle at Polytech Marseille are

asked to do an internship at a research laboratory by the end of the 4th year.

And so I did mine at “Dipartimento Di Matematica e Informatica; Università degli

Studi di Cagliari “, the department of mathematics and computing science at the University of

Cagliari in Italy from the first of June to the 31st of July 2016.

The University of Cagliari is a partner involved in the CagliariPort2020 project, they are parts,

or co-leader for many development objectives and the leaders of 2 tasks of the project:

Defining a logistic model design and implementation of the harbor urban area

infrastructure of Cagliari.

Developing optimization methods to support decision making process on logistics.

The first task has for purpose to define a general architecture design of the Cagliariport2020

system, structured on multiple levels to ensure the maximum interoperability and scalability

system, to ease its use by other systems.

The second one has for purpose the development of a platform for the optimal planning of inner

and external logistics in the port of Cagliari.

Therefore, I’ve been working on a project which intends to realize a system able to cope with

forthcoming increasing in vehicles, goods, and passengers, by developing a general

methodology for managing the interface between the city and the port system in term of logistic

hubs.

For my part, the internship was about creating a linear program on CPLEX (software)

and creating the data that can be used on this program to validate the optimization model of the

shipper planning problem.

I have been doing this research internship under the supervision of Professor Paola ZUDDAS

among her team of PhD students and contributors.

4

The shipper planning problem in maritime urban areas

This study investigates a planning problem faced by shippers in maritime urban areas.

In this problem the loads of several customers are grouped into containers and trucks, which

are discharged from vessels and moved to satellite facilities strategically located in the city or

around.

The transshipment of loads is performed at satellites and loads are moved by vehicles from

satellites to customers.

In this context, shippers are dealing with the assignment of containers and trucks to satellites,

and in turn of their loads to the vehicles used for the final distribution.

The mathematical model to minimize the assignment coasts, while accounting for distribution

coasts and fair sharing of workload among all carriers involved in this distribution scheme.

To sum up, the shipper planning problem aims to define a cost-minimizing set of routes,

by satisfying different constraints to support decision making process. And here is schema 1 a

representation of the port, the satellites and the customers:

Shema 1

Port

Deposit

1

Deposit

2

Deposit

i

Client j

Client 3

Client 2

Client 1

Cost P - 1

Cost P - i

Cost P - 2

Cost 1 - 1

Cost 1 - 4

Cost 1 - j

Cost 2 - 1

Cost i - 1

Cost 2 - j

Cost i - j

5

The optimization model of the shipper planning problem

Let C, S, K and U be respectively, the sets of containers, satellites, vehicles and customers.

Let P(c) be the set of pallets into the container c ϵ C. A first formulation for the problem uses

the following set of variables:

- xsc = 1 if the container c ϵ C is assigned to the satellites s ϵ S, and 0 otherwise.

- yscpk = 1 if the pallet p ϵ P(c) of the container c ϵ C, assigned to the satellite s ϵ S, is

carried by the vehicle k ϵ K.

- wsk = 1 if the vehicle k ϵ K is assigned to the satellite s ϵ S, and 0 otherwise.

- Smin, Smax: absolute value (relative) maximum and minimum load for any vehicle.

And the following set of data:

- tsc: assignment coast of the container c ϵ C to the satellite s ϵ S.

- hsk: assignment coast of the vehicle k ϵ K to the satellite s ϵ S.

- Vs: capacity of the satellite s ϵ S, i.e. the maximum number of containers contained into

the satellite s ϵ S.

- rc: the load of container c ϵ C (in term of pallets), i.e. the number of pallets carried in

container c ϵ C.

- Sk: the maximum load of the vehicle k ϵ K, i.e. the maximum number of pallets entering

to the container k ϵ K.

- ρ: a scale parameter.

Let fs be the cost to unload any container c ϵ C at the satellite s ϵ S, and let Ω(c) ⊆ U be the set

of customers having goods in the container c ϵ C. Moreover, let indicate by dsu the distance between

the satellite s ϵ S and the customer u ϵ U. Then, the assignment cost tsc, is computed as follows:

𝑡𝑠𝑐 = 𝑏 ∑ 𝑑𝑠𝑢 + 𝑓𝑠

𝑢ϵ Ω(c)

Where b is a scale factor.

The problem can be formulated as indicated herein below where the objective function aims to

minimize the assignment cost and the number of the vehicles involved in the distribution.

The objective function:

𝑚𝑖𝑛 ∑ ∑ 𝑡𝑠𝑐 𝑥𝑠𝑐 + ∑ ∑ ℎ𝑠𝑘𝑤𝑠𝑘

𝑘ϵ K𝑠ϵ S

𝑐ϵ C𝑠ϵ S

− 𝜌 𝑆𝑚𝑖𝑛

Subject to:

∑ 𝑥𝑠𝑐 = 1𝑠ϵ S c ϵ C

6

∑ 𝑤𝑠𝑘 ≤ 1𝑠ϵ S k ϵ K

∑ 𝑥𝑠𝑐 ≤ 𝑉𝑠𝑐ϵ C s ϵ S

∑ ∑ 𝑦𝑠𝑐𝑝𝑘 = 𝑟𝑐 𝑥𝑠𝑐𝑝ϵ P(c)𝑘ϵ K c ϵ C, s ϵ S

∑ ∑ 𝑦𝑠𝑐𝑝𝑘 = 1𝑘ϵ K𝑠ϵ S c ϵ C, p ϵ P(c)

∑ ∑ 𝑦𝑠𝑐𝑝𝑘 ≤ 𝑤𝑠𝑘 𝑆𝑘𝑝ϵ P(c)𝑠ϵ 𝑆 k ϵ K, s ϵ S

𝑆𝑚𝑖𝑛 ≤ ∑ ∑ (𝑦𝑠𝑐𝑝𝑘 + 𝑀 (1 − 𝑤𝑠𝑘))𝑝ϵ P(c)𝑐ϵ C k ϵ K, s ϵ S

xsc ϵ {0, 1} c ϵ C, s ϵ S

yscpk ϵ {0, 1} c ϵ C, s ϵ S, p ϵ P(c), k ϵ K

wsk ϵ {0, 1} k ϵ K, s ϵ S

Smin ≥ 0

Where M = max {S: k ϵ K}

7

Work done

After the model had been created I had to implement it on IBM ILOG CPLEX

Optimization Studio (CPLEX) which is an optimization software package implemented in C

programming language. This software solves the linear programming problems using either

primal or dual variants.

And I had to create different data that is used as an input to the program to experiment the

performance of the suggested model and to verify that problems in real life dimensions are

solvable in time.

To validate the model, I was asked to proceed by steps:

1. First step

The first step was to create the model and small instances of data on CPLEX manually. In order

to validate the formulation of the objective function and the constraints of the model.

And so as input of the model program we had: T

The assignment cost of the containers to the satellites and vehicle to satellites;

The capacity of satellites;

The distance between satellite and customers;

The number of deposits, containers, clients, vehicles, pallets;

The scalars;

The figure 1 represents a part of the input data to the CPLEX program at the first step:

Figure1

8

2. Second step:

At the second step I was asked to calculate the assignment cost of containers to satellite (tsc)

𝑡𝑠𝑐 = 𝑏 ∑ 𝑑𝑠𝑢 + 𝑓𝑠

𝑢ϵ Ω(c)

instead of generating a matrix of distance like in the first step.

And unlike the first step, I had to generate atomically the assignment cost of vehicle to satellite

hsk which is used in the objective function. And fs the cost to unload any container to a satellite

which is used to calculate tsc

And so, since hsk correlates with the distance between initial position of vehicle and satellite,

we made the choice that hsk can be calculated by calculating the distance between the initial

vehicle position and satellites they serve. And made the choice that fs can be calculated by

calculating the distance between the port and the satellite where the container is unloaded.

So, I generated the client’s position, the deposit’s position and then calculated the distances

with a function created using the program on CPLEX.

The figure 2 represents a part of the input data to the CPLEX program at the second step:

Figure 2

9

The figure 3 represents the function on the CPLEX program that calculates variables hsk, fs and

dsu which represents the distance between satellite and customer.

Figure 3

You can find attached in annex 1 and annex 2 respectively the model on CPLEX and the data

associated to the model at the execution of the second step.

3. Third step:

At the third step I was asked to write a program on C++ that generates random data in a

way that it can be ridden on CPLEX.

We suggested that the user writes a “.txt” format file in a specific way that contains the

data needed to execute the C++ program. After that, the program written on C++ generates a

file that can be used as an input for the CPLEX program. And after executing the C++ output

file the CPLEX program generates the solution of the model.

In this study “model” at the third step we dispose of 2 types of containers:

C1: container of 10 pallets, so rc1 = 10

C2: container of 24 pallets, so rc2 = 24

And we have to run the model for 5, 10, 50, 100 and 150 containers with different percentage

of the two types of containers

Here bellow a table of the different types of containers we have to calculate on C++

Label 1 3 5 7 9

pc1 10% 30% 50% 70% 90%

pc2 90% 70% 50% 30% 10%

On C++ we have to make sure that the number of pallets is:

|p| = Sum(c in C ) rc = rc1 × pc1 × |C| + rc2 × pc2 × |C|

10

|p| = |C| x (rc1 × pc1 + rc2 × pc2)

= |C| ∑ (i = 1 to 2) rci ×pci

We dispose also of 4 types of vehicles:

V1: vehicle with a capacity of 1 pallet: Sk1 = 1

V2: vehicle with a capacity of 2 pallets: Sk2 = 2

V3: vehicle with a capacity of 6 pallets: Sk3 = 6

V4: vehicle with a capacity of 10 pallets: Sk4 = 10

After being in the deposits, pallets must be delivered to the clients by respecting a 3

dispositions of vehicles.

Disposition A B C

pk1 10% 40% 25%

pk2 20% 20% 25%

pk3 30% 30% 25%

pk4 40% 10% 25%

So for example, for disposition A:

10% of pallets will be delivered to clients using vehicles of type 1

20% of pallets will be delivered to clients using vehicles of type 2

30% of pallets will be delivered to clients using vehicles of type 3

40% of pallets will be delivered to clients using vehicles of type 4

On C++ we have to make sure that the number of vehicles is:

S = Sum(k in K ) Sk = Sk1 × pk1 × |K| + Sk2 × pk2 × |K| + Sk3 × pk3 × |K|+ Sk4 × pk4 × |K|

= |K| x (Sk1 × pk1 + Sk2 × pk2 + Sk3 × pk3 + Sk4 × pk4)

= |K| ∑ (i = 1 to 4) Ski × pki

S = Sum (k in K) Sk ≥ |p|

So:

|K| ∑ (i = 1 to 4) Ski *pki ≥ |C| ∑ (i = 1 to 2) rci *pci

|K|≥ (|C| ∑ (i = 1 to 2) rci *pci ) / (∑ (i = 1 to 4) Ski *pki )

At this study the number of clients could be 50% of the number of pallets or 20%

11

Here bellow an example of the C++ entry file

b = 1;

rho = 1;

numContainers = 5;

percContTyp_1 = 10;

percContTyp_2 = 90;

percVehTyp_1 = 10;

percVehTyp_2 = 20;

percVehTyp_3 = 30;

percVehTyp_4 = 40;

percClient = 20;

randDistanceX = 100;

randDistanceY = 180;

maxDistancePortDepot = 100;

maxDistancePortClient = 150;

minCapacityDepot = 10 ;

maxCapacityDepot = 91;

In this example the user chose to run the C++ program for 5 containers, and by using the

disposition A for vehicles, and disposition 1 for containers.

The number of pallets is calculated this way on C++

rc1 and rc2 represent respectively the capacity of containers of type 1 and type 2 in this case

rc1 = 10 and rc2 = 24

Since percClient = 20; the number of clients is 20% of the number of pallets

randDistanceX and randDistanceY are input data that are requested in functions that calculate

randomly different distances.

maxDistancePortDepot is a data used to check that the distance between the port and the

depots depass a limit

12

The figure 4 represents a screenshot of a function on C++ program using the data

randDistanceX, and maxDistancePortDepot.

Figure 4

Here a depot i is defined in a structure client.

The capacity of the depot is calculated with the function

depot.amount = qrand()%maxCapacityDepot + minCapacityDepot ;

The x coordinates of the depot I is calculated by the function:

while(abs(customer.at(0).corX - xDepot) > maxDistancePortDepot){

xDepot = qrand()%randDistanceX+(-randDistanceX/2);

}

This function generates a random number between the value of randDistanceX and

randDistanceX/2.

And in addition to generating solutions, the CPLEX program generates a file that summarizes

the solutions for the different dispositions, the figure 5 represents the table file where we can

see the objective value for different combinations.

13

Figure 5

14

Conclusion and perspectives

The main task of the project was to create the model of the shipper planning problem in

maritime urban areas on CPLEX and generate multiple combinations of realistic data to validate

the model. To achieve that, we worked by steps, and at the end of the project we used C++ in

order to generate random data to test the strength of the CPLEX model, which we managed to

do as planned.

Still, there can be many improvements of the program; we could have created an

interface on C++ where the client can enter the data instead of writing files. After the validation

of the strength of the model, we could have created an interface where the client enters the GPS

positions of different deposits and clients and then calculates the cost of the different paths in a

more realistic way.

15

Sources

https://www.vesseltracker.com/fr/Port/cagliari/Dashboard.html

http://people.unica.it/unicamappe/2012/08/10/dipartimento-di-matematica-e-informatica/

The research project Cagliariort2020

http://www.ibm.com/support/knowledgecenter/SSSA5P_12.6.3/ilog.odms.studio.help/pdf/opl

_languser.pdf

https://en.wikipedia.org/wiki/CPLEX

1

ANNEX 1

int numDeposits = ...;

int numContainers = ...;

int numClients = ...;

int numVehicles = ...;

int numPallets = ...;

float b = ...;

float rho = ...;

range S = 1..numDeposits; /* number of depot*/

range C = 1..numContainers; /* number of containers*/

range U = 1..numClients; /* number of clients */

range K = 1..numVehicles; /* number of vehicles*/

range P = 1..numPallets; /* number of palets*/

int Sk[K]=...;

float Vs[S]=...;

float dsu[S][U];

float hs[S][K];

float fs[S];

float t[S][C];

int labcls[U];

int rc[C];

dvar boolean x[S][C]; /* = 1 if container c is assigned to satellite s, 0

otherwise */

dvar boolean y[S][C][P][K]; /* = 1 if pallet p of container c assigned to

satellite s is ccarried by vehicle k*/

dvar boolean w[S][K]; /* = 1 if the vehicle k is assigned to satellite s, 0

otherwise*/

dvar float+ Smin;

tuple clientPosition { // creation of the client's position

key int id;

int corX;

int corY;

}

{clientPosition} clientP = ...;

tuple depositPosition { // creation of the deposit's position

key int id;

int corX;

int corY;

}

{depositPosition} depositP = ...;

tuple vehiclePosition { // creation of the vehicle's position

key int id;

int corX;

int corY;

}

{vehiclePosition} vehicleP = ...;

tuple pallet { // this variable is to associate pallets to their clients and to

the container they hold them

key int id;

int container;

int client;

2

}

{pallet} PalletsSet = ...;

/*###############################################################################

#######################*/

// initialization of the variables (dsc & hs & fs) used in the assignement coast

tsc

execute INITIALIZE_1{

for(var s in depositP ) for(var u in clientP ) {

dsu[s.id][u.id] = Math.pow((Math.pow((s.corX - u.corX),2) +

Math.pow((s.corY - u.corY),2)),0.5);

}

for(var s in depositP) for (var k in vehicleP) {

hs[s.id][k.id] = Math.pow((Math.pow((s.corX - k.corX),2) +

Math.pow((s.corY - k.corY),2)),0.5);

}

for(var s in depositP) {

fs[s.id] = Math.pow((Math.pow((s.corX ),2) + Math.pow((s.corY),2)),0.5);

}

}

float val;

int initM;

execute INITIALIZE {

// initialization of the variable tsc used in the OF

for (var c in C) {

rc[c] = 0;

for (var p in PalletsSet) // for any container & for p from 1 to the number

of pallets

if (p.container == c) // if a pallet p is in a container rc = rc +1

(number of pallets/container)

rc[c] += 1;

};

for(var s in S) for (var c in C) {

val = 0;

for( var u in U )

labcls[u] = 0;

for (var p in PalletsSet)

if( (p.container == c) && ( labcls[p.client]== 0 )){ // if container c

contains pallet c

val += dsu[s][p.client];

labcls[p.client] = 1;

}

t[s][c] = b * val + fs[s];

}

initM =0;

for (var i in K){

if (Sk[i] > initM){

initM = Sk[i];

}

}

3

}

int M = initM;

float cplexTimeExecBefore;

float cplexTimeExecAfter;

float tempo;

execute PARAMS {

cplex.tilim = 3600.000;

cplex.threads = 1;

var temptime= new Date();

cplexTimeExecBefore = temptime.getTime()/1000;

}

/*###############################################################################

#######################*/

minimize sum (s in S, c in C) (x [s][c]*t[s][c]) + sum (s in S, k in

K)(hs[s][k]*w[s][k])- rho * Smin;

subject to {

forall (c in C) sum (s in S) x[s][c] == 1;

forall (k in K) sum (s in S) w[s][k] <= 1;

forall (s in S) sum (c in C) x[s][c] <= Vs[s];

forall (c in C, s in S) (sum (k in K, p in 1..rc[c] ) y[s][c][p][k] )== rc[c]

* x[s][c];

forall (c in C, p in 1..rc[c]) sum (s in S, k in K) y[s][c][p][k] == 1;

forall (k in K, s in S) sum (c in C, p in 1..rc[c]) y[s][c][p][k] <= w[s][k]

* Sk[k];

forall (k in K, s in S)sum (c in C, p in 1..rc[c]) y[s][c][p][k] + M * (1 -

w[s][k]) >= Smin;

}

main {

thisOplModel.generate();

cplex.exportModel("dataInter.lp");

}

execute DISPLAY {

var temptime= new Date();

cplexTimeExecAfter = temptime.getTime()/1000;

tempo = cplexTimeExecAfter - cplexTimeExecBefore;

writeln("\nTime from the Model to the Solution: ", tempo);

writeln ("\r\n\r\n Objective function value: ", cplex.getObjValue());

var ofile = new IloOplOutputFile("tabellaLP.csv", true);

if(ofile.exists)

writeln(" exists ==> append ");

else

writeln("output.txt doesn't exist");

4

ofile.writeln( cplex.getBestObjValue() + "\t" + cplex.getObjValue() +

"\t" + tempo );

ofile.close();

}

5

ANNEX 2 /* b scale factor for tsc */

b = 10;

/*rho*/

rho = 1.0;

/*number of depot */

numDeposits = 2;

/*number of containers */

numContainers = 10;

/*number of vehicules */

numVehicles = 4;

/*number of clients */

numClients = 10;

/*number of pallets */

numPallets = 50;

/*this data associate pallets to their clients and to the container they hold

them < pallet id (num), container, client>*/

PalletsSet={

<1, 1 , 1 >,

<2, 1 , 5 >,

<3, 1 , 7 >,

<4, 2 , 2 >,

<5, 2 , 4 >,

<6, 2 , 9 >,

<7, 3 , 2 >,

<8, 3 , 2 >,

<9, 3 , 4 >,

<10, 3 , 5 >,

<11, 4 , 1 >,

<12, 4 , 1 >,

<13, 4 , 2 >,

<14, 4 , 3 >,

<15, 5 , 5 >,

<16, 5 , 5 >,

<17, 5 , 6 >,

<18, 5 , 6 >,

<19, 5 , 6 >,

<20, 5 , 7 >,

<21, 6 , 3 >,

<22, 6 , 1 >,

<23, 6 , 4 >,

<24, 6 , 6 >,

<25, 6 , 4 >,

<26, 6 , 5 >,

<27, 6 , 9 >,

<28, 6 , 8 >,

<29, 6 , 10 >,

<30, 7 , 1 >,

<31, 7 , 6 >,

<32, 7 , 7 >,

<33, 7 , 9 >,

<34, 8 , 1 >,

<35, 8 , 2 >,

<36, 8 , 2 >,

6

<37, 8 , 8 >,

<38, 8 , 9 >,

<39, 9 , 2 >,

<40, 9 , 3 >,

<41, 9 , 5 >,

<42, 9 , 5 >,

<43, 9 , 8 >,

<44, 9 , 8 >,

<45, 10 , 3 >,

<46, 10 , 3 >,

<47, 10 , 2 >,

<48, 10 , 1 >,

<49, 10 , 9 >,

<50, 10 , 5 >

};

/* Capacity of the deposits; number of containers in each satellite */

Vs = [ 10, 15 ];

/* Capacity of vehicles */

Sk = [ 20, 30, 40, 10 ];

/* Deposit position <deposit id , corX, corY>*/

depositP = {

<1, -30, 40>,

<2, 20, 26>

};

/* Client position <client id , corX, corY>*/

clientP = {

<1, 30, 78>,

<2, -45, 150>,

<3, -30, 200>,

<4, 50, 180>,

<5, 25, 260>,

<6, 18, 78>,

<7, -10, 13>,

<8, 13, 65>,

<9, -30, 120>,

<10, 17, 250>

};

/* Vehicle position <vehicle id , corX, corY>*/

vehicleP = {

<1, 10, 260>,

<2, -30, 160>,

<3, 30, 50>,

<4, -25, 200>

};