Dynamically generating an optimization problem

I'm an infrequent MatLab user, so when I need it I tend to find an example and tailor it to my problem. I followed that approach recently in building a constrained optimization model.
I wrote several functions for a) calculating values b) evaluating constraints and c) the objective function. My final script looked like this
x0 = [0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0];
lb = [0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0;
0,0,0,0,0];
%at work version -release returns 2014b, and then the options are
%MaxFunEvals, MaxIter
%or on some computers, its 2017a, and then the options are
%MaxFunctionEvaluations, MaxIterations
version = evalc('version -release');
if strcmp(version,'2017a')
options = optimoptions(@fmincon,'Algorithm','active-set','MaxFunctionEvaluations',100000,'MaxIterations',100000);
else
options = optimoptions(@fmincon,'Algorithm','active-set','MaxFunEvals',100000,'MaxIter',100000);
end
p = gcp('nocreate'); % If no pool, do not create new one.
if isempty(p)
parpool;
end
ms = MultiStart('UseParallel', true);
problem = createOptimProblem('fmincon','objective',@carry_forward_objective,'nonlcon',@turbulence_constraints,'x0',x0,'lb',lb,'options',options);
[x,fval] = run(ms,problem,100)
This has worked well, but note that the problem is hard-coded...it's the same with the referenced functions @carry_forward_objective and @turbulence_constraints. In this case there are 23 rows and 5 columns of decision variables.
My challenge now is to generalize the process so that I can read in a variable number of rows (there will always be 5 columns) from a file that defines a problem and set up the optimization. I can use xlsread to get the data in, but am unsure how to proceed programmatically creating the functions/handles required to set up the problem. Can anyone point me in the right direction?
Thanks!

13 个评论

