求解线性规化(求极大、极小值)方法的源程序 (200分)

  • 主题发起人 主题发起人 tom12345
  • 开始时间 开始时间
T

tom12345

Unregistered / Unconfirmed
GUEST, unregistred user!
求解线性规化(求极大、极小值)方法的源程序,其中,各变量可以有上、下界。
 
源程序没有,思路有一个:
南航学报上有一个什么破算法(好象叫什么最小覆盖线法),一个反例就能把他干倒.
先用贪心法求一解,以此解为基础在所有解空间中用分支定界法求最优解
 
//解线性规划的用乘数的单纯形法
//问题:x0 + Sum{j = 1..n;
a[0, j] * x[j]} = a[0, 0] (1)
// Sum{a[i, j] * x[j] = a[i, 0] (i = 1..m) (2)
// x[j] >= 0 (j = 1..n) (3)
//即求出满足约束条件(2)和(3)、且使目标函数x0为极小或极大的
//x = (x[j1], x[j2], ..., x[jm], 0, ..., 0)。
//其中,a[i, j] (i = 0..m;
j = 0..n)开始时给定,在求解过程中
//被不断地改变。
//
//参数:
//d 指示值。当d = -1时解极大问题,d = 1时解极小问题
//m 线性规划问题的阶数(即约束条件数)
//n 线性规划问题的维数(为原给的线性规划问题的变量数加m
// 详见例子
//id 数组id[0..m],存放基本变量的下标,开始时id[0] = 0,
// id = n - m + i (i = 1..m)
//a 数组a[0..m, 0..n],开始时存放线性规划问题的全部给定
// 数据,在求解过程中其值不断改变(具体存放方式见例子)
//k 指示量,计算结束时如果k = 0则表示线性线性规划问题有
// 有限最优解。
//常数说明:
//PSUMChangeBaseZero 规定老基变新基运算中的无穷小量
//PSUMAccumulateZero 为减小由于舍入误差的积累造成错误允许值,
// 用于引进新基本变量
//PSUMZero 在决定应从原来的基本变量中去掉的基本变量的
// 下标时,为减小舍入误差的影响而使用的无穷小。
//例子:
// x0 -1.1 x1 - 2.2 x2 + 3.3 x3 - 4.4 x4 = 0
// x1 + x2 + 2 x3 = 4
// x1 + 2 x2 + 2.5 x3 + 3 x4 = 5
//d = -1, m = 2, 变量数 = 4,于是:
//m = 2, n = 4 + m = 6,
//a = 0, -1.1, -2.2, 3.3, -4.4, (0), (0) //后面补m个0
// 4, 1, 1, 2, 0, (1), (0) //后面形成单位阵
// 5, 1, 2, 2.5, 3, (0), (1)
type
TMatrix = array of array of Extended;
const
PSUMInfinity: Extended = 1E30;
PSUMChangeBaseZero: Extended = 1E-15;
PSUMAccumulateZero: Extended = 1E-15;
PSUMZero: Extended = 1E-15;
procedure PSUM(d: Integer;
m, n: Integer;
var id: array of Integer;
a: TMatrix;
var k: Integer);
implementation
procedure PSUM(d: Integer;
m, n: Integer;
var id: array of Integer;
a: TMatrix;
var k: Integer);
var
i, j, L: Integer;
f, exm: Extended;
function SI(c, cr: Extended): Extended;
begin
if Abs(c) > cr then
Result := c else
Result := 0;
end;

begin
repeat
exm := PSUMInfinity * d;
k := -1;
for j := 1 to ndo
if (d * a[0, j] > PSUMAccumulateZero)
and (-d * (a[0, j] - exm) > 0) then
begin
exm := a[0, j];
k := j;
end;
if k = -1 then
begin
k := 0;
Break;
end;
if k > n - m then
Break;
exm := PSUMInfinity;
L := -1;
for i := 1 to mdo
begin
f := a[i, 0] / a[i, k];
if (a[i, k] > PSUMChangeBaseZero)
and (exm > f) then
begin
exm := f;
L := i;
end;
end;
if L = -1 then
Break;
id[L] := k;
for j := 0 to ndo
if j <> k then
a[L, j] := a[L, j] / a[L, k];
a[L, k] := 1;
for i := 0 to mdo
if i <> L then
begin
for j := 0 to ndo
if j <> k then
a[i, j] := SI(a[i, j] - a[L, j] * a[i, k], PSUMChangeBaseZero);
a[i, k] := SI(a[i, k] * (1 - a[L, k]), PSUMChangeBaseZero);
end;
until False;
end;

