一、概述
1、定义:规划中变量部分或全部定义成整数是,称为整数规划。
2、分诶:纯整数规划和混合整数规划。
3、特点:
(1)原线性规划有最优解,当自变量限制为整数后:
a、原最优解全是整数,那最优解仍成立
b、整数规划没有可行解
c、有可行解,但是不是原最优解
4、求解方法分类
(1)分支定界法
(2)割平面法
(3)隐枚举法
(4)匈牙利法
(5)蒙特卡洛法
二、分支定界法
1、算法如下(求解整数规划最大化问题)
MATLAB实现
function r=checkint(x) %判断x(i)是不是整数了。是的话r(i)返回1,不是的话,返回0 %输入参数:x X向量 %输出参数:r R向量 for i=1:length(x) if(min(abs(x(i)-floor(x(i))),abs(x(i)-ceil(x(i))))<1e-3) r(i)=1; else r(i)=0; end end
function val=isrowinmat(arow,mat) %用来判断mat中是否包含与arow一样的向量 %输入变量:arow 向量 % mat 矩阵 %输出变量:val 1表示有,0表示没有 val=0; rows=size(mat,1); for i=1:rows temp=(mat(i,:)==arow); if length(find(temp==0))==0 val=1; return; else val=0; end; end
function [x,fval,exitflag,output,lambda]=linprogdis(ifint,f,A,b,Aeq,beq,lb,ub,x0,options) % 用法 % [x,fval,exitflag,output,lambda]=lpint(ifint.f,A,b,Aeq,beq) % [x,fval,exitflag,output,lambda]=lpint(ifint,f,A,b,Aeq,beq,lb) % [x,fval,exitflag,output,lambda]=lpint(ifint,f,A,b,Aeq,beq,lb,ub) % [x,fval,exitflag,output,lambda]=lpint(ifint,f,A,b,Aeq,beq,lb,ub,x0) % [x,fval,exitflag,output,lambda]=lpint(ifint,f,A,b,Aeq,beq,lb,ub,x0,options) if nargin<10, options=[]; end if nargin<9, x0=[]; end if nargin<8, ub=inf*ones(size(f)); end if nargin<7, lb=zeros(size(f)); end [x,fval,exitflag,output,lambda]=linprog(f,A,b,Aeq,beq,lb,ub,x0,options); if exitflag<=0 %表示线性规划没有最优解 return end v1=find(ifint==1); %找到需要整数规划的变量的下标 temp=x(v1);%如果不是要求整数规划的就可以返回了。 if isempty(temp) return end v2=find(checkint(temp)==0); if isempty(v2) %都是整数,得到最众解 return end k=v1(v2(1)); temp1=zeros(1,length(f)); temp1(k)=1; low=floor(x(k)); if isrowinmat([temp1,low],[A,b])==1 thisA=A; thisb=b; else thisA=[A;temp1]; thisb=b; thisb(end+1)=low; end [x1,fval1,exitflag1,output1,lambda1]=linprogdis(ifint,f,thisA,thisb,Aeq,beq,lb,ub,x0,options); temp2=zeros(1,length(f)); temp2(k)=-1; high=-ceil(x(k)); if isrowinmat([temp2,high],[A,b])==1 thisA=A; thisb=b; else thisA=[A;temp2]; thisb=b; thisb(end+1)=high; end [x2,fval2,exitflag2,output2,lambda2]=linprogdis(ifint,f,thisA,thisb,Aeq,beq,lb,ub,x0,options); if (isempty(v2) && ((exitflag1>0 && exitflag2<=0 && fval<=fval)||(exitflag2>0 && exitflag1<=0 && fval<=fval2)||(exitflag1>0 && exitflag2>0 && fval<=fval1 && fval<=fval2))) disp(‘error call‘); return ; %表示都是整数 end if exitflag1>0&&exitflag2<=0 x=x1; fval=fval1; exitflag=exitflag1; output=output1; lambda=lambda1; elseif exitflag1<=0&&exitflag2>0 x=x2; fval=fval2; exitflag=exitflag2; output=output2; lambda=lambda2; elseif exitflag1>0 && exitflag2>0 if fval1<fval2 x=x1; fval=fval1; exitflag=exitflag1; output=output1; lambda=lambda1; else x=x2; fval=fval2; exitflag=exitflag2; output=output2; lambda=lambda2; end end
时间: 2024-09-30 20:37:56