I'm new to Mathlab and I'm still learning how to use it correctly. I'd really appreciate if you could help me a little bit. I'm trying to simulate (Q,R) model (for inventory) and there is something I'm doing wrong and I can't tell what it is. The objective is to optimize function in attached to find Q (quantity) and R (re order level) In this case, the demand is adjusted to lognormal distribution.
%Demand
D = [55 54 57 59 51 52 42 42 41 34 32 18 19 18 23 33 30 31 24 27 25 27 35 38];
Dmin = min(D);
%P: unit price / h: storage cost / K: order cost
K = 50;
p = 542.73694;
h = p*0.12;
%Objective funtion
objective = @(x) (Dmin*K)/x(1) + h*(x(1)/2 + x(2)) + ((p*Dmin)/x(1))*int((x-x(2)- int((euler((log(x)-37.73)/((-2)*std(D))).^2)/(sqrt(2*pi)*std(D)),x(2),100))*(euler(((log(x)-37.73)/((-2)*std(D))).^2))/(x*sqrt(2*pi)*std(D)),x(2),100);
x0 = [3,3];
% ub reflects the max amount of units that can be at the same time in
% stockroom and lb the security stock
A = [];
b = [];
Aeq = [];
beq = [];
lb = 3.0* ones(2);
ub = 22.0* ones(2);
nonlincon = @nonlcon;
x = fmincon(objective,x0,A,b,Aeq,beq,lb,ub,nonlincon);
disp(x)
%(Disferent script)
function [c,ceq] = nonlcon(x)
c = -(x(1))/2 - x(2);
ceq = [];
The errors are the following
Error using symengine
A nonnegative integer or a symbol is expected.
Error in sym/privUnaryOp (line 979)
Csym = mupadmex(op,args{1}.s,varargin{:});
Error in sym/euler (line 14)
Y = privUnaryOp(n, 'symobj::vectorizeSpecfunc', 'euler', 'undefined');
Error in sym.useSymForNumeric (line 158)
res = cast(fn(args{:}),superiorfloat(varargin{:}));
Error in double/euler (line 14)
Y = sym.useSymForNumeric(@euler, varargin{:});
Error in
intento1>@(x)(Dmin*K)/x(1)+h*(x(1)/2+x(2))+((p*Dmin)/x(1))*int((x-x(2)-int((euler((log(x)-37.73)/((-2)*std(D))).^2)/(sqrt(2*pi)*std(D)),x(2),100))*(euler(((log(x)-37.73)/((-2)*std(D))).^2))/(x*sqrt(2*pi)*std(D)),x(2),100)
Error in fmincon (line 536)
initVals.f = feval(funfcn{3},X,varargin{:});
Error in intento1 (line 19)
x = fmincon(objective,x0,A,b,Aeq,beq,lb,ub,nonlincon);
Caused by:
Failure in initial objective function evaluation. FMINCON cannot continue.

답변 (1개)

Walter Roberson
Walter Roberson 2018년 9월 8일

2 개 추천

You have
objective = @(x) (Dmin*K)/x(1) + h*(x(1)/2 + x(2)) + ((p*Dmin)/x(1))*int((x-x(2)- int((euler((log(x)-37.73)/((-2)*std(D))).^2)/(sqrt(2*pi)*std(D)),x(2),100))*(euler(((log(x)-37.73)/((-2)*std(D))).^2))/(x*sqrt(2*pi)*std(D)),x(2),100);
That involves a numeric vector, x.
As part of it, the call
int((euler((log(x)-37.73)/((-2)*std(D))).^2)/(sqrt(2*pi)*std(D)),x(2),100))*(euler(((log(x)-37.73)/((-2)*std(D))).^2))/(x*sqrt(2*pi)*std(D)),x(2),100)
is made. Remember that x is a numeric vector.
The first part of that expression involves invoking
euler((log(x)-37.73)/((-2)*std(D)))
x is a numeric vector, log of it is a numeric vectr, 37.73 is numeric scalar, so the numerator is a numeric vector.
D is a numeric vector so std(D) is a numeric scalar, so the denominator is a numeric scalar.
With the numerator being a numeric vector and the denominator being a numeric scalar, the overall is a numeric scalar.
So euler() is being invoked on a numeric vector.
There is no stand-alone euler() routine defined for double. There is, though, euler() defined by the Symbolic Toolbox, together with a convenience function for double values that effectively calls euler(sym(TheDouble), 'd') -- that is, the hardware floating point numbers are converted to software floating point numbers and the symbolic euler is called on that.
Now look at the definition of the symbolic euler() routine: https://www.mathworks.com/help/symbolic/euler.html
euler(n) returns the nth Euler number.
euler(n,x) returns the nth Euler polynomial.
Thus when a single input parameter is given (you provided a single input parameter that happened to be a vector) then the input needs to be a positive integer (or array of them) because you need to be passing in the index of the Euler number that you want.
The two-parameter version of euler() would require that you call euler with a first parameter that is the index of the euler polynomial; it then evaluates the polynomial at the given input. It would be valid to evaluate the polynomial at a vector of locations. For example it would be valid to call
euler(12, (log(x)-37.73)/((-2)*std(D)))
to create the 12th euler polynomial and evaluate it with the numeric vector value (log(x)-37.73)/((-2)*std(D)) . The result would be a vector of doubles.
This would not be the most efficient way to proceed since it would require recreating the polynomial each time, but it would be legal.
Now, that euler() call occurs inside an int() call. If we hypothesize that you meant to create euler polynomial and evaluate them but overlooked putting in the polynomial index, then the adjusted version would involve creating a numeric vector, and calling
int(numeric_vector, x(2), 100)
but that is a problem, because you cannot int() numeric vectors, since int() is strictly a symbolic integrator.
We can speculate that maybe you wanted to introduce a symbolic variable and create euler polynomials based upon a formula in that variable. Like perhaps you wanted
Nth_out = 12; %which polynomial for outer integration euler
Nth_in = 6; %which polynomial for inner integration euler
syms Tin Tout
objective = @(x) (Dmin*K)/x(1) + h*(x(1)/2 + x(2)) + ((p*Dmin)/x(1))*int((Tout-x(2)- int((euler(Nth_out, (log(Tin)-37.73)/((-2)*std(D))).^2)/(sqrt(2*pi)*std(D)), Tin, x(2),100))*(euler(Nth_in, ((log(Tout)-37.73)/((-2)*std(D))).^2))/(Tout*sqrt(2*pi)*std(D)), Tout, x(2),100);
If so then you also need to toss in a double(), as the result of int() is symbolic, but fmincon requires the output to be strictly scalar double.
This would not be an efficient expression, as it has several opportunities for optimization, such as pre-computing the euler polynomials. Or even precomputing Dmin*K or (sqrt(2*pi)*std(D)) since those do not change for the objective function so you are wasting compute cycles calculating them again each time.

카테고리

도움말 센터File Exchange에서 Mathematics and Optimization에 대해 자세히 알아보기

질문:

2018년 9월 8일

답변:

2018년 9월 8일

Community Treasure Hunt

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

Start Hunting!

Translated by