MrZ000 2024-11-25 22:34 采纳率: 100%
浏览 16
已结题

matlab有程序一直报错,如何解决?(相关搜索:惩罚函数)

matlab中有两个程序一直无法运行,有没有人能帮忙看一下程序哪里出问题了嘛?
第一个程序是使用内点惩罚函数法求解约束优化问题,下面是我的程序代码:

clear all;clc
syms x1 x2 x;
f=(x1-3)^2+(x2-4)^2+8;%原函数
g1=2*x1-x2-1;g2=x1+x2-2;%约束条件转换函数
e1=0.1;%梯度法最优值收敛精度
e2=0.1;%内点法收敛精度
D=1;
k=1;
A(k)=0;B(k)=0;%A,B分别记录x1,x2点,初始点为[0,0]
r(k)=3;%r为惩罚因子
a=0.7;%a为递增函数
while D>e2;%惩罚因子迭代收敛条件
    x1=A(k);
    x2=B(k);
    %约束问题转换后的新目标函数
    F=f+r(k)*(log10(-g1)+log(-g2));%F=f+r(k)*(1/g1^2+1/g2^2+1/g3^2);%F=f-r(k)*(1/g1+1/g2+1/g3);
    %梯度法求F的最优解xr
    Fx1=diff(F,'x1');
    Fx2=diff(F,'x2');
    Fx1x1=diff(Fx1,'x1');
    Fx1x2=diff(Fx1,'x2');
    Fx2x1=diff(Fx2,'x1');
    Fx2x2=diff(Fx2,'x2');%求偏导、海森元素
    for n=1:100%梯度法求最优值
        F1=subs(Fx1);%求解梯度值和海森矩阵
        F2=subs(Fx2);
        F11=subs(Fx1x1);
        F12=subs(Fx1x2);
        F21=subs(Fx2x1);
        F22=subs(Fx2x2);
        if(double(sqrt(F1^2+F2^2))<=e1)
            A(k+1)=double(x1);
            B(k+1)=double(x2);
            break;
        else
            X=[x1 x2]'-([F11 F12;F21 F22])\[F1 F2]';
            x1=X(1,1);
            x2=X(2,1);
        end
    end
    D=double(sqrt((A(k+1)-A(k))^2+(B(k+1)-B(k))^2));
    r(k+1)=a*r(k);
    k=k+1;
end

程序运行会提示以下错误:

错误使用 mupadengine/feval2char
Unable to convert expression containing symbolic variables into double array. Apply 'subs' function first
to substitute values for variables.

出错 sym/double (第 755 行)
            Xstr = feval2char(symengine, "symobj::double", S);

出错 task3 (第 31 行)
        if(double(sqrt(F1^2+F2^2))<=e1)

第二个程序则是使用外点惩罚函数法求解约束优化问题
代码如下

syms x1 x2 x;
f=(x1-3)^2+(x2-4)^2+8;
g1=2*x1-x2-1;g2=x1+x2-2;
e1=0.1;
e2=0.1;
d=1;
k=1;
a(k)=0;
b(k)=0;
r(k)=3;
a=0.7;
while d>e2
    x1=a(k);
    x2=b(k);
    F=f+r(k)*((-g1)^2+(-g2)^2);
    Fx1=diff(F,'x1');
    Fx2=diff(F,'x2');
    Fx1x1=diff(Fx1,'x1');
    Fx1x2=diff(Fx1,'x2');
    Fx2x1=diff(Fx2,'x1');
    Fx2x2=diff(Fx2,'x2');
    for n=1:100
        F1=subs(Fx1);
        F2=subs(Fx2);
        F11=subs(Fx1x1);
        F12=subs(Fx1x2);
        F21=subs(Fx2x1);
        F22=subs(Fx2x2);
        if(double(sqrt(F1^2+F2^2))<=e1)
            a(k+1)=double(x1);
            b(k+1)=double(x2);
            break
        else
            X=[x1 x2]'-([F11 F12;F21 F22])\[F1 F2]';
            x1=X(1,1);
            x2=X(2,1);
        end
    end
    d=double(sqrt((a(k+1)-a(k))^2+(b(k+1)-b(k))^2));
    r(k+1)=a*r(k);
    k=k+1;
end

程序提示以下错误:

无法执行赋值,因为左侧和右侧的元素数目不同。

出错 task4 (第 40 行)
    r(k+1)=a*r(k);

  • 写回答

