Splitting GAMS equation using if else statements - variables

I have a working GAMS optimization model using LP. I want to modify one of my equations so that it excludes one of the terms when t = 1. Here's the simplification of this problem:
Set t "time in hours" / 1 * 8760/ ;
If t = 1:
vDemand(t) =e= p1*(vInternal(t) - pAmbient(t))
else:
vDemand(t) =e= p1*(vInternal(t) - pAmbient(t)) + p2*(vInternal(t) - vInternal(t-1))
How do I modify this vDemand equation while keeping my optimization linear?
I looked up and tried the different ways to incorporate conditional statements on GAMS, but not successful so far.

vDemand(t) =e= p1*(vInternal(t) - pAmbient(t)) + (p2*(vInternal(t) - vInternal(t-1)))$(ord(t)>1);
The $ condition at the end of the second term makes sure, that that part is only used, if it is not the first element of the set t.

Related

Solving GAMS optimization for a specific range within a set

I'm trying to solve an optimization problem on GAMS, but only for a subset. Right now, i have a code that optimizes for all the elements of set t:
t time in hours / 1 * 8760 /
How do I run the optimization only for t from 1 to 3500, AND from 6500 to 8760 (for example)? FYI, all of my parameters data (from .csv) that i imported to GAMS have 8760 values. Here's a simple objective function to use:
eObjFunc.. vZ =e= sum(t, v1(t));
The simplest way I could think of is to edit all my .csv data so they only have the t values that I care for. In this case, define set t = 1 to 3500, 6500 to 8760. Then, just run the optimization.
However, I'm sure there's a smarter way to do this without having to modify my .csv data...
Really appreciate your help!
You can define subsets like this (assuming t is defined already as 1*8760):
Set tt(t) /1*3500, 6500*8760/;
And then use tt instead of t in your equation:
eObjFunc.. vZ =e= sum(tt, v1(tt));

pyomo: minimal production time / BIG M

I am looking for a way to map a minimum necessary duty cycle in an optimization model.
After several attempts, however, I have now reached the end of my knowledge and hope for some inspiration here.
The idea is that a variable (binary) mdl.ontime is set so that the sum of successive ontime values is greater than or equal to the minimum duty cycle:
def ontime(mdl,t):
min_on_time = 3 # minimum on time in h
if t < min_on_time: return mdl.ontime[t] == 0
return sum(mdl.ontime[t-i] for i in range(min_on_time)) >= min_on_time
That works so far, if the variable mdl.ontime will not be recognized at all.
Then I tried three different constraints, unfortunately they all gave the same result: CPLEX only finds inf. results.
The first variant was:
def flag(mdl,t):
return mdl.ontime[t] + (mdl.production[t]>=0.1) >= 2
So if mdl.ontime is 1 and mdl.production is greater or equal 0.1 (the assumption is just exact enough), it should be greater or equal 2: a logical addition therm.
The second attemp was quite similar to the first:
def flag(mdl,t):
return (mdl.ontime[t]) >= (mdl.production[t] >= 0.1)
If mdl.ontime is 1, it should be greater or equal mdl.production compared with 0.1.
And the third with a big M variable:
def flag(mdl,t):
bigM = 10**6
return mdl.ontime[t] * bigM >= mdl.production[t]
bigM instead should be great enough in my case...
All of them do not work at all...and I have no idea, why CPLEX returns the error that there is only an infeasible solution.
Basically the model runs if I don't consider the ontime-integration.
Do you guys have any more ideas how I could implement this?
Many greetings,
Mathias
It isn't real clear what the desired relationship is between your variables/constraints. That said, I don't think this is legal. I'm surprised that it isn't popping an error....and if not popping an error, I'm pretty sure it isn't doing what you think:
def flag(mdl,t):
return mdl.ontime[t] + (mdl.production[t]>=0.1) >= 2
You are essentially burying an inferred binary variable in there with the test on mdl.production, which isn't going to work, I believe. You probably need to introduce another variable or such.