By the way, you do not need the evalc(): you can use verLessThan()
It would be trivial to modify the above to read x0 and lb from a file, but I am not clear how the data you would read in would define the problem or change the functions ?
x0 and lb aren't really the issues, the constraint and objective functions are. For example, here is the basic constraint function
function [ c, ceq ] = base_constraints(X)
%base_constraints multi-year constraints function
% no turbulence
% matrix X is the decision variables (funding levels)
% matrix R is the requirements
R = [65.268, 52.444, 48.531, 63.806, 62.555;
0.453, 0.456, 0.456, 0.458, 0.449;
20.201, 17.852, 9.985, 8.788, 8.616;
19.580, 19.580, 19.580, 19.580, 19.580;
41.964, 56.609, 61.640, 40.717, 39.919;
100.985,95.939, 88.995, 77.450, 75.932;
2.752, 1.229, 1.211, 0.505, 0.495;
42.891, 51.856, 32.449, 15.496, 15.192;
7.344, 7.211, 7.080, 6.951, 6.814;
4.696, 13.811, 17.151, 19.470, 19.088;
16.905, 16.573, 17.151, 15.930, 15.618;
1.062, 1.041, 1.021, 1.092, 1.071;
5.836, 1.907, 14.959, 16.499, 16.176;
0.000, 6.628, 13.924, 13.651, 13.383;
2.817, 12.890, 19.859, 21.240, 20.823;
8.452, 0.000, 0.000, 0.000, 0.000;
4.696, 6.445, 7.222, 7.080, 6.941;
8.452, 8.287, 8.124, 8.850, 8.676;
0.939, 0.921, 0.903, 0.885, 0.868;
9.486, 13.820, 13.549, 13.284, 13.023;
33.400, 30.753, 30.150, 29.559, 28.979;
10.447, 14.183, 15.020, 16.355, 16.034;
26.848, 15.831, 5.142, 0.000, 0.000];
S=sum(X);
c = [X(1,1) - R(1,1);
X(2,1) - R(2,1);
X(3,1) - R(3,1);
X(4,1) - R(4,1);
X(5,1) - R(5,1);
X(6,1) - R(6,1);
X(7,1) - R(7,1);
X(8,1) - R(8,1);
X(9,1) - R(9,1);
X(10,1) - R(10,1);
X(11,1) - R(11,1);
X(12,1) - R(12,1);
X(13,1) - R(13,1);
X(14,1) - R(14,1);
X(15,1) - R(15,1);
X(16,1) - R(16,1);
X(17,1) - R(17,1);
X(18,1) - R(18,1);
X(19,1) - R(19,1);
X(20,1) - R(20,1);
X(21,1) - R(21,1);
X(22,1) - R(22,1);
X(23,1) - R(23,1);
X(1,2) - R(1,2);
X(2,2) - R(2,2);
X(3,2) - R(3,2);
X(4,2) - R(4,2);
X(5,2) - R(5,2);
X(6,2) - R(6,2);
X(7,2) - R(7,2);
X(8,2) - R(8,2);
X(9,2) - R(9,2);
X(10,2) - R(10,2);
X(11,2) - R(11,2);
X(12,2) - R(12,2);
X(13,2) - R(13,2);
X(14,2) - R(14,2);
X(15,2) - R(15,2);
X(16,2) - R(16,2);
X(17,2) - R(17,2);
X(18,2) - R(18,2);
X(19,2) - R(19,2);
X(20,2) - R(20,2);
X(21,2) - R(21,2);
X(22,2) - R(22,2);
X(23,2) - R(23,2);
X(1,3) - R(1,3);
X(2,3) - R(2,3);
X(3,3) - R(3,3);
X(4,3) - R(4,3);
X(5,3) - R(5,3);
X(6,3) - R(6,3);
X(7,3) - R(7,3);
X(8,3) - R(8,3);
X(9,3) - R(9,3);
X(10,3) - R(10,3);
X(11,3) - R(11,3);
X(12,3) - R(12,3);
X(13,3) - R(13,3);
X(14,3) - R(14,3);
X(15,3) - R(15,3);
X(16,3) - R(16,3);
X(17,3) - R(17,3);
X(18,3) - R(18,3);
X(19,3) - R(19,3);
X(20,3) - R(20,3);
X(21,3) - R(21,3);
X(22,3) - R(22,3);
X(23,3) - R(23,3);
X(1,4) - R(1,4);
X(2,4) - R(2,4);
X(3,4) - R(3,4);
X(4,4) - R(4,4);
X(5,4) - R(5,4);
X(6,4) - R(6,4);
X(7,4) - R(7,4);
X(8,4) - R(8,4);
X(9,4) - R(9,4);
X(10,4) - R(10,4);
X(11,4) - R(11,4);
X(12,4) - R(12,4);
X(13,4) - R(13,4);
X(14,4) - R(14,4);
X(15,4) - R(15,4);
X(16,4) - R(16,4);
X(17,4) - R(17,4);
X(18,4) - R(18,4);
X(19,4) - R(19,4);
X(20,4) - R(20,4);
X(21,4) - R(21,4);
X(22,4) - R(22,4);
X(23,4) - R(23,4);
X(1,5) - R(1,5);
X(2,5) - R(2,5);
X(3,5) - R(3,5);
X(4,5) - R(4,5);
X(5,5) - R(5,5);
X(6,5) - R(6,5);
X(7,5) - R(7,5);
X(8,5) - R(8,5);
X(9,5) - R(9,5);
X(10,5) - R(10,5);
X(11,5) - R(11,5);
X(12,5) - R(12,5);
X(13,5) - R(13,5);
X(14,5) - R(14,5);
X(15,5) - R(15,5);
X(16,5) - R(16,5);
X(17,5) - R(17,5);
X(18,5) - R(18,5);
X(19,5) - R(19,5);
X(20,5) - R(20,5);
X(21,5) - R(21,5);
X(22,5) - R(22,5);
X(23,5) - R(23,5);
S(1) - 108.869;
S(2) - 111.567;
S(3) - 108.526;
S(4) - 99.412;
S(5) - 97.558];
ceq = [];
end
I'm sure there was a better way to do that, but whatever it is, it would currently be contained in a separate file, base_constraints.m, so that when I made the call to createOptimProblem() I could use the function handle @base_constraints. If I'm dynamically generating the problem though, do I need to programmatically write out a file so that I can then pass a handle? Or is there another means to accomplish this?
It appears to me that you should be able to program those constraints as linear constraints, the A and b matrix inputs for fmincon. If I am correct, then those too could be read in.
Forgive my ignorance (and my obviously incomplete OP) but that leaves me with my objective function.
In this case, the X values represent funding allocated to projects. The projects accrue "value" depending on what percentage of their full funding requirement they receive. This value accrues in one of three ways: linearly (i.e. 50% funding achieves 50% value); according to an exponential function described a parameter rho which adjusts the shape of the curve; or according to an S-curve that has two anchor points to adjust the shape. (Just to complicate matters, there is also one project that has its own custom step function). So I have written functions for each of those, which are then called in the objective function.
So my current objective function is
function [ f ] = base_objective(X)
%base_objective multi-year objective function
% no turbulence or carry forward
% matrix X is the decision variables (funding levels)
% matrix R is the requirements
% matrix W are the element weights
rho = -0.5;
X1 = 0.3;
Y1 = 0.1;
X2 = 0.7;
Y2 = 0.95;
R = [65.268, 52.444, 48.531, 63.806, 62.555;
0.453, 0.456, 0.456, 0.458, 0.449;
20.201, 17.852, 9.985, 8.788, 8.616;
19.580, 19.580, 19.580, 19.580, 19.580;
41.964, 56.609, 61.640, 40.717, 39.919;
100.985,95.939, 88.995, 77.450, 75.932;
2.752, 1.229, 1.211, 0.505, 0.495;
42.891, 51.856, 32.449, 15.496, 15.192;
7.344, 7.211, 7.080, 6.951, 6.814;
4.696, 13.811, 17.151, 19.470, 19.088;
16.905, 16.573, 17.151, 15.930, 15.618;
1.062, 1.041, 1.021, 1.092, 1.071;
5.836, 1.907, 14.959, 16.499, 16.176;
0.000, 6.628, 13.924, 13.651, 13.383;
2.817, 12.890, 19.859, 21.240, 20.823;
8.452, 0.000, 0.000, 0.000, 0.000;
4.696, 6.445, 7.222, 7.080, 6.941;
8.452, 8.287, 8.124, 8.850, 8.676;
0.939, 0.921, 0.903, 0.885, 0.868;
9.486, 13.820, 13.549, 13.284, 13.023;
33.400, 30.753, 30.150, 29.559, 28.979;
10.447, 14.183, 15.020, 16.355, 16.034;
26.848, 15.831, 5.142, 0.000, 0.000];
W = [.0773;
.0722;
.0629;
.0621;
.0614;
.0588;
.0583;
.0572;
.0547;
.0521;
.0495;
.0490;
.0485;
.0382;
.0382;
.0371;
.0268;
.0247;
.0222;
.0180;
.0155;
.0103;
.0052];
year1 = (linear_value(X(1,1),R(1,1)) * W(1)) + ...
(linear_value(X(2,1),R(2,1)) * W(2)) + ...
(linear_value(X(3,1),R(3,1)) * W(3)) + ...
(linear_value(X(4,1),R(4,1)) * W(4)) + ...
(exponential_value(X(5,1),R(5,1),rho) * W(5)) + ...
(linear_value(X(6,1),R(6,1)) * W(6)) + ...
(linear_value(X(7,1),R(7,1)) * W(7)) + ...
(exponential_value(X(8,1),R(8,1),rho) * W(8)) + ...
(linear_value(X(9,1),R(9,1)) * W(9)) + ...
(s_curve_value(X(10,1),R(10,1),X1,Y1,X2,Y2) * W(10)) + ...
(s_curve_value(X(11,1),R(11,1),X1,Y1,X2,Y2) * W(11)) + ...
(s_curve_value(X(12,1),R(12,1),X1,Y1,X2,Y2) * W(12)) + ...
(exponential_value(X(13,1),R(13,1),rho) * W(13)) + ...
(s_curve_value(X(14,1),R(14,1),X1,Y1,X2,Y2) * W(14)) + ...
(s_curve_value(X(15,1),R(15,1),X1,Y1,X2,Y2) * W(15)) + ...
(linear_value(X(16,1),R(16,1)) * W(16)) + ...
(s_curve_value(X(17,1),R(17,1),X1,Y1,X2,Y2) * W(17)) + ...
(s_curve_value(X(18,1),R(18,1),X1,Y1,X2,Y2) * W(18)) + ...
(s_curve_value(X(19,1),R(19,1),X1,Y1,X2,Y2) * W(19)) + ...
(s_curve_value(X(20,1),R(20,1),X1,Y1,X2,Y2) * W(20)) + ...
(s_curve_value(X(21,1),R(21,1),X1,Y1,X2,Y2) * W(21)) + ...
(custom_step_function(X(22,1)) * W(22)) + ...
(exponential_value(X(23,1),R(23,1),rho) * W(23));
year2 = (linear_value(X(1,2),R(1,2)) * W(1)) + ...
(linear_value(X(2,2),R(2,2)) * W(2)) + ...
(linear_value(X(3,2),R(3,2)) * W(3)) + ...
(linear_value(X(4,2),R(4,2)) * W(4)) + ...
(exponential_value(X(5,2),R(5,2),rho) * W(5)) + ...
(linear_value(X(6,2),R(6,2)) * W(6)) + ...
(linear_value(X(7,2),R(7,2)) * W(7)) + ...
(exponential_value(X(8,2),R(8,2),rho) * W(8)) + ...
(linear_value(X(9,2),R(9,2)) * W(9)) + ...
(s_curve_value(X(10,2),R(10,2),X1,Y1,X2,Y2) * W(10)) + ...
(s_curve_value(X(11,2),R(11,2),X1,Y1,X2,Y2) * W(11)) + ...
(s_curve_value(X(12,2),R(12,2),X1,Y1,X2,Y2) * W(12)) + ...
(exponential_value(X(13,2),R(13,2),rho) * W(13)) + ...
(s_curve_value(X(14,2),R(14,2),X1,Y1,X2,Y2) * W(14)) + ...
(s_curve_value(X(15,2),R(15,2),X1,Y1,X2,Y2) * W(15)) + ...
(linear_value(X(16,2),R(16,2)) * W(16)) + ...
(s_curve_value(X(17,2),R(17,2),X1,Y1,X2,Y2) * W(17)) + ...
(s_curve_value(X(18,2),R(18,2),X1,Y1,X2,Y2) * W(18)) + ...
(s_curve_value(X(19,2),R(19,2),X1,Y1,X2,Y2) * W(19)) + ...
(s_curve_value(X(20,2),R(20,2),X1,Y1,X2,Y2) * W(20)) + ...
(s_curve_value(X(21,2),R(21,2),X1,Y1,X2,Y2) * W(21)) + ...
(custom_step_function(X(22,2)) * W(22)) + ...
(exponential_value(X(23,2),R(23,2),rho) * W(23));
year3 = (linear_value(X(1,3),R(1,3)) * W(1)) + ...
(linear_value(X(2,3),R(2,3)) * W(2)) + ...
(linear_value(X(3,3),R(3,3)) * W(3)) + ...
(linear_value(X(4,3),R(4,3)) * W(4)) + ...
(exponential_value(X(5,3),R(5,3),rho) * W(5)) + ...
(linear_value(X(6,3),R(6,3)) * W(6)) + ...
(linear_value(X(7,3),R(7,3)) * W(7)) + ...
(exponential_value(X(8,3),R(8,3),rho) * W(8)) + ...
(linear_value(X(9,3),R(9,3)) * W(9)) + ...
(s_curve_value(X(10,3),R(10,3),X1,Y1,X2,Y2) * W(10)) + ...
(s_curve_value(X(11,3),R(11,3),X1,Y1,X2,Y2) * W(11)) + ...
(s_curve_value(X(12,3),R(12,3),X1,Y1,X2,Y2) * W(12)) + ...
(exponential_value(X(13,3),R(13,3),rho) * W(13)) + ...
(s_curve_value(X(14,3),R(14,3),X1,Y1,X2,Y2) * W(14)) + ...
(s_curve_value(X(15,3),R(15,3),X1,Y1,X2,Y2) * W(15)) + ...
(linear_value(X(16,3),R(16,3)) * W(16)) + ...
(s_curve_value(X(17,3),R(17,3),X1,Y1,X2,Y2) * W(17)) + ...
(s_curve_value(X(18,3),R(18,3),X1,Y1,X2,Y2) * W(18)) + ...
(s_curve_value(X(19,3),R(19,3),X1,Y1,X2,Y2) * W(19)) + ...
(s_curve_value(X(20,3),R(20,3),X1,Y1,X2,Y2) * W(20)) + ...
(s_curve_value(X(21,3),R(21,3),X1,Y1,X2,Y2) * W(21)) + ...
(custom_step_function(X(22,3)) * W(22)) + ...
(exponential_value(X(23,3),R(23,3),rho) * W(23));
year4 = (linear_value(X(1,4),R(1,4)) * W(1)) + ...
(linear_value(X(2,4),R(2,4)) * W(2)) + ...
(linear_value(X(3,4),R(3,4)) * W(3)) + ...
(linear_value(X(4,4),R(4,4)) * W(4)) + ...
(exponential_value(X(5,4),R(5,4),rho) * W(5)) + ...
(linear_value(X(6,4),R(6,4)) * W(6)) + ...
(linear_value(X(7,4),R(7,4)) * W(7)) + ...
(exponential_value(X(8,4),R(8,4),rho) * W(8)) + ...
(linear_value(X(9,4),R(9,4)) * W(9)) + ...
(s_curve_value(X(10,4),R(10,4),X1,Y1,X2,Y2) * W(10)) + ...
(s_curve_value(X(11,4),R(11,4),X1,Y1,X2,Y2) * W(11)) + ...
(s_curve_value(X(12,4),R(12,4),X1,Y1,X2,Y2) * W(12)) + ...
(exponential_value(X(13,4),R(13,4),rho) * W(13)) + ...
(s_curve_value(X(14,4),R(14,4),X1,Y1,X2,Y2) * W(14)) + ...
(s_curve_value(X(15,4),R(15,4),X1,Y1,X2,Y2) * W(15)) + ...
(linear_value(X(16,4),R(16,4)) * W(16)) + ...
(s_curve_value(X(17,4),R(17,4),X1,Y1,X2,Y2) * W(17)) + ...
(s_curve_value(X(18,4),R(18,4),X1,Y1,X2,Y2) * W(18)) + ...
(s_curve_value(X(19,4),R(19,4),X1,Y1,X2,Y2) * W(19)) + ...
(s_curve_value(X(20,4),R(20,4),X1,Y1,X2,Y2) * W(20)) + ...
(s_curve_value(X(21,4),R(21,4),X1,Y1,X2,Y2) * W(21)) + ...
(custom_step_function(X(22,4)) * W(22)) + ...
(exponential_value(X(23,4),R(23,4),rho) * W(23));
year5 = (linear_value(X(1,5),R(1,5)) * W(1)) + ...
(linear_value(X(2,5),R(2,5)) * W(2)) + ...
(linear_value(X(3,5),R(3,5)) * W(3)) + ...
(linear_value(X(4,5),R(4,5)) * W(4)) + ...
(exponential_value(X(5,5),R(5,5),rho) * W(5)) + ...
(linear_value(X(6,5),R(6,5)) * W(6)) + ...
(linear_value(X(7,5),R(7,5)) * W(7)) + ...
(exponential_value(X(8,5),R(8,5),rho) * W(8)) + ...
(linear_value(X(9,5),R(9,5)) * W(9)) + ...
(s_curve_value(X(10,5),R(10,5),X1,Y1,X2,Y2) * W(10)) + ...
(s_curve_value(X(11,5),R(11,5),X1,Y1,X2,Y2) * W(11)) + ...
(s_curve_value(X(12,5),R(12,5),X1,Y1,X2,Y2) * W(12)) + ...
(exponential_value(X(13,5),R(13,5),rho) * W(13)) + ...
(s_curve_value(X(14,5),R(14,5),X1,Y1,X2,Y2) * W(14)) + ...
(s_curve_value(X(15,5),R(15,5),X1,Y1,X2,Y2) * W(15)) + ...
(linear_value(X(16,5),R(16,5)) * W(16)) + ...
(s_curve_value(X(17,5),R(17,5),X1,Y1,X2,Y2) * W(17)) + ...
(s_curve_value(X(18,5),R(18,5),X1,Y1,X2,Y2) * W(18)) + ...
(s_curve_value(X(19,5),R(19,5),X1,Y1,X2,Y2) * W(19)) + ...
(s_curve_value(X(20,5),R(20,5),X1,Y1,X2,Y2) * W(20)) + ...
(s_curve_value(X(21,5),R(21,5),X1,Y1,X2,Y2) * W(21)) + ...
(custom_step_function(X(22,5)) * W(22)) + ...
(exponential_value(X(23,5),R(23,5),rho) * W(23));
f = -1 * ((year1 + year2 + year3 + year4 + year5)/5);
%matlab minimizes, so * -1
end
Again, there's probably a better way to do that...but eventually I need to be able to achieve that objective function calculation programmatically.
(Just to complicate matters, there is also one project that has its own custom step function)
That does complicate matters as step functions are non-differentiable and so not within the scope of what fmincon can handle. You should probably just use ga().
So my current objective function is
It is still not clear how you want this to function to look for different numbers of rows.
I'm advocating for getting rid of the step function anyway...that's more a managerial problem than a technical one.
As for the objective function...what we're doing is allocating annual funding over a five year period to a basket of projects in such a way that we achieve the greatest "value" possible. In the hard-coded example there are 23, but that number can vary. Each project is assigned one of the three value functions (linear, exponential, or S). The projects are weighted to normalize everything, so that if all projects were fully funded in a given year, that year would achieve a value of 1.
So I'll read in:
  • the number of projects
  • each project's full-funding requirement for each of 5 years
  • each project's value curve and associated parameters
  • each project's weight
  • the total amount of funding available each year