例子:
var
a: TMatrix;
id: array [0..2] of Integer;
k: Integer;
begin
SetLength(a, 3, 7);
a[0, 0] := 0;
a[0, 1] := -1.1;
a[0, 2] := -2.2;
a[0, 3] := 3.3;
a[0, 4] := -4.4;
a[0, 5] := 0;
a[0, 6] := 0;
a[1, 0] := 4;
a[1, 1] := 1;
a[1, 2] := 1;
a[1, 3] := 2;
a[1, 4] := 0;
a[1, 5] := 1;
a[1, 6] := 0;
a[2, 0] := 5;
a[2, 1] := 1;
a[2, 2] := 2;
a[2, 3] := 2.5;
a[2, 4] := 3;
a[2, 5] := 0;
a[2, 6] := 1;
id[0] := 0;
id[1] := 4;
id[2] := 5;
PSUM(-1, 2, 6, id, a, k);
if k = 0 then
ShowMessage('failed')
else

ShowMessage(Format('Base variables: x%d = %f, x%d = %f, max x0 = %f',
[id[1], a[1, 0], id[2], a[2, 0], a[0, 0]]));
end;
注:如果要改变上界或下界,那么要添加变量数来调整矩阵A
如:下界:x2 > 3
则要添加一个变量和一个约束:
x2 - x[k] = 3
上界:x2 < 10
则要添加一个变量和一个约束:
x2 + x[k] = 10
其中k为原变量数 + 1
 
线性规划一般用单纯形法及对偶算法。
好的算法要注意灵敏度的分析,以前上大学学这的时候写过一个,现在却有些生疏了!
这几天好好重温一下!
 
TO LeeChange:
分支定界法只对整数线性规划有效!如果只是这个,那问题简单多了。
用割平面法或者隐枚举法也可以实现!
其实说来说去最终都是一个可行解的问题,建议看看书,把二分算法和P分算法看透彻再说!
 
请问 JohnsonGuo,以下例子为什么运行错误?
求 x0 = x2 - 3 x3 + 2 x5 的最小值。
约束条件:
x1 + 3 x2 - x3 + 2 x5 = 7
- 2 x2 + 4 x3 + x4 = 12
- 4 x2 + 3 x3 + 8 x5 + x6 = 10
d = 1, m = 3, 变量数 = 6,于是:
m = 3, n = 6 + m = 9
Var
a: TMatrix;
id: array [0..3] of Integer;
k: Integer;
begin
SetLength(a, 4, 10);
a[0, 0] := 0;
a[0, 1] := 0;
a[0, 2] :=-1;
a[0, 3] := 3;
a[0, 4] := 0;
a[0, 5] :=-2;
a[0, 6] := 0;
a[0, 7] := 0;
a[0, 8] := 0;
a[0, 9] := 0;
a[1, 0] := 7;
a[1, 1] := 1;
a[1, 2] := 3;
a[1, 3] :=-1;
a[1, 4] := 0;
a[1, 5] := 2;
a[1, 6] := 0;
a[1, 7] := 1;
a[1, 8] := 0;
a[1, 9] := 0;
a[2, 0] :=12;
a[2, 1] := 0;
a[2, 2] :=-2;
a[2, 3] := 4;
a[2, 4] := 1;
a[2, 5] := 0;
a[2, 6] := 0;
a[2, 7] := 0;
a[2, 8] := 1;
a[2, 9] := 0;
a[3, 0] :=10;
a[3, 1] := 0;
a[3, 2] :=-4;
a[3, 3] := 3;
a[3, 4] := 0;
a[3, 5] := 8;
a[3, 6] := 1;
a[3, 7] := 0;
a[3, 8] := 0;
a[3, 9] := 1;
id[0] := 0;
id[1] := 6;
id[2] := 7 ;
id[3] := 8;
PSUM(1, 3, 9, id, a, k);
if k = 0 then
ShowMessage('failed')
else
ShowMessage(Format('Base variables: x%d = %f, x%d = %f, max x0 = %f',
[id[1], a[1, 0], id[2], a[2, 0], a[0, 0]]));
end;

运行显示 failed。
正确结果应为: x1=0, x2=4, x3=5, x4=0, x5=0, x6=11, x0_min=-11
 
JohnsonGuo,你看到了我的问题吗?
 
看来这个问题比较难,我愿意再加300分.
 
线性规划问题好像组合数学书上讲过,你去图书馆找一找这方面的书!
 
多人接受答案了。
 
后退
顶部