My smax function is not working properly even though execution of nload is right

I can not find the answer by myself and therefore I'm asking you. I'm trying to modify the input load subject to two different price range. It goes well I receive answers on nload, however when it comes to find the maximum value it doesn't work. I have even replaced smax with an number, but the output answer is being strange...
Con3(d,hpd).. ndload(d,hpd) =E= odload(d,hpd)*(1+sum(hpd1,PRICE_EL(hpd,hpd1)*(P_H(hpd1)-PH_OLD)/PH_OLD));
Con4(hpd)$((ord(hpd)>15)and(ord(hpd)<23)).. P_H(hpd) =E= PHP;
Con5(hpd)$((ord(hpd)<16)or(ord(hpd)>22)).. P_H(hpd) =E= PLP;
Con6.. E_NEW =E= sum((d,hpd),ndload(d,hpd)) ;;
Con7.. LF_NEW =E= sum(d,NDLF(d))/1;
Con8(d).. NDLF(d) =E= sum(hpd,ndload(d,hpd))/(smax(hpd,ndload(d,hpd))*24);

Maxima doesn't find a solution for diff eq with desolve

During my exercise with wxmaxima 11.08.0 (ubuntu 12.04, Maxima version: 5.24.0)
I followed an example from P.Lutus and his second example didn't work for me.
eq: y(t) = -r*c*'diff(y(t),t)+m*sin(%omega*t);
sol:desolve( eq, y(t) );
Is %omega zero or nonzero? nonzero
then Maxima isn't reacting anymore until I restart it.
Is there something changed in maxima that I need to activate or define first to get the result ?
The expected output should be:
There is a second part of my question in case I define the equation by hand:
sol: y(t) = (m * sin(%omega*t)) / (%omega^2*c^2*r^2 + 1) -
(%omega*c*m*r*cos(%omega*t)) / (%omega^2*c^2*r^2 + 1) +
(%omega*c*m*r*%e^-((1*t)/(c*r))) / (%omega^2*c^2*r^2 + 1);
Initial conditions for a continuous process:
init_val:-(c*m*r*(%e^-(t/r*c))*%omega)/(c^2*r^2*%omega^2+1);
atvalue(y(t),t=0, init_val);
try2 : desolve(sol,y(t));
"Is "%omega" zero or nonzero?" nonzero;
Here the last term is still there. Are these problems based on the use of trigonometric functions ?
Best regards,
Marcus
I updated via PPA to wxMaxima 13.04.0 & Maxima 5.29.1. Now desolve fnished, but the last term seems very complicated.
Doing the init_val with the negativ last term and desolve command still leaves the %e^(..)*... in the equation.
You might get more interest in this question on the Maxima mailing list. See: http://maxima.sourceforge.net/maximalist.html
For the first version of Lutus example 2, I get:
y(t) = m*sin(%omega*t)/(%omega^2*c^2*r^2+1)
-%omega*c*m*r*cos(%omega*t)/(%omega^2*c^2*r^2+1)
+(y(0)*%omega^2*c^3*r^3+%omega*c^2*m*r^2+y(0)*c*r)*%e^-(t/(c*r))
/(c*r*(%omega^2*c^2*r^2+1))$
which is the same as the expected result, if y(0) = 0. However, I don't see where that is assumed.
After atvalue(y(t),t=0,init_val), I get the same result as Lutus, namely:
y(t) = m*sin(%omega*t)/(%omega^2*c^2*r^2+1)
-%omega*c*m*r*cos(%omega*t)/(%omega^2*c^2*r^2+1)$
I am working with Maxima 5.31.1, built with Clisp, on Linux.

Best way solving optimization with multiple variables in Matlab?