Right now it's all hard-coded for a portfolio of 23 projects, but the desire is to produce a tool that will allow the budgeting folks to set up any set of projects and any set of funding constraints and get an allocation of funds to projects
You have a limited number of different types of operations. Each different type can be described by matrices of indices and corresponding coefficients. Therefore each complete scenario can be encoded as a series of data matrices. For efficiency you might want to have a routine that takes input data and builds a series of control matrices, so that you do not have to decode the matrices on each iteration; for any given scenario you would parse the input once and use the control matrices repeatedly. To get the control matrices into the objective function, use the techniques described at http://www.mathworks.com/help/matlab/math/parameterizing-functions.html
Thanks! I think that will get me there...I didn't realize you could define a function within a function like that.
You do not need to define a function within a function, unless you are referring to anonymous functions.
In pseudo-code:
control_inputs = .... %load the various matrices that are in a user-friendly form
[pcm, X0] = build_control_matrices(control_inputs); %transform from user-friendly form to something usable internally
obj = @(x) compute_scenario_value(x, pcm.internal_matrices);
options = ....
fmincon(obj, X0, pcm.A, pcm.b, pcm.Aeq, pcm.beq, pcm.lb, pcm.ub, pcm.nlcon, options)
Didn't realize you'd posted this comment...guess I only get notifications for "answers".
Thanks again for the help. I think I see the way forward now. I have actually coded it up where I nest the function declarations but it's quite slow and I see now why it's unnecessary.
If you'll forgive my ignorance (again) I do have one question regarding the pseudo-code you posted above. It has to do with this line
[pcm, X0] = build_control_matrices(control_inputs);
and then later referencing pcm.A, pcm.b, etc. I'm familiar with having a function return multiple values such as
function [ A, b, Aeq ] = build_control_matrices(control_inputs);
but you appear to be returning an "object" for lack of a better term in which you've combined these return values to then access via the dot notation pcm.A, pcm.B, etc. How do you do that?
I suggest that you could return a structure
function [pcm, X0] = build_control_matrices(control_inputs)
...
pcm.A = ...
pcm.b = ...
pcm.Aeq = ...
Wow, I feel dumb.
Thanks...I assumed there were some other directions required to ensure that it didn't just see pcm.A, pcm.b, etc as a bunch of individual variables.

请先登录,再进行评论。

 采纳的回答

I assume the quantity that you are reading in is R and maybe also
sumBounds= [ 108.869; 111.567; 108.526; 99.412; 97.558];
the bounds on sum(X). If so, then a dimension-independent way to run what you have shown so far (i.e., neglecting the objective function) is as follows,
[m,n]=size(R);
x0=zeros(m,n);
lb=zeros(m,n);
ub=R;
A=kron(eye(n),ones(1,m));
b=sumBounds(:);
problem = createOptimProblem('fmincon','objective',?,...
'x0',x0,'lb',lb,'ub',ub,'A',A,'b',b,'options',options);
As Walter said, you can get rid of the nonlinear constraint function. The constraints you had there were not really nonlinear.

3 个评论

Thank you. I'm also reading in which of the three "value curves" each alternative adheres to so that I can build the objective function.
Similar to what Walter said, all the data that you read in can be passed as fixed parameters to the objective function using techniques discussed here. You then have dynamic control of the calculations from within the objective function code.
Thanks! I think that will get me there.

请先登录,再进行评论。

更多回答(0 个)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by