I am working on a so called Security Constrained Unit Commitment problem with several generators in a 24 hour period. This means that the decision variable stating the power production is a nx24 matrix, where n is the number of generators. Same concept goes for the other decision variables, as you can see in the code below. To solve this problem I use Yalmip together with the Knitro solver. I am using the Knitro solver because this problem is a mixed integer non linear problem (quadratic?). The unit commitment problem becomes non linear when optimal power flow is added to the optimization model.
There are 24 busses and 13 producing units.
My problem comes when I try to solve this model. It takes approximately 9000 seconds to solve this problem, and afterwards it comes up with a message saying "Optimal solution found".
Therefore the problem is not that the model is infeasible etc. The problem is the solving time.
Is this due to my Matlab code, or just a result of the non linearity coupled with binary decision variables?
In order to give some background for answers, the optimization code itself can be seen below.
In advance thank you for anwers. They are much appreciated.
%% Decision variables
% Creaing binary variables defined for turning on and off the engines
GenOnOff = binvar(NumGenUnits,h+1,'full'); % If 1 generation unit is on else off
% Creating variables that define the production of each unit
GenActivePowerProduction = sdpvar(NumGenUnits,h,'full');
GenReactivePowerProduction = sdpvar(NumGenUnits,h,'full');
GenEfficiency = sdpvar(NumGenUnits,h,'full');
% Creating binvar variables that defines each time a unit is started
GenStart = binvar(NumGenUnits,h,'full');
GenStop = intvar(NumGenUnits,h,'full');
% Creating variables defining the SOC, Charge and discharge
SOC = sdpvar(NumBatUnits,h+1,'full');
Charge = sdpvar(NumBatUnits,h,'full');
DisCharge = sdpvar(NumBatUnits,h,'full');
BinCharge = binvar(NumBatUnits,h,'full');
% Creating Network values variables load flow constraints
CapBankON = binvar(NumCapBanks,h,'full');
BusVoltage = sdpvar(NumBus,h,'full');
VoltageAngles = sdpvar(NumBus,h,'full');
RefBus = 1;%intvar(1,1);
%% Set up Constraint
constraints = [];
constraints = [constraints, GenOnOff(:,1) == 0];
for t = 1:24
% Battery constraints
constraints = [constraints, ((1-BatDOD)*BatMaxCapacity) <= SOC(:,t+1) <= BatMaxCapacity];
constraints = [constraints, 0 <= Charge(:,t) <= (BatCRate*BatMaxCapacity.*BinCharge(:,t))./Sbase];
constraints = [constraints, 0 <= DisCharge(:,t) <= (BatCRate*BatMaxCapacity.*(1-BinCharge(:,t)))./Sbase];
constraints = [constraints, SOC(:,t+1) == SOC(:,t)-DisCharge(:,t).*Sbase+Charge(:,t).*Sbase];
% Generator constraints
constraints = [constraints, abs(GenActivePowerProduction(:,t)+1i*GenReactivePowerProduction(:,t)) <= (GenMaxCapacity.*GenOnOff(:,t+1))./Sbase];
constraints = [constraints, (GenMinProduction.*GenOnOff(:,t+1))./Sbase <= GenActivePowerProduction(:,t)];
constraints = [constraints, GenOnOff(:,t+1)-GenOnOff(:,t) <= GenStart(:,t)];
constraints = [constraints, GenOnOff(:,t)-GenOnOff(:,t+1) == GenStop(:,t)];
for unit = 1:NumGenUnits
constraints = [constraints, GenOnOff(unit,t+1:min(h,t+GenMinUpTime(unit))) >= GenStart(unit,t)];
constraints = [constraints, GenOnOff(unit,t+1:min(h,t+GenMinDownTime(unit))) <= 1-GenStop(unit,t)];
end
% Network constraints
constraints = [constraints, (RenMatrix*RenProduction(t,:)')./Sbase+BatMatrix*DisCharge(:,t)-BatMatrix*Charge(:,t)+GenMatrix*(GenActivePowerProduction(:,t).*GenEfficiency(:,t))-PDemandMatrix(:,t) == real((BusVoltage(:,t).*exp(1i*VoltageAngles(:,t))).*conj(Ybus* (BusVoltage(:,t).*exp(1i*VoltageAngles(:,t)))))];
constraints = [constraints, GenMatrix*GenReactivePowerProduction(:,t)+CapBankMatrix*(CapBank.*CapBankON(:,t)./Sbase)-QDemandMatrix(:,t) == imag((BusVoltage(:,t).*exp(1i*VoltageAngles(:,t))).*conj(Ybus*(BusVoltage(:,t).*exp(1i*VoltageAngles(:,t)))))];
constraints = [constraints, 0.95 <= BusVoltage(:,t) <= 1.05];
constraints = [constraints, VoltageAngles(RefBus,t) == 0];
% N-1 criteria or 10% spinning reserve
constraints = [constraints, max(sum((RenMatrix*RenProduction(t,:)')./Sbase+sum(BatMatrix*DisCharge(:,t)-BatMatrix*Charge(:,t))+sum(GenMatrix*(GenActivePowerProduction(:,t))))*0.1,max(GenActivePowerProduction(:,t))) <= sum((GenMaxCapacity./Sbase- GenActivePowerProduction(:,t)).*GenOnOff(:,t+1))];
end
%% Define objective function
ObjGenProductionCosts = sum(sum(GenActivePowerProduction,2).*(GenMargProdCost+GenEmissionFactor));
ObjGenStartUpCosts = sum(sum(GenStart,2).*GenStartUpCost);
Objective = ObjGenProductionCosts + ObjGenStartUpCosts;