当前位置:   article > 正文

数学建模之matlab中线性规划_matlab线性规划

matlab线性规划

目录

一、线性规划的标准形式

二、整数规划

二、整数规划之分支定界

1.概念

2、代码实现

三、整数规划之割平面法

1、基本思想

 2、代码实现

四、整数规划之匈牙利算法(0-1)

1、适用情况

①0-1变量的使用

② 互斥问题

 ③固定费用问题

④指派问题

 2、指派问题中匈牙利法

①步骤

②举例

 3、代码实现

总结



一、线性规划的标准形式

求的是max,所以f中要加符号。f中是目标函数的系数

a表示的是不等式约束的系数(有不等号的,并且不等号为<)

b表示不等号后面的数

aeq表示线性约束的系数(有等号的系数)

beq表示等号后面的数

lb和ub表示最小值和最大值

(这里的zeros(3,1)表示创建3*1的数组,值都是0


二、整数规划

1、概念

 

 2、一般形式

 

 

二、整数规划之分支定界

1.概念

 

 举例:

2、代码实现

matlab中代码:首先定义两个函数,然后再写一个测试脚本

  1. function [x,fval,status] = intprog(f,A,B,I,Aeq,Beq,lb,ub,e)
  2. %整数规划求解函数 intprog()
  3. % 其中 f为目标函数向量
  4. % A和B为不等式约束 Aeq与Beq为等式约束
  5. % I为整数约束
  6. % lb与ub分别为变量下界与上界
  7. % x为最优解,fval为最优值
  8. %例子:
  9. % maximize 20 x1 + 10 x2
  10. % S.T.
  11. % 5 x1 + 4 x2 <=24
  12. % 2 x1 + 5 x2 <=13
  13. % x1, x2 >=0
  14. % x1, x2是整数
  15. % f=[-20, -10];
  16. % A=[ 5 4; 2 5];
  17. % B=[24; 13];
  18. % lb=[0 0];
  19. % ub=[inf inf];
  20. % I=[1,2];
  21. % e=0.000001;
  22. % [x v s]= IP(f,A,B,I,[],[],lb,ub,,e)
  23. % x = 4 1 v = -90.0000 s = 1
  24. % 控制输入参数
  25. if nargin < 9, e = 0.00001;
  26. if nargin < 8, ub = [];
  27. if nargin < 7, lb = [];
  28. if nargin < 6, Beq = [];
  29. if nargin < 5, Aeq = [];
  30. if nargin < 4, I = [1:length(f)];
  31. end, end, end, end, end, end
  32. %求解整数规划对应的线性规划,判断是否有解
  33. options = optimset('display','off');
  34. [x0,fval0,exitflag] = linprog(f,A,B,Aeq,Beq,lb,ub,[],options);
  35. if exitflag < 0
  36. disp('没有合适整数解');
  37. x = x0;
  38. fval = fval0;
  39. status = exitflag;
  40. return;
  41. else
  42. %采用分支定界法求解
  43. bound = inf;
  44. [x,fval,status] = branchbound(f,A,B,I,x0,fval0,bound,Aeq,Beq,lb,ub,e);
  45. end
  1. function [newx,newfval,status,newbound] = branchbound(f,A,B,I,x,fval,bound,Aeq,Beq,lb,ub,e)
  2. % 分支定界法求解整数规划
  3. % f,A,B,Aeq,Beq,lb,ub与线性规划相同
  4. % I为整数限制变量的向量
  5. % x为初始解,fval为初始值
  6. options = optimset('display','off');
  7. [x0,fval0,status0]=linprog(f,A,B,Aeq,Beq,lb,ub,[],options);
  8. %递归中的最终退出条件
  9. %无解或者解比现有上界大则返回原解
  10. if status0 <= 0 || fval0 >= bound
  11. newx = x;
  12. newfval = fval;
  13. newbound = bound;
  14. status = status0;
  15. return;
  16. end
  17. %是否为整数解,如果是整数解则返回
  18. intindex = find(abs(x0(I) - round(x0(I))) > e);
  19. if isempty(intindex) %判断是否为空值
  20. newx(I) = round(x0(I));
  21. newfval = fval0;
  22. newbound = fval0;
  23. status = 1;
  24. return;
  25. end
  26. %当有非整可行解时,则进行分支求解
  27. %此时必定会有整数解或空解
  28. %找到第一个不满足整数要求的变量
  29. n = I(intindex(1));
  30. addA = zeros(1,length(f));
  31. addA(n) = 1;
  32. %构造第一个分支 x<=floor(x(n))
  33. A = [A;addA];
  34. B = [B,floor(x(n))];%向下取整
  35. [x1,fval1,status1,bound1] = branchbound(f,A,B,I,x0,fval0,bound,Aeq,Beq,lb,ub,e);
  36. A(end,:) = [];
  37. B(:,end) = [];
  38. %解得第一个分支,若为更优解则替换,若不是则保持原状
  39. status = status1;
  40. if status1 > 0 && bound1 < bound
  41. newx = x1;
  42. newfval = fval1;
  43. bound = fval1;
  44. newbound = bound1;
  45. else
  46. newx = x0;
  47. newfval = fval0;
  48. newbound = bound;
  49. end
  50. %构造第二分支
  51. A = [A;-addA];
  52. B = [B,-ceil(x(n))];%向上取整
  53. [x2,fval2,status2,bound2] = branchbound(f,A,B,I,x0,fval0,bound,Aeq,Beq,lb,ub,e);
  54. A(end,:) = [];
  55. B(:,end) = [];
  56. %解得第二分支,并与第一分支做比较,如果更优则替换
  57. if status2 > 0 && bound2 < bound
  58. status = status2;
  59. newx = x2;
  60. newfval = fval2;
  61. newbound = bound2;
  62. end

 测试:

  1. f=[-20 -10];
  2. A=[5 4;2 5];
  3. B=[24 13];
  4. lb=[0 0];
  5. [x,fval,status]= intprog(f,A,B,[1,2],[],[],lb)

三、整数规划之割平面法

1、基本思想

 

实例:

引入松弛变量 x7 x8 x9 x10

 2、代码实现

 定义一个函数DIvidePlane

  1. function [intx,intf] = DividePlane(A,c,b,baseVector)
  2. %功能:用割平面法求解整数规划
  3. %调用格式:[intx,intf]=DividePlane(A,c,b,baseVector)
  4. %其中, A:约束矩阵;
  5. % c:目标函数系数向量;
  6. % b:约束右端向量;
  7. % baseVector:初始基向量;
  8. % intx:目标函数取最值时的自变量值;
  9. % intf:目标函数的最值;
  10. sz = size(A);
  11. nVia = sz(2);%获取有多少决策变量
  12. n = sz(1);%获取有多少约束条件
  13. xx = 1:nVia;
  14. if length(baseVector) ~= n
  15. disp('基变量的个数要与约束矩阵的行数相等!');
  16. mx = NaN;
  17. mf = NaN;
  18. return;
  19. end
  20. M = 0;
  21. sigma = -[transpose(c) zeros(1,(nVia-length(c)))];
  22. xb = b;
  23. %首先用单纯形法求出最优解
  24. while 1
  25. [maxs,ind] = max(sigma);
  26. %--------------------用单纯形法求最优解--------------------------------------
  27. if maxs <= 0 %当检验数均小于0时,求得最优解。
  28. vr = find(c~=0 ,1,'last');
  29. for l=1:vr
  30. ele = find(baseVector == l,1);
  31. if(isempty(ele))
  32. mx(l) = 0;
  33. else
  34. mx(l)=xb(ele);
  35. end
  36. end
  37. if max(abs(round(mx) - mx))<1.0e-7 %判断最优解是否为整数解,如果是整数解。
  38. intx = mx;
  39. intf = mx*c;
  40. return;
  41. else %如果最优解不是整数解时,构建切割方程
  42. sz = size(A);
  43. sr = sz(1);
  44. sc = sz(2);
  45. [max_x, index_x] = max(abs(round(mx) - mx));
  46. [isB, num] = find(index_x == baseVector);
  47. fi = xb(num) - floor(xb(num));
  48. for i=1:(index_x-1)
  49. Atmp(1,i) = A(num,i) - floor(A(num,i));
  50. end
  51. for i=(index_x+1):sc
  52. Atmp(1,i) = A(num,i) - floor(A(num,i));
  53. end
  54. Atmp(1,index_x) = 0; %构建对偶单纯形法的初始表格
  55. A = [A zeros(sr,1);-Atmp(1,:) 1];
  56. xb = [xb;-fi];
  57. baseVector = [baseVector sc+1];
  58. sigma = [sigma 0];
  59. %-------------------对偶单纯形法的迭代过程----------------------
  60. while 1
  61. %----------------------------------------------------------
  62. if xb >= 0 %判断如果右端向量均大于0,求得最优解
  63. if max(abs(round(xb) - xb))<1.0e-7 %如果用对偶单纯形法求得了整数解,则返回最优整数解
  64. vr = find(c~=0 ,1,'last');
  65. for l=1:vr
  66. ele = find(baseVector == l,1);
  67. if(isempty(ele))
  68. mx_1(l) = 0;
  69. else
  70. mx_1(l)=xb(ele);
  71. end
  72. end
  73. intx = mx_1;
  74. intf = mx_1*c;
  75. return;
  76. else %如果对偶单纯形法求得的最优解不是整数解,继续添加切割方程
  77. sz = size(A);
  78. sr = sz(1);
  79. sc = sz(2);
  80. [max_x, index_x] = max(abs(round(mx_1) - mx_1));
  81. [isB, num] = find(index_x == baseVector);
  82. fi = xb(num) - floor(xb(num));
  83. for i=1:(index_x-1)
  84. Atmp(1,i) = A(num,i) - floor(A(num,i));
  85. end
  86. for i=(index_x+1):sc
  87. Atmp(1,i) = A(num,i) - floor(A(num,i));
  88. end
  89. Atmp(1,index_x) = 0; %下一次对偶单纯形迭代的初始表格
  90. A = [A zeros(sr,1);-Atmp(1,:) 1];
  91. xb = [xb;-fi];
  92. baseVector = [baseVector sc+1];
  93. sigma = [sigma 0];
  94. continue;
  95. end
  96. else %如果右端向量不全大于0,则进行对偶单纯形法的换基变量过程
  97. minb_1 = inf;
  98. chagB_1 = inf;
  99. sA = size(A);
  100. [br,idb] = min(xb);
  101. for j=1:sA(2)
  102. if A(idb,j)<0
  103. bm = sigma(j)/A(idb,j);
  104. if bm<minb_1
  105. minb_1 = bm;
  106. chagB_1 = j;
  107. end
  108. end
  109. end
  110. sigma = sigma -A(idb,:)*minb_1;
  111. xb(idb) = xb(idb)/A(idb,chagB_1);
  112. A(idb,:) = A(idb,:)/A(idb,chagB_1);
  113. for i =1:sA(1)
  114. if i ~= idb
  115. xb(i) = xb(i)-A(i,chagB_1)*xb(idb);
  116. A(i,:) = A(i,:) - A(i,chagB_1)*A(idb,:);
  117. end
  118. end
  119. baseVector(idb) = chagB_1;
  120. end
  121. %------------------------------------------------------------
  122. end
  123. %--------------------对偶单纯形法的迭代过程---------------------
  124. end
  125. else %如果检验数有不小于0的,则进行单纯形算法的迭代过程
  126. minb = inf;
  127. chagB = inf;
  128. for j=1:n
  129. if A(j,ind)>0
  130. bz = xb(j)/A(j,ind);
  131. if bz<minb
  132. minb = bz;
  133. chagB = j;
  134. end
  135. end
  136. end
  137. sigma = sigma -A(chagB,:)*maxs/A(chagB,ind);
  138. xb(chagB) = xb(chagB)/A(chagB,ind);
  139. A(chagB,:) = A(chagB,:)/A(chagB,ind);
  140. for i =1:n
  141. if i ~= chagB
  142. xb(i) = xb(i)-A(i,ind)*xb(chagB);
  143. A(i,:) = A(i,:) - A(i,ind)*A(chagB,:);
  144. end
  145. end
  146. baseVector(chagB) = ind;
  147. end
  148. M = M + 1;
  149. if (M == 1000000)
  150. disp('找不到最优解!');
  151. mx = NaN;
  152. minf = NaN;
  153. return;
  154. end
  155. end

举例:


 
>> c = [-1;-1]; % 不要加松弛变量
A = [-1 1 1 0;3 1 0 1]; % 加上松弛变量
b = [1;4];
[x fval] = DividePlane(A,c,b,[3 4]); % 松弛变量 3 4

>> x

x =

    1.0000    1.0000

>> maxz=-fval%求得最大值,加负号

maxz =

     2

四、整数规划之匈牙利算法(0-1)

1、适用情况

①0-1变量的使用

② 互斥问题

 

 ③固定费用问题

④指派问题

 

 

 

 2、指派问题中匈牙利法

①步骤

 

 

 

②举例

 

 

 

 3、代码实现

例子1

  1. c = [3 8 2 10 3;8 7 2 9 7;6 4 2 7 5;8 4 2 3 5;9 10 6 9 10]
  2. c = c(:); % 矩阵转换为向量
  3. a = zeros(10,25);
  4. for i = 1:5
  5. a(i,(i-1)*5+1:5*i) = 1;
  6. a(5+i,i:5:25) = 1;
  7. end % 循环将指派问题转换为线性规划问题
  8. b= ones(10,1); % 10个约束(5*2)
  9. [x y] = linprog(c,[],[],a,b,zeros(25,1),ones(25,1));
  10. X = reshape(x,5,5)
  11. opt = y

 

 例子2:

 %% 指派问题(选择队员去进行游泳接力比赛)
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)  
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    戊不参加

 (感觉这个例子很实用,就引用过来了,要是有啥侵权,告诉我我删掉,不好意思)


总结

以上为线性规划中算法代码,图片来自数学建模老哥课上ppt,仅为笔记。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/354686?site
推荐阅读
相关标签
  

闽ICP备14008679号