Hi all,
i am new to GAMS and try to implement a complex vehicle routing problem. I did quite well but one thing isn’t working at all:
There is routing variable x(i,j,t) which has location indices i and j, and index for time period t. Later in my code I want to add a vehicle index v to this, so i have parameter xt(i,j,t,v). Every location can be at least met once per period and every delivering tour has to start and end in depot ‘i1’. With this knowledge every tour can be identified even without index v. As an example tour1 can look like i1 - i2 - i3 - i5 - i1 and tour2 like i1 - i4 - i6 - i1.
To add vehicle index v I have to tell GAMS these tours and try to do this by adding variable nexti, while nexti equals ord(j), and looping over i and j. With the code attached I get the (exact) xt(i,j,t,v) for tour1 which then looks like:
INDEX 1 = v1
t1
i1.i2 1.000
i2.i3 1.000
i3.i5 1.000
i5.i1 1.000
In the next loop iteration, tour i1 - i2 - i3 - i5 - i1 should be “ignored” but I didn’t get that. I think every xt(i,j,t,v) is filled with data from tour1 until my abort criterion stops the loop. How can I tell GAMS to ignore x(i1,i2,t) and take x(i1,i4,t) with which the loop should generate the exact xt(i,j,t,v) for tour2?
Obviously my break statement is wrong even, but I don’t know better… Hope you understand what I am trying to do and can help me!
Thanks a lot in advance.
Sven
Note: In my original code I x(i,j,t) is a variable but in this reduced example I created it as a parameter.
*---------------------------------------------------------------------------
*---------------------------------------------------------------------------
*Data
*---------------------------------------------------------------------------
*---------------------------------------------------------------------------
Sets i 'locations' / i1 * i6 /
v 'vehicles' / v1 * v3 /
t 'time period' / t1 /;
Alias (i,j);
Set nextv(v);
Parameter
x(i,j,t) '1 if location i immediately precedes location j on a delivery route; 0 otherwise'
xt(v,i,j,t) '1 if location i immediately precedes location j on a delivery route; 0 otherwise'
touren(t) 'number of vehicles leaving depot i1 in period t'
count 'parameter to count in loop'
;
touren(t) = 0;
Variable nexti 'faces following location in delivering route'
;
*---------------------------------------------------------------------------
*---------------------------------------------------------------------------
*Random Delivery Routes
*---------------------------------------------------------------------------
*---------------------------------------------------------------------------
x('i1','i2',t) = 1;
x('i1','i4',t) = 1;
x('i2','i3',t) = 1;
x('i3','i5',t) = 1;
x('i5','i1',t) = 1;
x('i4','i6',t) = 1;
x('i6','i1',t) = 1;
*---------------------------------------------------------------------------
*---------------------------------------------------------------------------
*Count number of vehicles leaving depot i1 in period t
*---------------------------------------------------------------------------
*---------------------------------------------------------------------------
loop(t,
loop((i,j),
if(x(i,j,t)$(ord(i) = 1) = 1,
touren(t) = touren(t)+1;
);
);
);
*---------------------------------------------------------------------------
*---------------------------------------------------------------------------
*Tour must start in depot i1 and end in depot i1, each vehicle v can do at
*least one tour per period t
*Goal: Assign index v to every tour
*---------------------------------------------------------------------------
*---------------------------------------------------------------------------
loop(t,
nexti.l = 1;
count = 1;
nextv(v)=no;
nextv('v1')=yes;
loop(i$(Ord(i)=nexti.l),
loop(j,
if(x(i,j,t) = 1,
xt(nextv,i,j,t) = x(i,j,t);
nexti.l = ord(j);
*when following location equals i1 (depot), then use next vehicle v
if(nexti.l=1,
nextv(v) = nextv(v-1);
count = count+1;
);
break;
);
);
);
);
display xt;
In the end, parameter xt should look like:
INDEX 1 = v1
t1
i1.i2 1.000
i2.i3 1.000
i3.i5 1.000
i5.i1 1.000
INDEX 1 = v2
t1
i1.i4 1.000
i4.i6 1.000
i6.i1 1.000
Thank you!