/********************************************* * OPL Model * Transportation problem with additional constraints * An implementation using dexpr and tuple *********************************************/ int Ndest = ...; setof(string) I = ...; // origins setof(int) J = asSet(1..Ndest); // destinations int O[I] = ...; // capacity of origin i in I int D[J] = ...; // request of destintion j in J float C[I][J] = ...; // unit transportation cost //additional parameters for requirement 1: // if the cost of link from i to j is at most LowCost, // then the flow on this link should be at least LowCostMinOnLink float LowCost = ...; int LowCostMinOnLink = ...; //additional parameters for requirement 2: // destination SpecialDestination should receive at least MinToSpecialDest units // from each origin, but for origin SpecialOrigin int SpecialDestination = ...; string SpecialOrigin = ...; float MinToSpecialDest = ...; //define a "custom type" identifying an origin-destination (od) pair tuple odpair { string i; int j; } //define a set of od pairs (the ones connecting non-expensive links) float CostThreshold = 0.8*max(i in I, j in J) C[i][j]; {odpair} OD = { | i in I, j in J : C[i][j]<=CostThreshold }; dvar int+ x[OD]; // how much to move from i to j ? dexpr float total_cost = sum (od in OD) (C[od.i][od.j] * x[od]); minimize total_cost; subject to { forall ( j in J ) { request: sum ( od in OD: od.j == j ) x[od] >= D[j]; } forall ( i in I ) { capacity: sum ( in OD ) x[] <= O[i]; } //additional constraints 1 forall ( od in OD : C[od.i][od.j] <= LowCost ) { lowerboundCost: x[od] >= LowCostMinOnLink; } //additional constraints 2 forall ( in OD : i != SpecialOrigin) { lowerboundSpecial: x[] >= MinToSpecialDest; } //additional constraints 3: at least 25% of the total transport cost // has to be spent for transportations from SpecialOrigin // (we use factorized dexpr "total_cost") sum ( in OD ) C[SpecialOrigin][j]*x[] >= 0.25*total_cost; } execute{ writeln("TRANSPORT FLOWS"); for ( var od in OD ) { if ( x[od] > 1e-6 ) { writeln("from ", od.i, " to ", od.j , " send ", x[od], " units"); } } }