Reputation: 18547
The goal of the opl model below is to choose the freights with total minimum cost to fulfill all orders, I have a constraint of the order on a freight must be delivered to <= 2 clientId. Currently the optimal solution is to use the third freight for all orders (since it's the cheapest), but with the new constraint, the 3rd freight can carry at most two orders (since each order is for different clientId). but how to encode that constraint?
current .mod file (model file)
tuple TFreightTypes {
key string Destination;
key string VehicleType;
int TotalWeight;
key string Company;
int Cost;
};
tuple TOrders {
key int OrderNumber;
float Weight;
string ClientId;
string Destination;
string MaterialCategory;
int CategoryPriority;
};
{TFreightTypes} FreightTypes = ...;
{TOrders} Orders = ...;
dvar boolean Assignment[Orders][FreightTypes];
dexpr float objective =
sum(o in Orders, f in FreightTypes)
Assignment[o][f] * f.Cost;
//choose freight with total minimum cost
minimize objective;
subject to{
//c1: all order must be fulfilled
forall(o in Orders)
sum(f in FreightTypes) Assignment[o][f]==1;
//c2: the order on a freight must be less than 2 destination
}
.dat file (data file)
FreightTypes = {
<"LONDON","Type1",20000,"SP TRANSPORTS",40000>,
<"LONDON","Type2",20000,"SP TRANSPORTS",40000>,
<"DURHAM","Type3",10000,"SP TRANSPORTS",30000>,
};
Orders = {
<1,5000,"Client1","LONDON","A",0>,
<2,1000,"Client2","DURHAM","B",1>,
<3,2000,"Client3","LONDON","C",1>,
};
Upvotes: 1
Views: 116
Reputation: 10062
You can write
//c2: the orders on a freight must be less than 2
forall(f in FreightTypes)
ctMax2:
sum(o in Orders) Assignment[o][f]<=2;
and 2 comply with the 2 destinations, the complete model could look like
tuple TFreightTypes {
key string Destination;
key string VehicleType;
int TotalWeight;
key string Company;
int Cost;
};
tuple TOrders {
key int OrderNumber;
float Weight;
string ClientId;
string Destination;
string MaterialCategory;
int CategoryPriority;
};
{TFreightTypes} FreightTypes = ...;
{TOrders} Orders = ...;
dvar boolean Assignment[Orders][FreightTypes];
dexpr float objective =
sum(o in Orders, f in FreightTypes)
Assignment[o][f] * f.Cost;
{string} destinations={i.Destination | i in Orders};
dvar boolean Destination[FreightTypes][destinations];
//choose freight with total minimum cost
minimize objective;
subject to{
forall(f in FreightTypes,d in destinations)
Destination[f][d]==(1<=sum(o in Orders:o.Destination==d)Assignment[o][f]);
//c1: all order must be fulfilled
forall(o in Orders)
sum(f in FreightTypes) Assignment[o][f]==1;
//c2: the order on a freight must be less than 2 destinations
forall(f in FreightTypes)
ctMax2:
sum(d in destinations) Destination[f][d]<=2;
}
Upvotes: 1