11条回答 默认 最新

  • GISer Liu 2024-11-25 22:46
    关注

    该回答引用自GPT-4o, 由博主 GISer Liu 编写:

    问题分析

    用户在MATLAB中编写了两个程序,分别使用内点惩罚函数法和外点惩罚函数法求解约束优化问题。两个程序在运行时都遇到了错误,需要进行调试和修正。

    第一个程序的错误分析

    错误信息

    错误使用 mupadengine/feval2char
    Unable to convert expression containing symbolic variables into double array. Apply 'subs' function first
    to substitute values for variables.
    
    出错 sym/double (第 755 行)
                Xstr = feval2char(symengine, "symobj::double", S);
    
    出错 task3 (第 31 行)
            if(double(sqrt(F1^2+F2^2))<=e1)
    

    错误原因
    在第31行,double(sqrt(F1^2+F2^2))试图将符号表达式转换为双精度数,但由于符号变量未被替换为具体数值,导致转换失败。

    解决方案
    在使用double函数之前,需要使用subs函数将符号变量替换为具体数值。

    第二个程序的错误分析

    错误信息

    无法执行赋值,因为左侧和右侧的元素数目不同。
    
    出错 task4 (第 40 行)
        r(k+1)=a*r(k);
    

    错误原因
    在第40行,r(k+1)=a*r(k)试图将标量a乘以标量r(k)的结果赋值给r(k+1),但由于a已经被定义为数组,导致赋值失败。

    解决方案
    a重新定义为标量,或者在赋值时确保a的类型与r(k)一致。

    解决方案

    第一个程序的修正

    clear all; clc;
    syms x1 x2;
    f = (x1-3)^2 + (x2-4)^2 + 8; % 原函数
    g1 = 2*x1 - x2 - 1; g2 = x1 + x2 - 2; % 约束条件转换函数
    e1 = 0.1; % 梯度法最优值收敛精度
    e2 = 0.1; % 内点法收敛精度
    D = 1;
    k = 1;
    A(k) = 0; B(k) = 0; % A, B分别记录x1, x2点,初始点为[00]
    r(k) = 3; % r为惩罚因子
    a = 0.7; % a为递增函数
    
    while D > e2; % 惩罚因子迭代收敛条件
        x1 = A(k);
        x2 = B(k);
        % 约束问题转换后的新目标函数
        F = f + r(k) * (log10(-g1) + log(-g2));
        % 梯度法求F的最优解xr
        Fx1 = diff(F, 'x1');
        Fx2 = diff(F, 'x2');
        Fx1x1 = diff(Fx1, 'x1');
        Fx1x2 = diff(Fx1, 'x2');
        Fx2x1 = diff(Fx2, 'x1');
        Fx2x2 = diff(Fx2, 'x2'); % 求偏导、海森元素
        
        for n = 1:100 % 梯度法求最优值
            F1 = double(subs(Fx1, {x1, x2}, {A(k), B(k)})); % 替换符号变量为具体数值
            F2 = double(subs(Fx2, {x1, x2}, {A(k), B(k)}));
            F11 = double(subs(Fx1x1, {x1, x2}, {A(k), B(k)}));
            F12 = double(subs(Fx1x2, {x1, x2}, {A(k), B(k)}));
            F21 = double(subs(Fx2x1, {x1, x2}, {A(k), B(k)}));
            F22 = double(subs(Fx2x2, {x1, x2}, {A(k), B(k)}));
            
            if (sqrt(F1^2 + F2^2) <= e1)
                A(k+1) = double(x1);
                B(k+1) = double(x2);
                break;
            else
                X = [x1 x2]' - ([F11 F12; F21 F22] \ [F1 F2]');
                x1 = X(1, 1);
                x2 = X(2, 1);
            end
        end
        
        D = sqrt((A(k+1) - A(k))^2 + (B(k+1) - B(k))^2);
        r(k+1) = a * r(k);
        k = k + 1;
    end
    

    第二个程序的修正

    clear all; clc;
    syms x1 x2;
    f = (x1-3)^2 + (x2-4)^2 + 8;
    g1 = 2*x1 - x2 - 1; g2 = x1 + x2 - 2;
    e1 = 0.1;
    e2 = 0.1;
    d = 1;
    k = 1;
    a = 0; b = 0; % 初始点为[00]
    r(k) = 3;
    a_scalar = 0.7; % 重新定义a为标量
    
    while d > e2
        x1 = a(k);
        x2 = b(k);
        F = f + r(k) * ((-g1)^2 + (-g2)^2);
        Fx1 = diff(F, 'x1');
        Fx2 = diff(F, 'x2');
        Fx1x1 = diff(Fx1, 'x1');
        Fx1x2 = diff(Fx1, 'x2');
        Fx2x1 = diff(Fx2, 'x1');
        Fx2x2 = diff(Fx2, 'x2');
        
        for n = 1:100
            F1 = double(subs(Fx1, {x1, x2}, {a(k), b(k)})); % 替换符号变量为具体数值
            F2 = double(subs(Fx2, {x1, x2}, {a(k), b(k)}));
            F11 = double(subs(Fx1x1, {x1, x2}, {a(k), b(k)}));
            F12 = double(subs(Fx1x2, {x1, x2}, {a(k), b(k)}));
            F21 = double(subs(Fx2x1, {x1, x2}, {a(k), b(k)}));
            F22 = double(subs(Fx2x2, {x1, x2}, {a(k), b(k)}));
            
            if (sqrt(F1^2 + F2^2) <= e1)
                a(k+1) = double(x1);
                b(k+1) = double(x2);
                break
            else
                X = [x1 x2]' - ([F11 F12; F21 F22] \ [F1 F2]');
                x1 = X(1, 1);
                x2 = X(2, 1);
            end
        end
        
        d = sqrt((a(k+1) - a(k))^2 + (b(k+1) - b(k))^2);
        r(k+1) = a_scalar * r(k);
        k = k + 1;
    end
    

    总结

    通过上述修正,两个程序的错误都得到了解决。第一个程序中,通过使用subs函数将符号变量替换为具体数值,避免了double函数转换失败的问题。第二个程序中,通过重新定义a为标量,解决了赋值时元素数目不匹配的问题。

    如果该回答解决了您的问题,请采纳!如果没有,请私信联系或评论您的疑惑

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(10条)

报告相同问题?

问题事件

  • 系统已结题 12月3日
  • 已采纳回答 11月25日
  • 创建了问题 11月25日