Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SAS使变量函数最大化_Sas - Fatal编程技术网

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个球分配到k个箱子”的问题,其中,
    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)