I have a little confusion in the optimization model I trying to solve. Its a small model to minimize the cost of two units. I have just started with the optimization and I am not sure if I am interpreting the problem very well into AMPL. Especially regarding the minimization constraints and their bounds.
I have to two decision variables as Units in my models. Cost of u1 is 10 and u2 is 13. And the limit on the u1 is that you can not make more than 100 units and for u2 is 50 units. I got different results by reversing the bounds of this minimization problem. Can anyone help me interpret whats happening?
var u1 >=0;
var u2 >=0;
minimize costofunits: 10*u1 +13*u2;
subject to unit1: 0 <= u1 <= 100;
subject to unit2: 0 <= u2 <= 50;
With above constraints I have output as:
CPLEX 12.8.0.0: optimal solution; objective 0
0 dual simplex iterations (0 in phase I)
Objective is: 0.000000
: _varname _var :=
1 u1 0
2 u2 0
;
: _objname _obj :=
1 costofunits 0
;
: _conname _con :=
1 unit1 0
2 unit2 0
;
Reversing the Constraints:
subject to unit1: 100 <= u1 <= 0;
subject to unit2: 50 <= u2 <= 0;
OUTPUT AS:
inconsistent bounds for constraint unit1:
lower bound = 100 > upper bound = 0
inconsistent bounds for constraint unit2:
lower bound = 50 > upper bound = 0
Infeasible constraints determined by presolve.
Objective is: 825.000000
: _varname _var :=
1 u1 50
2 u2 25
;
: _objname _obj :=
1 costofunits 825
;
: _conname _con :=
1 unit1 10
2 unit2 13
;
For your first problem: as you've defined the problem, the objective is to minimize costs, and the easiest solution is simply to make zero of everything, for zero cost.
For your second problem, the error message explains the problem. You have set a lower bound of 100 for u1 (100 <= u1) and also an upper bound of 0 (u1 <= 0). Obviously there is no possible number that would satisfy both of these requirements at once. Instead of "<=" in your constraints, you should be using ">=" here, assuming you want to bound u1 between 100 and 0.
Same issue for unit2 constraint.
Related
While finding time complexities I can find the time complexity of any loop but not able to proof or understand it mathematically for eg : for(i = 0 ; i > n ; i /= 2) have O(log n) but how can i find and proof it mathematically, Please help me to understand this.
Correciting the loop for(i = n ; i > 0 ; i /= 2)
First of all, I think the loop you want to ask about is this:
for (i = n; i > 0; i /= 2)
A simple empirical way to figure out the complexity is to simply relate the bound of the loop n to the number of times the loop executes. For example, if n = 16, then i would take the following values:
i | loop iteration
16 | 1
8 | 2
4 | 3
2 | 4
1 | 5
So for an input of n = 16, there are roughly 4 steps:
2^4 = n
log_2(n) = 4
=> number of iterations is log_2(n)
I have a binary variable y[k][t], where k = 1..3 (machines) and t = 1..10 (time). Variable Y is 1 if machine is active and 0 otherwise.
In the optimization if machine 1 is active in period 1 e.g. Y[1][1] = 1, i want the machine to continue to operate for at least 3 time periods. i.e. Y[1][1] = Y[1][2] = Y[1][3] = Y[1][4] = 1.
I only want the succesive variable for t+1,t+2,t+3 to be same as t if it is active.
how can i do that in cplex studio?
This is sometimes called a minimum run length. There are different approaches to handle this. Say we have x(t) as our binary variables indicating if the machine is operating at time t. The first thing is to introduce a binary variable start(t) that indicates when a run starts. This is what I mean:
t 1 2 3 4 5 6 7 8
x 0 1 1 1 0 1 1 0
start 0 1 0 0 0 1 0 0
A run starts when x(t-1)=0 and x(t)=1, or more formally:
start(t) = x(t)*(1-x(t-1))
This is nonlinear. We can linearize this using:
start(t) <= x(t)
start(t) <= 1-x(t-1)
start(t) >= x(t)-x(t-1)
Often we just use the bound:
start(t) >= x(t)-x(t-1)
Next we need:
start(t) = 1 ==> x(t)...x(t+K-1) = 1
where K is the minimum run length.
This can be modeled as:
x(t+1) >= start(t)
...
x(t+K-1) >= start(t)
(we already know that x(t)=1 if start(t)=1).
what Erwin wrote about minimum run length is fine. If you rely on logical constraints that are available in CPLEX the model is a bit easier:
range K=1..3;
range T=1..10;
dvar boolean Y[K][T];
dvar boolean start[K][T];
subject to
{
forall(k in K) start[k][1]==Y[k][1];
forall(k in K,t in T:t!=1) start[k][t] == ((Y[k][t]==1) && (Y[k][t-1]==0));
forall(k in K) forall(l in 1..3)
forall(t in T:(t+l) in T) (start[k][t]==1) => (Y[k][t+l]==1);
}
But what could lead to long solve time if you grow the time horizon is that we enumerate time. Within CPLEX and OPL you may also use CPOptimizer and its dedicated scheduling concepts : intervals.
Then you would write
using CP;
range K=1..3;
range T=1..10;
int nbMaxIntervals=4;
dvar interval itvs[K][1..nbMaxIntervals] optional in T size 3..10;
subject to
{
forall(k in K) forall(i in 1..nbMaxIntervals-1)
endBeforeStart(itvs[k][i],itvs[k][i+1]);
}
What makes sure that you are on for at least 3 time periods is
size 3..10;
NB: More about CPOptimizer
I'm working on an optimization project and I faced a small problem. For my project, I'm using AMPL and CPLEX as a solver. In my code, I have some elements indicated by e1, e2, ..., en. I also have a set which contains tuples within these elements. I must assign a number between 1 and 'n' to each element such that I maximize the distance between every 2 elements in 1 tuple in the moveTuples set (I need to order them but try to keep a distance between elements in the same tuple).
Every element MUST have ONLY 1 assigned number and each number should be given to ONLY 1 element. For this purpose, I wrote the following code:
set Elements;
set moveTuples dimen 2;
set Numbers;
var assign {Elements,Numbers} binary;
var maximizer{moveTuples} integer >= 0;
maximize obj: sum {(A,B) in moveTuples} maximizer[A,B];
subject to assign1NumberPerElement {i in Element}: sum {c in Numbers} assign[i,c] = 1;
subject to assign1ElementPerNumber {c in Numbers}: sum {i in Element} assign[i,c] = 1;
subject to moveApart {(A,B) in moveTuples}: abs(sum{i in Numbers}(assign[A,i]*i) - (sum{j in Numbers}x[B,j]*j)) - maximizer[A,B] = 0 ;
data;
set Elements:= e1 e2 e3;
set Numbers:= 1 2 3;
set moveTuples: e1 e2 e3:=
(e1, e2);
solve;
display assign;
Now the problem is clear and for the previous example, the output must be either:
e1 -> 1
e2 -> 3
e3 -> 2
or
e1 -> 3
e2 -> 1
e3 -> 2
since it is required to only move e1 from e2 using the tuple (e1,e2). When running the previous code, I get the error: ... contains a non-quadratic non-linear constraint (definitely the "moveApart" constraint). Can you please guide me on how to solve this problem? Thanks in advance.
The constraint moveApart is nonlinear (and non-quadratic) because it contains a call to abs. However, since your problem is purely integer, you can solve it with CPLEX CP Optimizer (ilogcp).
I am trying to solve a LP, which is a facility location problem.
The task asks me to deduct 10.000$ iff the optimal model results in having less than 3 Distribution Centers open (y1,y2,y3,y4).
The objective function looks like this: min z = Σ(fiyi) + ΣΣ(cijxij) + ΣΣ(xij*bi) - Σqi*10.000
fi: fixed costs
yi: binary variable; yi = 1 - DC is open; yi = 0 - DC is closed
cij: transportation costs from DC i to customer j
xij: quantity shipped from DC i to customer j
bi: variable warehouse costs at DC i
qi: binary variable; bi = 1 - IT Cost reduction yes; bi = 0 - no IT cost reduction
Now I need to introduce a logical constraint for having the "if..then..." thingy in it. I want to express the following dependence as a constraint in xpress:
if Σyi ≤ 2 ; then Σqi = 1 → IT cost reduction
if Σyi > 2 ; then Σqi = 0 → no IT cost reduction
Any help highly appreciated!
Solved it myself by introducing the following constraints:
3 ≤ Σyi + 2q ≤ 4
I have a data set that looks like this (SAS 9.4):
data opt_test;
input ID GRP $ x1 MIN MAX y z;
cards;
2 F 10 9 11 1.5 100
3 F 10 9 11 1.2 50
4 F 11 9 11 .9 20
8 G 5 4 6 1.2 300
9 G 6 4 6 .9 200
;
run;
I want to create a new variable x2 that maximizes a function based on x1, x2, y, and z.
I am having two main problems:
The syntax on my proc optmodel has some errors that I have not been able to fix "Subscript 1 may not be a set" and constraint has incomplete declaration". UPDATE: I figured this part out.
I need for the value of x2 to be the same for all members of the same GRP. So, id 2,3,4 would have same x2. ID 8 and 9 would have same x2.
Below is my attempt. This will ultimately be able to run with sevarl different GRP of varying numbers of ID.
Thanks in advance for any assistance.
proc optmodel;
set<num> ID;
var x2{ID} >= 0;
string GRP{ID};
number x1{ID};
number MIN{ID};
number MAX{ID};
number y{ID};
number z{ID};
max sales=sum{i in ID}(x2[i])*(1-(x2[i]-x1[i])*y[i]/x1[i])*z[i];
con floor_METRIC1{i in ID}: x2[i]>=MIN[i];
con ceiling_METRIC1{i in ID}: x2[i]<=MAX[i];
read data opt_test into
ID=[ID]
GRP
x1
MIN
MAX
y
z
;
solve;
print x2;
quit;
If you want the value of x2 to be the same for all ids in the same group, then you only need one variable x2 per group. To keep track of which ids are in which group you could use an array of sets indexed by group:
set<num> ID;
string GRP{ID};
set GRPS = setof{i in ID} GRP[i];
set IDperGRP{gi in GRPS} = {i in ID: GRP[i] = gi};
When you use = (as opposed to init), you provide OPTMODEL with a function you don't need to update later. If you change any of the GRP or ID data, optmodel will recompute GRPS and IDperGRP as needed.
Now you can use the GRPS set and the IDperGRP array of sets to rewrite your objective to more closely match your business rule:
max sales = sum{gi in GRPS} sum{i in IDperGRP[gi]}
(x2[gi]) * (1-(x2[gi]-x1[i])*y[i]/x1[i]) * z[i];
Writing the expression this way makes it clearer (to me at least) that it can be simplified further as long as x1, y, and z are constants.
Adding the new sets also makes it clearer (to me at least) that the bounds from floor_METRIC1 and ceiling_METRIC1 can be combined to tighten the domain of x2. Since MIN and MAX are constants, you can move the constraints into direct variable bounds by adding >= and <= clauses to the declaration of x2. Since x2 will now depend on MIN and MAX, you will have to declare those before x2. IMHO that makes your intent clearer:
number MIN{ID};
number MAX{ID};
var x2{gi in GRPS} >= max{i in IDperGRP[gi]} MIN[i]
<= min{i in IDperGRP[gi]} MAX[i]
;