How do I input linear constraints for the genetic algorithm function using discrete variables?
Show older comments
Hello,
I am using the matlab's ga algorithm to solve an optimization problem using discrete variables. My decision variable is set to take only integer values, then using a simple mapping function, my decision variable are transformed to the n'th indexed value in a list of specific values which i provide, where n is the integer value initially assigned to the decision variable. I followed the exact steps of the following link:
Within this link, they inputed non-linear constraints using a function. In my case, I am interested in inserting linear constraints of inequality, using the matrices A and b. The algorithm seems to not respect these constraints. This is possible because the algorithm is applying the constraints to the decision variables in the form of integers rather than their transformed form.
How should I inser the A and b matrices in such a scenario?
Thank you.
19 Comments
Torsten
on 14 Jul 2023
Where do you use the integer decision variables in their transformed form ?
Samer Alsamadi
on 14 Jul 2023
If you don't use nonlinear equality constraints together with the integer decision variables in function "nonlcon", I don't know why the procedure you describe should not work.
But of course we cannot give further advice without code that reproduces the behaviour you describe. What MATLAB version are you using ?
Samer Alsamadi
on 14 Jul 2023
Samer Alsamadi
on 14 Jul 2023
Torsten
on 14 Jul 2023
I don't recall reading anywhere that the ga function with discrete variables can not be given linear constraints. Maybe I'm missing something here?
You can use linear constraints, but I think if you put them in A and b, it's not guaranteed that they are respected during the solution process. The final result should of course respect them, though.
This is different if you use lower and upper bounds: as far as I can remember, they are respected throughout the complete solution process. And I thought this is what you were asking for, weren't you ?
Samer Alsamadi
on 15 Jul 2023
Walter Roberson
on 15 Jul 2023
I don't think you can do what you want in your version, except by enforcing all of the integer constraints yourself after telling ga() that you are not using any integer constraints.
The A and b matrix constraints however were intended for the transformed form of the decision variables. These were not respected.
It is not possible to constrain the transformed variables with A and b. With A and b, you can only constrain solution variables. But the solution variables are the decision integers, not the deduced transformed variables.
You have to define the nonlinear inequality constraints on the transformed variables in "nonlcon".
But I don't understand why you wrote the constraints look like
x(1) >= t_ar(1), x(2) >= t_ar(2)
Aren't x(1), x(2) the integer decision variables and t_ar(1), t_ar(2) some fixed constants known right from the beginning of the computation ?
I just see in your code that you work with random inputs that change during each iteration. This is stochastic optimization and not possible with the usual MATLAB optimizers.
clear all
clc
rng('default') % For reproducibility
N = 10; % Nbr of electric vehicles
eta = 0.9;
C = 50; %kWh
P_ev = 8; %kWh
SoC_i = [0.5, 0.4, 0.6, 0.8, 0.1, 0.2, 0.5, 0.85, 0.55, 0.35];
SoC_f = 1;
time_step = 0.25; % 15 min. planning interval
delta_xi = zeros(1,10);
for i = 1:N
delta_xi_temp = ((SoC_f - SoC_i(i)) * C) / (eta * P_ev);
time_step = 0.25;
delta_xi(i) = ceil(delta_xi_temp / time_step) * time_step;
end
t_ar = [4,5,6,7,8,9,10,11,12,13];
t_dp = t_ar + 8;
A = diag(-1*ones(1,10)); % Arrival time inequality left side
b = [-t_ar(1);
-t_ar(2);
-t_ar(3);
-t_ar(4);
-t_ar(5);
-t_ar(6);
-t_ar(7);
-t_ar(8);
-t_ar(9);
-t_ar(10)]; % Arrival time inequality right side
lb = ones(1,10);
ub = 96*ones(1,10);
nvars = 10;
opts = optimoptions(@ga, ...
'PopulationSize', 150, ...
'MaxGenerations', 10, ...
'EliteCount', 10, ...
'FunctionTolerance', 1e-8, ...
'ConstraintTolerance',1.0000e-06, ...
'PlotFcn', @gaplotbestf);
[xbestDisc, fbestDisc, exitflag] = ga(@EVWithDisc, ...
10, A, b, [], [], lb, ub, [], 1:10, opts);
xbestDisc = EVMapVariables(xbestDisc);
xbestDisc >= t_ar
function cost = EVWithDisc(x)
%cantileverVolumeWithDisc Calculate volume of a stepped cantilever
%
% V = cantileverVolumeWithDisc(x) calculates the volume of the stepped
% cantilever in the "Solving a Mixed Integer Engineering Design Problem
% Using the Genetic Algorithm" example. In this function, the variables
% x(3), x(4), x(5) and x(6) are chosen from a discrete set.
% Copyright 2012 The MathWorks, Inc.
% Map the discrete variables
x = EVMapVariables(x);
% Volume of cantilever beam
cost = EV_fitness_func_(x);
end
function x = EVMapVariables(x)
all_X = 0:0.25:23.75;
x(1) = all_X(x(1));
x(2) = all_X(x(2));
x(3) = all_X(x(3));
x(4) = all_X(x(4));
x(5) = all_X(x(5));
x(6) = all_X(x(6));
x(7) = all_X(x(7));
x(8) = all_X(x(8));
x(9) = all_X(x(9));
x(10) = all_X(x(10));
end
function cost = EV_fitness_func_(chargingTimes)
rng('default')
a_t = 10 * rand(1,96);
N = 10; % Nbr of electric vehicles
eta = 0.9;
C = 50; %kWh
P_ev = 8; %kWh
SoC_i = [0.5, 0.4, 0.6, 0.8, 0.1, 0.2, 0.5, 0.85, 0.55, 0.35];
SoC_f = 1;
time_step = 0.25; % 15 minute time steps for planning
cost = 0;
delta_xi = zeros(1,10);
for i = 1:N
x_i = chargingTimes(i);
sum_internal = 0;
delta_xi(i) = ((SoC_f - SoC_i(i)) * C) / (eta * P_ev);
delta_xi(i) = ceil(delta_xi(i) / time_step) * time_step;
for t = x_i:0.25:x_i+delta_xi(i)
t_temp = t;
if t_temp > 23.75
t_temp = t_temp - 24;
end
index = (t_temp/0.25) + 1;
electricity_price = a_t(index);
sum_internal = sum_internal + P_ev * electricity_price * 0.25;
end
cost = cost + sum_internal;
end
end
Samer Alsamadi
on 17 Jul 2023
Torsten
on 17 Jul 2023
a_t and thus the electricity price change with each call to your cost function. So how should "ga" be able to get a stable deterministic solution to your problem ?
Samer Alsamadi
on 17 Jul 2023
Only the seed of the random generator is set to a specified value that remains constant each time you run the code. But if you call the random number generator several times within one program execution, the output changes:
rng("default")
rand()
rand()
rand()
Samer Alsamadi
on 17 Jul 2023
Torsten
on 17 Jul 2023
Inequality constraints on the transformed variables have to be set like this:
[xbestDisc, fbestDisc, exitflag] = ga(@EVWithDisc, ...
10, [],[], [], [], lb, ub, @nonlcon, 1:10, opts);
function [c,ceq] = nonlcon(x)
all_X = 0:0.25:23.75;
t_ar = [4,5,6,7,8,9,10,11,12,13];
n = numel(x);
x_trans(1:n) = all_X(x(1:n));
c = -x_trans + t_ar;
ceq = [];
end
Samer Alsamadi
on 17 Jul 2023
Your constraints are linear in the transformed variables, but not in the solution variables.
Or are you able to use A (which is multiplied by x, not x_trans) and b to set the constraints you want on x_trans ?
What you did in your code is setting x(1:10) >= t_ar(1:10), not x_trans(1:10) >= t_ar(1:10). And from what you wrote this is what you actually want, isn't it ?
Answers (0)
Categories
Find more on Linear Least Squares in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!