MATLAB分支定界法

最近一直在看建模老哥的课,在分支定界法这块他的代码我跑起来一直报错,打了很多断点也是没能发现问题所在,在网上搜索出现的基本都是和他一样的代码,我不知道其他人是否能正常运行,但是我实在是不行,所以干脆重写。

function [x, fval, status] = Branch_Bound(f, A, B, Aeq, Beq, lb, ub, fcheck, e)
    if nargin < 9, e = 1e-10; end
    if nargin < 8, fcheck = 1; end %-1求最大值
    if nargin < 7, ub = []; end
    if nargin < 6, lb = []; end
    if nargin < 5, Beq = []; end
    if nargin < 4, Aeq = []; end
    if nargin < 3, B = []; end
    if nargin < 2 || isempty(f)
        error('Not enough input arguments. ');
    end
    options = optimset('display', 'off');
    [xx, fvalx, exitflag] = linprog(f, A, B, Aeq, Beq, lb, ub, [], options);
    if exitflag < 0
        disp('No feasible integer solution found.');
        x = xx;
        fval = fvalx;
        status = exitflag;
        return;
    else
        [x, fval, status] = branch_bound(f, A, B, Aeq, Beq, lb, ub, e, 1:length(f), xx, fvalx, inf, -1);
        if fcheck==-1
            fval=-fval;
        end
    end
end

function [x, fval, status, bound] = branch_bound(f, A, B, Aeq, Beq, lb, ub, e, I, x, fval, bound, parent)
    %%因为存在多重递归,为了防止局部变量只在函数体内部变化,我们把关键变量定义为全局变量
    %xr 当前最优解 
    % fr当前最优值 
    % bound当前边界
    global xr;
    global fr;
    global bound;
    options = optimoptions('linprog', 'Display', 'off');
    if all(abs(x(I) - round(x(I))) <= e)%终止条件,全为整数解
        status = 1;
        return;
    end
    intindex = I(find(abs(x(I) - round(x(I))) > e, 1));%获取最近的非整数解
    %%增加约束分枝
    n = intindex;
    addA = zeros(1, length(f));
    addA(n) = 1;
    A1 = [A; addA];
    B1 = [B; floor(x(n))];
    [x1, fval1, status1] = linprog(f, A1, B1, Aeq, Beq, lb, ub, [], options);
    A2 = [A; -addA];
    B2 = [B; -ceil(x(n))];
    [x2, fval2, status2] = linprog(f, A2, B2, Aeq, Beq, lb, ub, [], options);

    %%定界 
    if status1 > 0 && fval1 < bound
        [x, fval, status, bound] = branch_bound(f, A1, B1, Aeq, Beq, lb, ub, e, I, x1, fval1, bound, n);
        if status == 1
            bound = min(bound, fval);
            x=x1;
            fval=fval1;
        end
    else
        status = -1;
        return;
    end
    if status==1&&fval<=bound  %给全局变量赋值以记录当前最优解,并更新迭代
        xr=x;
        fr=fval;
    end
    if status2 > 0 && fval2 < bound
        [x, fval, status, bound] = branch_bound(f, A2, B2, Aeq, Beq, lb, ub, e, I, x2, fval2, bound, n);
        
        if status == 1
            bound = min(bound, fval);
        end
    else
        status = -1;
        return;
    end
    if parent ~= -1 && all(abs(x - round(x)) > e)
        status = -1;
        return;
    end
    if status==1&&fval<=bound   %给全局变量赋值以记录当前最优解,并更新迭代
        xr=x;
        fr=fval;
    end
    %%将结果赋值给输出
    x=xr;
    fval=fr;
end

测试了三组数据,和割平面等其他算法结果一致,这里不再演示,可以用数据自己进行测试,如有疑问可以评论区讨论

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值