I am trying to compute numerically the solutions for a system of many equations and variables (100+). I tried so far three things:
I now that the vector of p(i) (which contains most of the endogenous variables) is decreasing. Thus I gave simply some starting points, and then was increasing(decreasing) my guess when I saw that the specific p was too low(high). Of course this was always conditional on the other being fixed which is not the case. This should eventually work, but it is neither efficient, nor obvious that I reach a solution in finite time. It worked when reducing the system to 4-6 variables though.
I could create 100+ loops around each other and use bisection for each loop. This would eventually lead me to the solution, but take ages both to program (as I have no idea how to create n loops around each other without actually having to write the loops - which is also bad as I would like to increase/decrease the amount of variables easily) and to execute.
I was trying fminsearch, but as expected for that wast amount of variables - no way!
I would appreciate any ideas... Here is the code (this one the fminsearch I tried):
This is the run file:
clear all
clc
% parameter
z=1.2;
w=20;
lam=0.7;
tau=1;
N=1000;
t_min=1;
t_max=4;
M=6;
a_min=0.6;
a_max=0.8;
t=zeros(1,N);
alp=zeros(1,M);
p=zeros(1,M);
p_min=2;
p_max=1;
for i=1:N
t(i)= t_min + (i-1)*(t_max - t_min)/(N-1);
end
for i=1:M
alp(i)= a_min + (i-1)*(a_max - a_min)/(M-1);
p(i)= p_min + (i-1)*(p_max - p_min)/(M-1);
end
fun=#(p) david(p ,z,w,lam,tau,N,M,t,alp);
p0=p;
fminsearch(fun,p0)
And this is the program-file:
function crit=david(p, z,w,lam,tau,N,M,t,alp)
X = zeros(M,N);
pi = zeros(M,N);
C = zeros(1,N);
Xa=zeros(1,N);
Z=zeros(1,M);
rl=0.01;
rh=1.99;
EXD=140;
while (abs(EXD)>100)
r1=rl + 0.5*(rh-rl);
for i=1:M
for j=1:N
X(i,j)=min(w*(1+lam), (alp(i) * p(i) / r1)^(1/(1-alp(i))) * t(j)^((z-alp(i))/(1-alp(i))));
pi(i,j)=p(i) * t(j)^(z-alp(i)) * X(i,j)^(alp(i)) - r1*X(i,j);
end
end
[C,I] = max(pi);
Xa(1)=X(I(1),1);
for j=2:N
Xa(j)=X(I(j),j);
end
EXD=sum(Xa)- N*w;
if (abs(EXD)>100 && EXD>0)
rl=r1;
elseif (abs(EXD)>100 && EXD<0)
rh=r1;
end
end
Ya=zeros(M,N);
for j=1:N
Ya(I(j),j)=t(j)^(z-alp(I(j))) * X(I(j),j)^(alp(I(j)));
end
Yi=sum(Ya,2);
if (Yi(1)==0)
Z(1)=-50;
end
for j=2:M
if (Yi(j)==0)
Z(j)=-50;
else
Z(j)=(p(1)/p(j))^tau - Yi(j)/Yi(1);
end
end
zz=sum(abs(Z))
crit=(sum(abs(Z)));
First of all my recommendation: use your brain.
What do you know about the function, can you use a gradient approach, linearize the problem, or perhaps fix most of the variables? If not, think twice before you decide that you are really interested in all 100 variables and perhaps simplify the problem.
Now, if that is not possible read this:
If you found a way to quickly get a local optimum, you could simply wrap a loop around it to try different starting points and hope you will find a good optimum.
If you really need to make lots of loops (and a variable amount) I suppose it can be done with recursion, but it is not easily explained.
If you just quickly want to make a fixed number of loops inside each other this can easily be done in excel (hint: loop variables can be called t1,t2 ... )
If you really need to evaluate a function at a lot of points, probably creating all the points first using ndgrid and then evaluating them all at once is preferable. (Needless to say this will not be a nice solution for 100 nontrivial variables)