I have this code:
If I use NLP i get the results, but using QCP as it was asked to me, I can not get results
anyone can help me finding the reason?
code:
sets g generators / P1*P5 /
properties generator properties / a,b,c,max,min /
cc(properties) cost categories / a,b,c /
table data(g,properties) generator cost characteristics and limits
a b c max min
P1 0.19 58.3 1800 155 35
P2 0.13 39.3 3250 195 60
P3 0.08 11.5 4600 165 95
P4 0.07 42.6 5100 305 170
P5 0.14 8.9 3850 280 130
parameter exp(cc) exponent for cost function / a 2, b 1, c 0 /;
scalar demand total power demand in MW / 730 / ;
variables
p(g) power generation level in MW
cost total generation cost - the objective function ;
positive variables p;
p.up(g) = data(g,"max") ;
p.lo(g) = data(g,"min") ;
equations
Q_Eq1 total cost calculation
Q_Eq2 constraint - total generation must equal demand ;
Q_Eq1 .. cost =e= sum((g,cc), data(g,cc)*power(p(g),exp(cc)));
Q_Eq2 .. sum(g,p(g)) =g= demand ;
model problem /all/ ;
solve problem using QCP minimizing cost ;
Seems as if the function "power" is treated as nonlinear in general without analyzing the value of "exp", so that it is not allowed for a QCP. You could reformulate Q_Eq1 like this to make it work:
Q_Eq1 .. cost =e= sum((g,cc), data(g,cc)*(1 $(exp(cc)=0) +
p(g) $(exp(cc)=1) +
sqr(p(g))$(exp(cc)=2)));
Best,
Lutz
Related
I have been trying to get my generalized network flow problem in AMPL but I keep running into this error:
presolve: constraint flow_balance['c5'] cannot hold:
body >= 0 cannot be <= -2500; difference = 2500
presolve: constraint flow_balance['p1'] cannot hold:
body <= 0 cannot be >= 4500; difference = -4500
presolve: constraint flow_balance['c5'] cannot hold:
body >= 0 cannot be <= -5300; difference = 5300
presolve: constraint flow_balance['p1'] cannot hold:
body <= 0 cannot be >= 4800; difference = -4800```
reset;
option solver cplex;
set NODES; # nodes in the network
set ARCS within {NODES, NODES}; # arcs in the network
param b {NODES} default 0; # supply/demand for node i
param c {ARCS} default 0; # cost of one of flow on arc(i,j)
param l {ARCS} default 0; # lower bound on flow on arc(i,j)
param u {ARCS} default Infinity; # upper bound on flow on arc(i,j)
param mu {ARCS} default 1; # multiplier on arc(i,j) -- if one unit leaves i, mu[i,j] units arrive
var x {ARCS}; # flow on arc (i,j)
data Prob3.dat
maximize profit: sum{(i,j) in ARCS} c[i,j] * x[i,j]; #objective: maximize arc flow profit
# Flow Out(i) - Flow In(i) = b(i)
subject to flow_balance {i in NODES}: sum{j in NODES: (i,j) in ARCS} x[i,j] - sum{j in NODES: (j,i) in ARCS} mu[j,i] * x[j,i] = b[i];
subject to capacity {(i,j) in ARCS}: l[i,j] <= x[i,j] <= u[i,j];
#subject to demand {i in NODES}: sum{j in NODES: (j,i) in ARCS} mu[j,i] * x[j,i] - sum{j in NODES: (i,j) in ARCS} x[i,j] = b[i];
solve;
display profit;
display NODES;
display ARCS;
display x;
#note: default arc costs and lower bounds are 0
# default arc upper bounds are infinity
# default node requirements are 0
# default multiplier is 1
set NODES := p1 p2 p3 p4 #product time period nodes
r1 r2 r3 r4 #raw material time period nodes
c1 c2 c3 c4 c5 c5p; #cash flow time period nodes
set ARCS := (p1,p2) (p2,p3) (p3,p4) #inventory arcs
(r1,r2) (r2,r3) (r3,r4) #raw inventory arcs
(c1,c2) (c2,c3) (c3,c4) (c4,c5) #cash flow arcs
(c5,c5p) #virtual arc
(p1,c2) (p2,c3) (p3,c4) (p4,c5) #buy arcs final
(r1,c2) (r2,c3) (r3,c4) (r4,c5) #buy arcs raw
(c1,p2) (c2,p3) (c3,p4) #sell arcs final
(c1,r2) (c2,r3) (c3,r4); #sell arcs raw
param b:= p1 2000 #ending final product on-hand
p4 2000; #initial final product on-hand
#specify costs, upper bound, and multipliers for each arc
param: c u mu l:=
[p1, p2] 1.30 3000 0.94 . #holding cost, capacity, 1-spoilage rate
[p2, p3] 1.30 3000 0.94 .
[p3, p4] 1.30 3000 0.94 .
[c1, c2] . . . . #final product period carry over cost
[c2, c3] . . . .
[c3, c4] . . . .
[c4, c5] . . . .
[r1, r2] 11 7500 0.45 . #raw material conversion
[r2, r3] 11 9000 0.45 .
[r3, r4] 11 8500 0.45 .
[p1, c2] . 3000 38 2000 #final price
[p2, c3] . 3000 40 2500
[p3, c4] . 5000 42 2800
[p4, c5] . 5000 42 2500
[c1, p2] . . -0.02631579 . #1/final price
[c2, p3] . . -0.025 .
[c3, p4] . . -0.02380952 .
[r1, c2] . 7500 0.4 . #raw price
[r2, c3] . 9000 0.4 .
[r3, c4] . 8500 0.333 .
[r4, c5] . 9200 0.286 .
[c1, r2] . . -2.5 . #1/raw price
[c2, r3] . . -2.5 .
[c3, r4] . . -3.0 .
[c5, c5p] -1 . 0 .; #virtual arc has negative cost to incentavize flow
I have posted my dat and mod files for reference. I know that the error is due somehow to the balance constraint but I am unsure why. I have tried to add min demand constraints but that seemed to make everything worse, I have tired redesigning the network flow chart multiple times and I've had no success. If anyone could provide some insight into why I can't figure this error out I would be extremely grateful.
With these messages, AMPL's presolve phase is telling you that your problem has no feasible solution: there is no way to assign values to the variables that are within the variables' bounds and that also satisfy all of the constraints. For a detailed analysis, see the reply to your question in the AMPL user forum.
I've been experiencing with GAMS but I still haven't got a clue what I'm doing.
Can someone take a look at this short model and try to point me in the right direction?
I have problems in the compilation at the equations, getting a few of these:
Dimension different - The symbol is referenced with more/less
indices as declared
Uncontrolled set entered as constant
Sets
i months / 1, 2, 3 /
j months / 1, 2, 3 /;
Parameters
cp(i) production cost in month i
/ 1 1.08
2 1.11
3 1.10
/
rh(i) number of necessary workers in month i
/ 1 3
2 4
3 6
/
cap(i) production capacity in month i
/ 1 25
2 20
3 25
/
q(j) number of motors to deliver in month j
/ 1 10
2 15
3 25
/
Scalar ca cost to store motors for a month /0.15/ ;
variables
mc(i,j) cost of production of motors in month i to be delivered in month j
x(i,j) number of motors produced in month i to be delivered in month j;
free variables
wf workforce
z cost of production
hr human resources;
Equations
cost cost
human_resources human resources
r1 restriction1
r2 restriction2 ;
cost .. z =e= sum((i,j), (cp(i)+(j-i)*ca)*x(i,j)) ;
human_resources .. hr =e= sum(i, sum(j, rh(i)*x(i, j))) ;
*lower than
r1.. sum(j, x(i,j)) =l= cap(i) ;
*greater than
r2.. sum(i, x(i,j)) =g= q(j) ;
Model
motors 'temp' /all/;
Solve motors using mip minimizing mc;
Display mc, x;
This works but check the solution. I added the positive variable x because otherwise you would have negative productions.
The main problem was the fact that you were optimizing a variable that is declared but that you never use in the equations. Also, the variable you are optimizing cannot have to dimensions (I think).
Then, for constraints r1 and r2 you need to add an index because they must be verified for each month, so r1(i) and r2(j). They are actually a "family of constraints".
You cannot subtract the indexes of the months (can't explain why), but you can subtract their order in the set.
And finally, calculate the mc(i,j) as a parameter after you have obtained the solution.
Sets
i months / 1, 2, 3 /
j months / 1, 2, 3 /;
Parameters
cp(i) production cost in month i
/ 1 1.08
2 1.11
3 1.10
/
rh(i) number of necessary workers in month i
/ 1 3
2 4
3 6
/
cap(i) production capacity in month i
/ 1 25
2 20
3 25
/
q(j) number of motors to deliver in month j
/ 1 10
2 15
3 25
/
Scalar ca cost to store motors for a month /0.15/ ;
variables
* mc(i,j) cost of production of motors in month i to be delivered in month j
x(i,j) number of motors produced in month i to be delivered in month j;
positive variable x;
free variables
wf workforce
z cost of production
hr human resources;
Equations
cost cost
human_resources human resources
r1(i) restriction1
r2(j) restriction2 ;
cost .. z =e= sum((i,j), (cp(i)+(ord(j)-ord(i))*ca)*x(i,j)) ;
human_resources .. hr =e= sum(i, sum(j, rh(i)*x(i, j))) ;
*lower than
r1(i).. sum(j, x(i,j)) =l= cap(i) ;
*greater than
r2(j).. sum(i, x(i,j)) =g= q(j) ;
Model
motors 'temp' /all/;
Solve motors using mip minimizing z;
Parameter mc(i,j);
mc(i,j)= (cp(i)+(ord(j)-ord(i))*ca)*x.l(i,j);
Display mc, x.l;
I have recently been introduced to AMPL in a class and I am currently working on an optimization problem that requires me to find the minimal cost for the demands required. The actual lines I have in question are these:
1. This is in my model file:
minimize Total_Cost:
sum{i in GENS, j in LOADS} cost[i,j] * Allocate[i,j];
subject to GenConst {i in GENS}:
sum {j in LOADS} Allocate[i,j] <= Generation[i];
subject to DemConst {j in LOADS}:
sum {i in GENS} Allocate [i,j] >= Demand[j];
in my data file:
param: GENS:
GenerationMin GenerationMax := #defines set "GENS" and param "Generation"
GEN1 10 90
GEN2 10 100
GEN3 5 85 ;
We have only ever worked with having problems where our demand=generation, but none with having minimum, maximum along with demand != supply. I get the following error when running my data file within ampl GenerationMin is not a subscripted param . When running this script with only the max value it runs fine. The issue, and I am only guessing, are with the lines above. Could someone explain to me where I am going wrong and how to fix this issue?
EDIT: I can include all of my code, although in case anyone wants to reproduce the problem. .mod file:
set GENS;
set LOADS;
param Generation {GENS} >=0;
param Demand {LOADS} >=0;
param cost {GENS, LOADS} >= 0;
var Allocate {GENS, LOADS} >= 0; #{GEN1, LOAD1}, {GEN1, LOAD2... etc}
minimize Total_Cost:
sum{i in GENS, j in LOADS} cost[i,j] * Allocate[i,j];
subject to GenConst {i in GENS}:
sum {j in LOADS} Allocate[i,j] <= Generation[i];
subject to DemConst {j in LOADS}:
sum {i in GENS} Allocate [i,j] >= Demand[j];
.data file:
data;
param: GENS:
GenerationMin GenerationMax := #defines set "GENS" and param "Generation"
GEN1 10 90
GEN2 10 100
GEN3 5 85 ;
param: LOADS: Demand := #Defining set "LOADS" and param "Demand"
Load1 70
Load2 20
Load3 30
Load4 60;
param cost:
Load1 Load2 Load3 Load4 :=
GEN1 39 14 11 14
GEN2 27 9 12 9
GEN3 24 14 17 13;
option solver cplex;
solve;
display Allocate;
display Allocate, Total_Cost > Output.txt
The correct AMPL syntax is:
set GENS;
param GenerationMin {GENS} >=0;
param GenerationMax {GENS} >=0;
data;
param: GENS:
GenerationMin GenerationMax :=
GEN1 10 90
GEN2 10 100
GEN3 5 85 ;
display GENS,GenerationMin,GenerationMax;
i.e. use both GenerationMin,GenerationMax in the model and in the data section.
I am trying to learn Julia for educational purposes. Specially, I trying to use Julia and the package JuMP to solve operational research problems.
I was watching this great video from youtube. A guy, named Philip Thomas, shows a didatic example. However, this video was produced in 2014. Since then, Julia has evolved.
He used this code:
#=
We are going to the thrift store and need 99 cents. What is the least amount of
weight we need to carry?
i.e. a knapsack problem
We specify that you need at least 99 cents - does the answer change if you need exact change?
=#
using JuMP
using Cbc # Open source solver. Must support integer programming.
m = Model(solver=CbcSolver())
# Variables represent how many of each coin we want to carry
#defVar(m, pennies >= 0, Int)
#defVar(m, nickels >= 0, Int)
#defVar(m, dimes >= 0, Int)
#defVar(m, quarters >= 0, Int)
# We need at least 99 cents
#addConstraint(m, 1 * pennies + 5 * nickels + 10 * dimes + 25 * quarters >= 99)
# Minimize mass (Grams)
# (source: US Mint)
#setObjective(m, Min, 2.5 * pennies + 5 * nickels + 2.268 * dimes + 5.670 * quarters)
# Solve
status = solve(m)
println("Minimum weight: ", getObjectiveValue(m), " grams")
println("using:")
println(round(getValue(pennies)), " pennies") # "round" to cast as integer
println(round(getValue(nickels)), " nickels")
println(round(getValue(dimes)), " dimes")
println(round(getValue(quarters)), " quarters")
His code returns this result:
Minimum weight: 22.68 grams
using:
0.0 pennies
0.0 nickels
0.0 dimes
4.0 quarters
I am using the current version of Julia (1.0). Moreover, I am using the current version of JUMP. There are syntactic differences between the current version of Julia and the code above. After some trial and error, I was able to properly translate the code to make it run in Julia 1.0:
#=
We are going to the thrift store and need 99 cents. What is the least amount of
weight we need to carry?
i.e. a knapsack problem
We specify that you need at least 99 cents - does the answer change if you need exact change?
=#
using JuMP
using GLPK
using Cbc # Open source solver. Must support integer programming.
model = Model(with_optimizer(GLPK.Optimizer))
# Variables represent how many of each coin we want to carry
#variable(model, pennies >= 0, Int)
#variable(model, nickels >= 0, Int)
#variable(model, dimes >= 0, Int)
#variable(model, quarters >= 0, Int)
# We need at least 99 cents
#constraint(model, 1 * pennies + 5 * nickels + 10 * dimes + 25 * quarters >= 99)
# Minimize mass (Grams)
# (source: US Mint)
#objective(model, Min, 2.5 * pennies + 5 * nickels + 2.268 * dimes + 5.670 * quarters)
# Solve
optimize!(model)
println("Minimum weight: ", objective_value(model), " grams")
println("using:")
println(round(value(pennies)), " pennies") # "round" to cast as integer
println(round(value(nickels)), " nickels")
println(round(value(dimes)), " dimes")
println(round(value(quarters)), " quarters")
The interesting thing is the result the terminal returned:
Minimum weight: 22.68 grams
using:
0.0 pennies
0.0 nickels
0.0 dimes
4.0 quarters
As you can see, the final result concerning the minimum weight remains the same. However, the decision about what coin to get changes from 10 dimes to 4 quarters.
Besides the syntactic changes, I modified the solver because, initially, I was not being able to run Cbc.
After that, I changed again to Cbc with this simple modification:
model = Model(with_optimizer(Cbc.Optimizer))
After the modification above the "code translation" was closer to the original with Cbc as the chosen solver. Curiously, the program returns the expected result:
Minimum weight: 22.68 grams
using:
0.0 pennies
0.0 nickels
10.0 dimes
0.0 quarters
However, I am still confused. According to the documentation both solvers can solve MILP (Mixed Integer Linear Problems).
Why this happens? Why different solvers return different results if they both have a similar profile? Did I miss some detail during the code translation?
Thanks in advance.
As you already discovered the value of the target function is the same for both solutions. Which solution is reached depends on the path that the solver went through to reach it.
Differences in the path may arise in the Simplex optimizer used to solve individual LP subproblems. Switching the sequence of variables or rows may be sufficient to end up in another point of the solution set. Some solver even use a random number generator to determine which variable enters the base in the Simplex algorithm first (but not GLPK).
Another reason for reaching a different solution may be the sequence in which the search tree for the integer variables is searched. This is influenced amongst others by the search strategy (e.g. depth first vs breadth first).
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