SAS使变量函数最大化
给定一组变量SAS使变量函数最大化,sas,Sas,给定一组变量v(1)-v(k),函数f被定义为f(v1,v2,…vk) 目标是使给定的v(1)+v(2)+..+v(k)=n具有一组v(i),使f最大化。所有元素都限制为非负整数 注意:我没有SAS/IML或SAS/or 如果k已知,比如说2,那么我可以做这样的事情 data out; set in; maxf = 0; n1 = 0; n2 = 0; do i = 0 to n; do j = 0 to n; if
v(1)-v(k)
,函数f
被定义为f(v1,v2,…vk)
目标是使给定的v(1)+v(2)+..+v(k)=n
具有一组v(i),使f
最大化。所有元素都限制为非负整数
注意:我没有SAS/IML
或SAS/or
如果k
已知,比如说2
,那么我可以做这样的事情
data out;
set in;
maxf = 0;
n1 = 0;
n2 = 0;
do i = 0 to n;
do j = 0 to n;
if i + j ne n then continue;
_max = f(i,j);
if _max > maxf then do;
maxf = max(maxf,_max);
n1 = i;
n2 = j;
end;
end;
end;
drop i j;
run;
proc fcmp outlib=work.fns.fns;
function f(x1,x2,a);
out = -10*(x1-5)*(x1-5) + -2*(x2-2)*(x2-2) + 2*(x1-5) + 3*(x2-2);
return(out+a);
endsub;
run;quit;
options cmplib=work.fns;
然而,这个解决方案有几个问题
k
由#个列决定,这些列在中具有特定前缀,n
由宏变量决定
函数f
是已知的,例如f(i,j)=2*i+3*j
这可以在数据步骤中完成吗?正如评论中所说,一般的非线性整数规划很难求解。以下方法将解决连续参数的问题。您必须获取输出并找到使函数最大化的最近的整数值。但是,现在循环将更小,运行速度更快 首先让我们做一个函数。此函数有一个额外的参数,并且在该参数中是线性的。将您的函数包装在这样的内容中
data out;
set in;
maxf = 0;
n1 = 0;
n2 = 0;
do i = 0 to n;
do j = 0 to n;
if i + j ne n then continue;
_max = f(i,j);
if _max > maxf then do;
maxf = max(maxf,_max);
n1 = i;
n2 = j;
end;
end;
end;
drop i j;
run;
proc fcmp outlib=work.fns.fns;
function f(x1,x2,a);
out = -10*(x1-5)*(x1-5) + -2*(x2-2)*(x2-2) + 2*(x1-5) + 3*(x2-2);
return(out+a);
endsub;
run;quit;
options cmplib=work.fns;
我们需要添加一个
参数,这样除了实际参数外,SAS还可以传递一个值。SAS将认为它正在基于x1
和x2
解决A
的可能性
生成具有a
值的数据集
data temp;
a = 1;
run;
现在使用PROC NLMIXED
最大化A
的可能性
ods output ParameterEstimates=Parameters;
ods select ParameterEstimates;
proc nlmixed data=temp;
parms x1=1 x2=1;
bounds x1>0, x2>0;
y = f(x1,x2,a);
model a ~ general(y);
run;
ods select default;
我得到的输出是x1=5.1
和x2=2.75
。然后,您可以搜索“周围”,以查看最大值出现在哪里
以下是我尝试在数据步骤中搜索该值:
%macro call_fn(fn,n,parr);
%local i;
&fn(&parr[1]
%do i=2 %to &n;
, &parr[&i]
%end;
,0)
%mend;
%let n=2;
%let c=%sysevalf(2**&n);
data max;
set Parameters end=last;
array parms[&n] _temporary_;
array start[&n] _temporary_;
array pmax[&n];
max = -9.99e256;
parms[_n_] = estimate;
if last then do;
do i=1 to &n;
start[i] = floor(parms[i]);
end;
do i=1 to &c;
x = put(i,$binary2.);
do j=1 to &n;
parms[j] = input(substr(x,j,1),best.) + start[j];
end;
/*You need a macro to write this dynamically*/
val = %call_fn(f,&n,parms);
*put i= max= val=;
if val > max then do;
do j=1 to &n;
pmax[j] = parms[j];
end;
max = val;
end;
end;
output;
end;
f总是变量的线性函数吗?如果是这样的话,我建议使用SAS将问题导出到另一个应用程序中,而不是重新发明轮子。@user667489不幸的是不是……这就是我想知道这个问题是否可以解决的部分原因。。。。你有SAS/STAT或SAS/ETS吗?@dompazz不是ETS。但是你能解释一下ets是如何做到这一点的吗?有趣的解决方案。对于最大似然部分,我需要查看教科书以了解详细信息,现在我记不起它背后的逻辑。但我认为一旦有了连续解,找到最近的整数应该很容易。我还有两个问题。1.在第一部分中,proc nlmixed不能保证x的和等于n。你把它留到第二部分吗?2.不理解substr部分是如何工作的..我没有看到sum(x)=n的约束。我将不得不考虑如何实现这一点。substr()部分之所以有效,是因为我在解决方案(2^n)周围取C个整数。我数到C,将数字转换成二进制字符串——即2=10。然后,我使用substr()函数获取该字符串中的第j个值,并将其添加到起始值。这给了我一个简单的方法来确保我将0和1的所有组合添加到起始值中,并且不用担心可能性部分。它只是最大化一个函数。NLMIXED没有一个约束,我可以强制求和(x)=n。SAS/ETS中的PROC模型允许这样做。我认为sum(x)