How do I fix this issue with fgoalattain?

I've formulated the below goal attainment problem:
When I set up the code in MATLAB using fgoalattain, I seem to be getting an issue in regards to the 'x0' variable. What am I doing wrong here?
Code:
clc
clear all
fun = @(x)[x(12)+x(22)+x(32);x(34);x(11)+x(21)+x(31);x(12)+x(22)+x(32);x(13)+x(23)+x(33);x(14)+x(24)+x(34);x(999);x(21)];
goal = [250,80,416,200,320,304,24750,0];
weight = [1,1,1,1,1,1,1,1];
x0=[1];
A = [1,1,1,1,0,0,0,0,0,0,0,0
0,0,0,0,1,1,1,1,0,0,0,0
0,0,0,0,0,0,0,0,1,1,1,1];
b= [420
610
340];
x = fgoalattain(fun,x0,goal,weightA,b)
Output:
Index exceeds the number of array elements. Index must not
exceed 1.
Error in HW12_2>@(x)[x(12)+x(22)+x(32);x(34);x(11)+x(21)+x(31);x(12)+x(22)+x(32);x(13)+x(23)+x(33);x(14)+x(24)+x(34);x(999);x(21)] (line 4)
fun = @(x)[x(12)+x(22)+x(32);x(34);x(11)+x(21)+x(31);x(12)+x(22)+x(32);x(13)+x(23)+x(33);x(14)+x(24)+x(34);x(999);x(21)];
Error in goalcon (line 63)
f = feval(funfcn{3},x,varargin{:});
Error in fgoalattain (line 437)
[ctmp,ceqtmp] = feval(cfun{3},xnew,extravarargin{:});
Error in HW12_2 (line 14)
x = fgoalattain(fun,x0,goal,weight)
Caused by:
Failure in initial objective function evaluation.
Optimization cannot continue.

10 Comments

