temp(k) = and(u(k),not(u(k-1));
c(k)=p(k)*u(k)+c_arranque*p(k)*temp(k));
What do you mean with fails?
If Mosek obtains a solution u(k)=8e-17, the expression and(u(k),not(u(k-1)) is surely 0.
>> u=8e-17
u =
8.0000e-17
>> and(u,1)
ans =
1
>>
temp1 = binvar(1,n);
temp2 = binvar(1,n);
...
temp1(k) = and(u(k),not(u(k-1));
c(k)=p(k)*u(k)+c_arranque*p(k)*temp1(k));
% Add to you list of constraints
Constraints = [Constraints, temp2(k) == temp1(k)]
% solve the problem
%and now look at the and operator value, i.e, this is the value the solver actually worked with
% when modelling and
value(temp2(k))
% This is not necessarily same as
and(value(u(k)),value(u(k-1))
since any numerical noise on the variables can destroy the logic
binvar a b
optimize(false(and(a,b)))
optimize([c <= a, c <= b, c >= a + b -1, c == 0])
and(value(a),value(b))
value(and(a,b))
binvar a b temp
optimize([false(and(a,b)),and(a,b) == temp])
and(round(value(a)),round(value(b)))
temp(k)=round(and(u(k),not(u(k-1))));
c(k)=p(k)*u(k)+c_arranque*p(k)*temp(k);
temp(k)=and(round(value(u(k))),round(not(u(k-1))));
c(k)=p(k)*u(k)+c_arranque*p(k)*temp(k);
Error using sdpvar/model (line 63)
Failed when trying to create a model for the "round" operator
Error in expandrecursive (line 19)
[properties,F_graph,arguments,fcn] =
model(variable,method,options,allExtStruct(ext_index),w);
Error in expandrecursive (line 206)
[F_expand,failure,cause] =
expandrecursive(recover(expressionvariables(i)),F_expand,extendedvariables,monomtable,variabletype,where,level+1,options,'exact',[],'none',allExtStruct,w);
Error in expandmodel>expand (line 376)
[F_expand,failure,cause] =
expandrecursive(recover(variables(i)),F_expand,extendedvariables,monomtable,variabletype,where,level+1,options,method,[],'convex',allExtStruct,w);
Error in expandmodel (line 209)
[F_expand,failure,cause] =
expand(index_in_extended,variables,h,F_expand,extendedvariables,monomtable,variabletype,'objective',0,options,method,[],allExtStructs,w);
Error in compileinterfacedata (line 116)
[F,failure,cause,operators] = expandmodel(F,h,options);
Error in solvesdp (line 251)
[interfacedata,recoverdata,solver,diagnostic,F,Fremoved,ForiginalQuadratics]
=
compileinterfacedata(F,[],logdetStruct,h,options,0,solving_parametric);
Error in optimize (line 31)
varargout{:} = solvesdp(varargin{:});
Error in PTAR_binvar_resthoras2 (line 50)
sol=optimize(rest,obj,opciones)
temp(k)=and(round(u(k)),round(not(u(k-1))));
c(k)=p(k)*u(k)+c_arranque*p(k)*temp(k);
u = sdpvar(3,1);
k = 2;
temp(k)=and(round(value(u(k))),round(not(u(k-1))))
Nonlinear matrix variable 1x2 (full, real, binary, 1 variable, values in range [0,1])
binvar a b
optimize(round(a) == b)
binvar a b
intvar c
optimize([c == b, a-0.5 <= c <= a + 0.5])
poolh=[30.01 25.05 20.43 13 12.4 16.5 26.11 43 40 48 44 39.6 38.4 34.51 28.63 28.6 34.2 37.08 37.59 48.8 51.48 43.1 38.55 37.33];
n=max(size(poolh)); %datos por día
MWsoplantes=0.5; %Dos soplantes de 250 kW según manual
precioh=poolh+48.371-0.5-0.07*(poolh+48.371); %MWh
p=MWsoplantes*precioh; %precio de tener en marcha las soplantes cada hora
%Constantes
e=1.5*ones(1,n); %Tasa máxima de eliminación de amonio con soplantes al máximo
d=2*ones(1,n); %Pendiente de incremento de amonio si no se airea. Función del flujo de amonio entrada
x_ini=9; %Amonio inicial
%Restricciones
hsin=4; %Número de horas máximas sin soplar
c_arranque=2; %Coeficiente de consumo eléctrico extra por arranque (% de potencia extra consumida)
xlimit=10; %Amonio máximo permitido
% Optimizar u
u=binvar(1,n-1);
x=sdpvar(1,n);
horas_sin=sdpvar(1,n);
temp=binvar(1,n-1);
for k=1:n-1
x(k+1)=0.85*x(k)+d(k)-e(k)*u(k); %Evolución del estado
if k>1
%temp(k)=round(and(u(k),not(u(k-1))));
temp(k)=and(round(u(k)),round(not(u(k-1))));
c(k)=p(k)*u(k)+c_arranque*p(k)*temp(k);
else
%temp(k)=round(u(k));
c(k)=p(k)*(1+c_arranque)*u(k);
end
if k>=hsin+1 %Bucle para contar horas seguidas sin soplar
horas_sin(k)=0;
for j=1:hsin+1
horas_sin(k)=horas_sin(k)+u(k-j+1);%Variable "hsin" últimas horas (sin soplar)
end
end
end
rest=[x(1)==x_ini, x<=xlimit , x>=0, horas_sin>=1];
obj=ones(1,n-1)*c';
opciones=sdpsettings('solver','mosek','verbose',0);
sol=optimize(rest,obj,opciones)
>> optimize(rest, obj)
Error using sdpvar/model (line 63)
Failed when trying to create a model for the "round"
operator
and(u(k),not(u(k-1)))
For exemple, execute the next code. The solution of the variable "cost" change if you use the two different lines of code for temp(k) (first one is now commented). The right solution (the one who does what I need) is the one that I get with the second line (using round). If I don't use round, you can see in the figure that the first green column is not so tall.
clear all
clc
tic
%Datos costes, pool
poolh=[30.01 25.05 20.43 13 12.4 16.5 26.11 43 40 48 44 39.6 38.4 34.51 28.63 28.6 34.2 37.08 37.59 48.8 51.48 43.1 38.55 37.33];
n=max(size(poolh)); %datos por día
MWsoplantes=0.5; %Dos soplantes de 250 kW según manual
precioh=poolh+48.371-0.5-0.07*(poolh+48.371); %MWh
p=MWsoplantes*precioh; %precio de tener en marcha las soplantes cada hora
%Constantes
e=1.5*ones(1,n); %Tasa máxima de eliminación de amonio con soplantes al máximo
d=2*ones(1,n); %Pendiente de incremento de amonio si no se airea. Función del flujo de amonio entrada
x_ini=9; %Amonio inicial
%Restricciones
hsin=4; %Número de horas má
ximas sin soplar
c_arranque=0.2; %Coeficiente de consumo eléctrico extra por arranque (% de potencia extra consumida)
xlimit=10; %Amonio máximo permitido
% Optimizar u
u=binvar(1,n-1);
x=sdpvar(1,n);
horas_sin=sdpvar(1,n);
temp=binvar(1,n-1);
for k=1:n-1
x(k+1)=0.85*x(k)+d(k)-e(k)*u(k); %Evolución del estado
if k>1
%temp(k)=and(u(k),not(u(k-1)));
temp(k)=round(and(u(k),not(u(k-1))));
c(k)=p(k)*u(k)+c_arranque*p(k)*temp(k);
else
%temp(k)=round(u(k));
c(k)=p(k)*(1+c_arranque)*u(k);
end
if k>=hsin+1 %Bucle para contar horas seguidas sin soplar
horas_sin(k)=0;
for j=1:hsin+1
horas_sin(k)=horas_sin(k)+u(k-j+1);%Variable "hsin" últimas horas (sin soplar)
end
end
end
rest=[x(1)==x_ini, x<=xlimit , x>=0, horas_sin>=1];
obj=ones(1,n-1)*c';
opciones=sdpsettings('solver','mosek','verbose
',0);
sol=optimize(rest,obj,opciones)
cs=double(c);
cost=ones(1,n-1)*cs'
toc
xs=double(x);
xlim=xlimit*ones(1,max(size(xs)));
us=round(double(u));
clf
stairs(p,'k')
hold on
plot(xs,'b')
hold on
plot(xlim,'b --')
hold on
stairs(cs,'g')
hold on
stairs(us,'r')
legend('Precio EE','Concentración amonio', 'Concentración máx','Coste','Soplantes')
grid
assign(u,round(value(u)));
clear x
clear c
clear temp
x = x_ini;
u = round(value(u));
for k=1:n-1 x(k+1)=0.85*x(k)+d(k)-e(k)*u(k); %Evolución del estado if k>1
temp(k)=(and(u(k),not(u(k-1))));
% Restricción de horas sin soplar. Incremento en el coste de arranque
clear all
clc
tic
%Datos costes, pool
poolh=[30.01 25.05 20.43 13 12.4 16.5 26.11 43 40 48 44 39.6 38.4 34.51 28.63 28.6 34.2 37.08 37.59 48.8 51.48 43.1 38.55 37.33];
n=max(size(poolh)); %datos por día
MWsoplantes=0.5; %Dos soplantes de 250 kW según manual
precioh=poolh+48.371-0.5-0.07*(poolh+48.371); %MWh
p=MWsoplantes*precioh; %precio de tener en marcha las soplantes cada hora
%Constantes
e=1.5*ones(1,n); %Tasa máxima de eliminación de amonio con soplantes al máximo
d=2*ones(1,n); %Pendiente de incremento de amonio si no se airea. Función del flujo de amonio entrada
x_ini=9; %Amonio inicial
%Restricciones
hsin=4; %Número de horas máximas sin soplar
c_arranque=0.2; %Coeficiente de consumo eléctrico extra por arranque (% de potencia extra consumida)
xlimit=10; %Amonio máximo permitido
% Optimizar u
u=binvar(1,n-1);
x=sdpvar(1,n);
horas_sin=sdpvar(1,n);
temp=binvar(1,n-1);
rest=[];
for k=1:n-1
x(k+1)=0.85*x(k)+d(k)-e(k)*u(k); %Evolución del estado
if k>1
%temp(k)=and(u(k),not(u(k-1)));
%temp(k)=round(and(u(k),not(u(k-1))));
c(k)=p(k)*u(k)+c_arranque*p(k)*temp(k);
rest=[rest, temp(k)==and(u(k),not(u(k-1)))];
else
c(k)=p(k)*(1+c_arranque)*u(k);
rest=[rest, temp(k)==u(k)];
end
if k>=hsin+1 %Bucle para contar horas seguidas sin soplar
horas_sin(k)=0;
for j=1:hsin+1
horas_sin(k)=horas_sin(k)+u(k-j+1);%Variable "hsin" últimas horas (sin soplar)
end
end
end
rest=[rest, x(1)==x_ini, x<=xlimit , x>=0, horas_sin>=1];