title: 數學規划模型——整數規划問題
date: 2020-02-27 00:37:35
categories: 數學建模
tags: [MATLAB, 數學規划模型]
整數規划
整數規划:
-
線性整數規划 - Matlab可進⾏求解 (線性的意思 在線性規划的基礎上 , 加⼊決策變量取整數的條件)
-
⾮線性整數規划 → ⽆特定算法, 只能⽤近似算法 , 如蒙特卡羅模擬 、 智能算法 ( 后續會講到)
特例: 特殊的整數規划 , Matlab中也只能求解線性01規划, 對於⾮線性 0-1規划也只能近似求解 。 (數模⽐賽中常出現)
Matlab整數規划求解
線性整數規划求解
[x ,fval] = linprog [ c, A, b, Aeq, beq, lb, ub, X0] -> 線性規划的函數
[x ,fval] = intlinprog [ c, intconA, b, Aeq, beq, lb, ub]→ 線性整數規划的求解
注 :
- intlinpng 不能指定初始值 ;
- 加⼊了 inton 參數可以指定哪些決策變量是整數。
例如決策變量有三個 : x1,x2,x3 ; 若x1和x3,是整數 , 則 intcon= [1 , 3] 。
線性 0-1規划求解
仍然使⽤intlinprog 函數 , 只不過在 lb和ub上作⽂章 。
例如決策變量有三個 : x1,x2,x3 ; 若x1和x3是0-1變量,x2不限制, 則 intcon= [1 , 3] ,lb=[0 -inf 0]',ub=[1,+inf,1]。
小例題
%% 線性整數規划問題
%% 例1
c=[-20,-10]';
intcon=[1,2]; % x1和x2限定為整數
A=[5,4;
2,5];
b=[24;13];
lb=zeros(2,1);
[x,fval]=intlinprog(c,intcon,A,b,[],[],lb)
fval = -fval
%% 例2
c=[18,23,5]';
intcon=3; % x3限定為整數
A=[107,500,0;
72,121,65;
-107,-500,0;
-72,-121,-65];
b=[50000;2250;-500;-2000];
lb=zeros(3,1);
[x,fval]=intlinprog(c,intcon,A,b,[],[],lb)
%% 例3
c=[-3;-2;-1]; intcon=3; % x3限定為整數
A=ones(1,3); b=7;
Aeq=[4 2 1]; beq=12;
lb=zeros(3,1); ub=[+inf;+inf;1]; %x(3)為0-1變量
[x,fval]=intlinprog(c,intcon,A,b,Aeq,beq,lb,ub)
整數規划的典型例題
背包問題
%% 背包問題(貨車運送貨物的問題)
c = -[540 200 180 350 60 150 280 450 320 120]; % 目標函數的系數矩陣(最大化問題記得加負號)
intcon=[1:10]; % 整數變量的位置(一共10個決策變量,均為0-1整數變量)
A = [6 3 4 5 1 2 3 5 4 2]; b = 30; % 線性不等式約束的系數矩陣和常數項向量(物品的重量不能超過30)
Aeq = []; beq =[]; % 不存在線性等式約束
lb = zeros(10,1); % 約束變量的范圍下限
ub = ones(10,1); % 約束變量的范圍上限
%最后調用intlinprog()函數
[x,fval]=intlinprog(c,intcon,A,b,Aeq,beq,lb,ub)
fval = -fval
指派問題
%% 指派問題(選擇隊員去進行游泳接力比賽)
clear;clc
c = [66.8 75.6 87 58.6 57.2 66 66.4 53 78 67.8 84.6 59.4 70 74.2 69.6 57.2 67.4 71 83.8 62.4]'; % 目標函數的系數矩陣(先列后行的寫法)
intcon = [1:20]; % 整數變量的位置(一共20個決策變量,均為0-1整數變量)
% 線性不等式約束的系數矩陣和常數項向量(每個人只能入選四種泳姿之一,一共五個約束)
A = [1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1];
% A = zeros(5,20);
% for i = 1:5
% A(i, (4*i-3): 4*i) = 1;
% end
b = [1;1;1;1;1];
% 線性等式約束的系數矩陣和常數項向量 (每種泳姿有且僅有一人參加,一共四個約束)
Aeq = [1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0;
0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0;
0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0;
0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1];
% Aeq = [eye(4),eye(4),eye(4),eye(4),eye(4)]; % 或者寫成 repmat(eye(4),1,5)
% Aeq=zeros(4,20);
% for i = 1:4
% for j =1:20
% if mod(j,4)==i
% Aeq(i,j)=1;
% end
% if i==4
% if mod(j,4)==0
% Aeq(i,j)=1;
% end
% end
% end
% end
beq = [1;1;1;1];
lb = zeros(20,1); % 約束變量的范圍下限
ub = ones(20,1); % 約束變量的范圍上限
%最后調用intlinprog()函數
[x,fval] = intlinprog(c,intcon,A,b,Aeq,beq,lb,ub)
% reshape(x,4,5)'
% 0 0 0 1 甲自由泳
% 1 0 0 0 乙蝶泳
% 0 1 0 0 丙仰泳
% 0 0 1 0 丁蛙泳
% 0 0 0 0 戊不參加
鋼管切割問題
%% 鋼管切割問題
%% (1)枚舉法找出同一個原材料上所有的切割方法
for i = 0: 2 % 2.9m長的圓鋼的數量
for j = 0: 3 % 2.1m長的圓鋼的數量
for k = 0:6 % 1m長的圓鋼的數量
if 2.9*i+2.1*j+1*k >= 6 & 2.9*i+2.1*j+1*k <= 6.9
disp([i, j, k])
end
end
end
end
%% (2) 線性整數規划問題的求解
c = ones(7,1); % 目標函數的系數矩陣
intcon=[1:7]; % 整數變量的位置(一共7個決策變量,均為整數變量)
A = -[1 2 0 0 0 0 1;
0 0 3 2 1 0 1;
4 1 0 2 4 6 1]; % 線性不等式約束的系數矩陣
b = -[100 100 100]'; % 線性不等式約束的常數項向量
lb = zeros(7,1); % 約束變量的范圍下限
[x,fval]=intlinprog(c,intcon,A,b,[],[],lb)