fun = @(x)[x(12)+x(22)+x(32);x(34);x(11)+x(21)+x(31);x(12)+x(22)+x(32);x(13)+x(23)+x(33);x(14)+x(24)+x(34);x(999);x(21)];
goal = [250,80,416,200,320,304,24750,0];
Your code creates 8 equations in 999 variables
x0=[1];
and passes a scalar value as the initial conditions.
A = [1,1,1,1,0,0,0,0,0,0,0,0
0,0,0,0,1,1,1,1,0,0,0,0
0,0,0,0,0,0,0,0,1,1,1,1];
and you define constraints as-if you have 12 variables.
Distinct variables in your equation are x(11), x(12), x(13), x(14), x(21), x(22), x(23), x(24), x(31), x(32), x(33), x(34), x(999) which is 13 variables.
Your constraint matrix A needs to have number of columns equation to number of variables, and your initial conditions needs to be a vector with as many elements as you have variables -- which is to say 999 since you access x(999)
syms x [1 999]
fun = @(x)[x(12)+x(22)+x(32);x(34);x(11)+x(21)+x(31);x(12)+x(22)+x(32);x(13)+x(23)+x(33);x(14)+x(24)+x(34);x(999);x(21)];
LHS = fun(x)
LHS = 
vars = symvar(LHS)
vars = 
fun2 = matlabFunction(LHS, 'vars', {vars})
fun2 = function_handle with value:
@(in1)[in1(:,2)+in1(:,6)+in1(:,10);in1(:,12);in1(:,1)+in1(:,5)+in1(:,9);in1(:,2)+in1(:,6)+in1(:,10);in1(:,3)+in1(:,7)+in1(:,11);in1(:,4)+in1(:,8)+in1(:,12);in1(:,13);in1(:,5)]
fun2 is now a function that expects a vector of 13 elements and computes the 8 results.
goal = [250,80,416,200,320,304,24750,0];
[A,b] = equationsToMatrix(LHS==goal.')
A = 
b = 
boundary = A\b
Warning: Solution does not exist because the system is inconsistent.
boundary = 
rank(A)
ans = 7
Your system is inconsistent at the boundary; perhaps there is a solution at some other point due to the inequalities
x(999) is supposed to be a total 'cost' variable so the 999 number was an arbitrary choice. I've changed it to x(5) now and updated the A matrix. How am I supposed to set up the x0 variable? I'm still getting the same error:
Code:
clc
clear all
syms x [1 5]
fun = @(x)[x(12)+x(22)+x(32);x(34);x(11)+x(21)+x(31);x(12)+x(22)+x(32);x(13)+x(23)+x(33);x(14)+x(24)+x(34);x(5);x(21)];
goal = [250,80,416,200,320,304,24750,0];
weight = [1,1,1,1,1,1,1,1];
A = [0,1,0,0,0,1,0,0,0,1,0,0,0
0,0,0,0,0,0,0,0,0,0,0,1,0
1,0,0,0,1,0,0,0,1,0,0,0,0
0,1,0,0,0,1,0,0,0,1,0,0,0
0,0,0,1,0,0,0,1,0,0,0,1,0
0,0,0,0,0,0,0,0,0,0,0,0,1
0,0,0,0,1,0,0,0,0,0,0,0,0];
b=[250,80,416,200,320,304,24750,0]
x0=[1];
x = fgoalattain(fun2,x0,goal,weight,A,b)
Output:
Index exceeds the number of array elements. Index must not
exceed 5.
Error in indexing (line 1075)
R_tilde = builtin('subsref',L_tilde,Idx);
Error in HW12_2>@(x)[x(12)+x(22)+x(32);x(34);x(11)+x(21)+x(31);x(12)+x(22)+x(32);x(13)+x(23)+x(33);x(14)+x(24)+x(34);x(5);x(21)] (line 4)
fun = @(x)[x(12)+x(22)+x(32);x(34);x(11)+x(21)+x(31);x(12)+x(22)+x(32);x(13)+x(23)+x(33);x(14)+x(24)+x(34);x(5);x(21)];
Error in HW12_2 (line 5)
LHS = fun(x)
>>
The following finishes in less than 2 seconds on my system, but for some reason takes more than 55 seconds here.
fun = @(x)[x(12)+x(22)+x(32);x(34);x(11)+x(21)+x(31);x(12)+x(22)+x(32);x(13)+x(23)+x(33);x(14)+x(24)+x(34);x(5);x(21)];
goal = [250,80,416,200,320,304,24750,0];
weight = [1,1,1,1,1,1,1,1];
A = [0,1,0,0,0,1,0,0,0,1,0,0,0
0,0,0,0,0,0,0,0,0,0,0,1,0
1,0,0,0,1,0,0,0,1,0,0,0,0
0,1,0,0,0,1,0,0,0,1,0,0,0
0,0,0,1,0,0,0,1,0,0,0,1,0
0,0,0,0,0,0,0,0,0,0,0,0,1
0,0,0,0,1,0,0,0,0,0,0,0,0];
b=[250,80,416,200,320,304,24750]
A = [A, zeros(size(A,1), 34-size(A,2))];
x0 = ones(34,1);
opt = optimoptions('fgoalattain', 'MaxFunctionEvaluations', 1e7, 'MaxIterations', 1e7);
format long g
x = fgoalattain(fun, x0, goal, weight, A, b, [], [], [], [], [], opt)
On my system it returns
5598031.17373463
0.992386115234259
1.00000734614772
1
-41243827299.5585
1
1
1
1
1
1
-34013605214.1836
-7722439417.55122
1
1
1
1
1
1
1
-21848653598.1129
-34027995453.5257
-8116712720.61692
1
1
1
1
1
1
1
1
-34027995475.0493
-8116699604.66787
-21953904727.7
This is, of course, a useless answer, since it does not solve the problem you thought you were solving.
Consider for example your first constraint that . To implement that in A*x<=b constraint matrix you would have to have a 1 in each of columns 11, 12, 13, and 14 -- but your original A matrix only has 13 columns. I pad the 13 out to 34 to get rid of the error messages, but since the padded A does not have any 1's in column 14, it cannot possibly be matching the constraint you were given.
I've reworked the code by renaming variables. However this solution doesn't seem to be solving any of the goals. I am missing something here in regards to how to set the weights?
clc
clear all
fun = @(x)[x(2)+x(6)+x(10);x(12);x(1)+x(5)+x(9);x(2)+x(6)+x(10);x(3)+x(7)+x(11);x(4)+x(8)+x(12);x(13);x(5)];
goal = [250,80,416,200,320,304,24750,0];
weight = [36,18,6,6,6,6,3,1];
A = [1,1,1,1,0,0,0,0,0,0,0,0,0
0,0,0,0,1,1,1,1,0,0,0,0,0
0,0,0,0,0,0,0,0,1,1,1,1,0
1,0,0,0,1,0,0,0,1,0,0,0,0
0,1,0,0,0,1,0,0,0,1,0,0,0
0,0,1,0,0,0,1,0,0,0,1,0,0
0,0,0,1,0,0,0,1,0,0,0,1,0];
b= [420
610
340
520
250
400
380];
Aeq=[22,17,30,18,15,35,20,25,28,21,16,14,-1];
beq=[0];
lb = [0,0,0,0,0,0,0,0,0,0,0,0,0];
ub = [];
nonlcon=[];
options = struct('MaxFunctionEvaluations',10e+10)
x0 = [200,200,200,200,200,200,200,200,200,200,200,200,50000];
x = fgoalattain(fun,x0,goal,weight,A,b,Aeq,beq,lb,ub,nonlcon,options)
The initial goals should have higher importance than the later goals.However in the above code's output, its solving the later goals and not the initial goals
Output:
options =
struct with fields:
MaxFunctionEvaluations: 1.0000e+11
Local minimum possible. Constraints satisfied.
fgoalattain stopped because the size of the current search direction is less than
twice the value of the step size tolerance and constraints are
satisfied to within the value of the constraint tolerance.
<stopping criteria details>
x =
1.0e+04 *
Columns 1 through 9
0.0072 0.0000 0.0278 0.0000 0.0000 0.0029 -0.0000 0.0304 0.0221
Columns 10 through 13
0.0000 0.0000 0.0000 2.4750
There's 13 variables and 13 columns now in A
C is now x(13) and defining C equation is now set to Aeq as an equality constraint
Your fundamental mistake is in looking at variable names such as and deciding that must be represented as x(34) . is just a variable name and the 34 does not need to be the subscript.
Consider this:
fun = @(x5,x11,x12,x13,x14,x21,x22,x24,x23,x31,x32,x33,x34)[x12+x22+x32;x34;x11+x21+x31;x12+x22+x32;x13+x23+x33;x14+x24+x34;x5;x21];
wrapper = @(x) fun(x(1),x(2),x(3),x(4),x(5),x(6),x(7),x(8),x(9),x(10),x(11),x(12),x(13))
Now if you were to fgoalattain asking to optimize function wrapper then you would have been able to use the names that are familiar to you, but at the same time fgoalattain would be working with the vector of values that it is required to work with.
You would have to make sure that your A matrix was built properly. You could do that using names such as
X5=1; X11=2; X12=3; %and so on to X34=13
A(1, [X12, X13, X14, X15]) = 1;
A(2, [X21, X22, X23, X24]) = 1;
%and so on
Or.. you could look into Problem Based Optimization; https://www.mathworks.com/help/optim/problem-based-approach.html
Or... you could use the Symbolic Toolbox the way I showed, in order to construct the problem matrices and the function to be optimized.

Sign in to comment.

Answers (0)

Categories

Products

Release

R2022a

Asked:

on 18 Nov 2022

Edited:

on 18 Nov 2022

Community Treasure Hunt

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

Start Hunting!