Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лекции рогов / Рогов_лек_7_транспорт_з.doc
Скачиваний:
43
Добавлен:
10.02.2015
Размер:
1.3 Mб
Скачать

4. Решение транспортной задачи методом потенциалов

Метод потенциалов решения транспортной задачи был разработан российским ученым, академиком Л.В. Канторовичем. Его идея аналогична симплекс–методу. Сначала строится допустимое базисное решение (например, методом северо–западного угла), затем оно последовательно улучшается с помощью цикла пересчета подходящей свободной клетки в таблице перевозок.

После построения начального допустимого базисного решения множество всех переменных системы уравнений можно разбить на два подмножества: – множество базисных переменных и–множество свободных переменных. Для анализа построенного базисного решения на оптимальность, нужно выразить функциюS–суммарную стоимость всех перевозок через свободные переменные:

(1) S=

Здесь свободный член равен стоимости всех перевозок построенного базисного решения. Очевидно, базисное решение будет оптимальным, если все коэффициенты при свободных переменныхбудут неотрицательными – в этом случаеminS=достигается при нулевых значениях свободных переменных.

Критерий оптимальности базисного решения: базисное решение оптимально тогда и только тогда, когда в выражении (1) функцииSчерез свободные переменные все коэффициенты при свободных переменных0.

Л.В. Канторович указал способ вычисления коэффициентов . Для этого он связал с каждой станцией отправленияновую переменную(потенциал станции), а с каждым пунктом потребления– другую новую переменную(потенциал пункта). Если задача имеет размерыmn, то получаетсяm+nнеизвестных потенциалов Для вычисления потенциалов составляется система уравнений (2):

(2)

где тариф соответствующей базисной клетки. Таким образом, в системе (2)m+n– 1 уравнений (число базисных клеток) иm+nнеизвестных потенциалови. Используя теорию двойственности, можно доказать, что ранг системы (2) совпадает с рангом системы ограничений транспортной задачи, т.е. равенm+n– 1.

Поэтому одна из переменных илиявляется свободной (например,), ее значение можно выбрать произвольно, значения остальных потенциалов находятся из уравнений системы (2).

Теорема Канторовича:коэффициент, с которым свободная переменнаявходит в выражение (1) функцииSчерез свободные переменные, вычисляется по формуле (3):

(3) =

Доказательство теоремы можно найти в [9].

Алгоритм метода потенциалов решения сбалансированной задачи :

1. Составляем математическую модель транспортной задачи.

2. Находим начальное базисное решение методом северо–западного угла или методом наименьшей стоимости. Вычисляем соответствующую стоимость всех перевозок .

3. Вычисляем потенциалы и, составляя систему (2). Считаем один из потенциалов, например,=0, остальные находим из системы (2).

4. Проверяем текущее базисное решение на оптимальность, для чего вычисляем коэффициенты по формуле (3). Если все0, то текущее базисное решение является оптимальным. Задача решена. В противном случае выполняем следующий шаг алгоритма.

5. Выбираем свободную клетку (p,q), для которой< 0 и строим для нее цикл пересчета.

6. Организуем сдвиг по циклу пересчета свободной клетки, находим новое базисное решение и новую суммарную стоимость перевозок по формуле (4), которая следует из формулы (1):

(4) S= , переходим к шагу 3.

Пример. Найти оптимальное решение транспортной задачи, исходные данные которой приведены в таблице перевозок:

Пункты

Станции

Тарифы перевозки груза в пункты потребления

Запасы груза на станциях

1

2

3

4

1

4

7

12

3

100

2

5

7

9

2

80

3

6

1

3

9

60

Потребности

70

40

60

70

1. Составим математическую модель задачи.

Среди неотрицательных решений системы уравнений

найти такое, при котором функция Sпринимает минимальное значение:

S=

2. В качестве начального базисного решения возьмем найденное ранее базисное решение, построенное методом минимальной стоимости:

Пункты

Станции

Тарифы и перевозки

Запасы груза на станциях

1

2

3

4

1

4

70

7

12

30

3

100

2

5

7

9

10

2

70

80

3

6

1

40

3

20

9

60

Потребности пунктов

70

40

60

70

В качестве начального базисного решения получаем систему чисел

= (70, 0, 30, 0, 0, 0, 10, 70, 0, 40, 20, 0)

Стоимость всех перевозок при этом решении:

S() = = 970 =

3. Находим потенциалы станций и пунктов, для чего составляем систему уравнений с потенциалами для базисных клеток :

Пусть. Из первого уравнения находим.

Из второго уравнения вычислим .

Из третьего уравнения вычислим .

Из четвертого уравнения вычислим

Из шестого уравнения вычислим

Из пятого уравнения вычислим

4. Проверяем решение на оптимальность, для чего находим коэффициентыв выраженииSчерез свободные переменные.

7 – (0 + 10) = –3. Так как < 0, то базисное решениене является оптимальным, переходим к следующему шагу.

5. Строим цикл пересчета для свободной клетки (1,2)

6. Выполним сдвиг по циклу пересчета свободной клетки (1,2) на величину t=min(30, 40) =30. Получим новые значения величин. Получаем новое базисное решение:

= (70, 30, 0, 0, 0,0, 10, 70, 0, 10, 50, 0)

Новая стоимость всех перевозок равна: S= = 970 – 330 =880. Переменнаястановится базисной, а переменнаясвободной.

Далее возвращаемся на шаг 3. Вычисляем снова потенциалы и, проверяем решениена оптимальность. Теперь, легко проверить, все коэффициенты при свободных переменных в выраженииSбудут неотрицательными. Значит,– оптимальное решение транспортной задачи, иminS= 880.

Для решения транспортной задачи можно применить систему компьютерной алгебры Maple, так как она содержит модуль simplex, позволяющий решить любую задачу линейного программирования, в частности транспортную задачу, симплекс–методом. После загрузки Maple подключим модуль simplex, зададим систему ограничений задачи под именем sn, определим функцию стоимости всех перевозок f и найдем оптимальное решение задачи линейного программирования с помощью стандартной функции mininmize:

>with(simplex);

>сn:={x11+x12+x13+x14=100, x21+x22+x23+x24=80, x31+x32+x33+x34=60,

x11+x21+x31=70, x12+x22+x32=40, x13+x23+x33=60, x14+x24+x34=70};

>f:=4*x11+7*x12+12*x13+3*x14+5*x21+7*x22+9*x23+2*x24+6*x31+

x32+3*x33+9*x34;

> minimize(f, cn, NONNEGATIVE);

Maple выводит решение, располагая значения перевозок в произвольном порядке:

{x31 = 0, x13 = 0, x14 = 0, x21 = 0, x34 = 0, x22 = 0, x11 = 70, x23 = 10,

x24 = 70, x32 = 10, x12 = 30, x33 = 50}

Ниже приводится программа решения транспортной задачи методом потенциалов. Предполагается, что размеры m и n задачи не превышают 20, и все данные – целые числа. Информация о задаче хранится в текстовом файле ‘trans.txt’. В его первой строке записаны 2 целых числа – размеры m и n. Во второй строке записаны m чисел – запасы груза на станциях. В третьей строке записаны n чисел – потребности пунктов. Далее в m строках по n чисел в каждой строке располагаются тарифы перевозки единицы груза со станции i в соответствующий пункт j. Для рассмотренной выше задачи файл ‘transt.txt’ имеет вид:

3 4

100 80 60

70 40 60 70

4 7 12 3

5 7 9 2

6 1 3 9

Сначала программа проверяет сбалансированность задачи и выводит сообщение, если она не сбалансирована. В противном случае программа приступает к решению задачи. Процедура readf считывает данные из файла, и выводит эти данные на экран. Процедура print выводит на экран результаты – оптимальный план перевозок и его стоимость. Процедура nordwest находит начальное базисное решение методом северо–западного угла.

program transport;

uses crt;

const mm=20; mn=20; {макс. кол. поставщиков и потребителей}

qq=40; bb=10000;

var t,m,n,i,j,k,h,r,v,w,xx,yy:integer;

x,z:array[1..mm,1..mn] of integer; {решение и тарифы}

a:array[1..mm] of integer; {поставки}

b:array[1..mn] of integer; {потребности}

e,g:array[1..qq] of integer; {массивы индексов базисных клеток}

p:boolean; f:text;

procedure readf;

begin assign(f,'trans.txt'); reset(f);

writeln('ТРАНСПОРТНАЯ ЗАДАЧА':50);

readln(f,m,n);

writeln('кол. станций: ',m);

writeln('кол. пунктов потребления: ',n);

writeln('запасы груза на станциях:');

for i:=1 to m do

begin read(f,a[i]); write(a[i]:4);

end; writeln;

writeln('потребности пунктов:');

for i:=1 to n do

begin read(f,b[i]); write(b[i]:4);

end; writeln;

writeln('таблица тарифов перевозок: ');

for i:=1 to m do

begin for j:=1 to n do

begin read(f,z[i,j]); write(z[i,j]:4)

end; writeln;

end; close(f);

end;

procedure nordwest;

begin i:=1; j:=1;

for h:=1 to n+m-1 do

begin r:=a[i]-b[j];

if (r>0) or ((r=0) and (b[j]<>0)) then

begin w:=b[j];

if w<>0 then x[i,j]:=w else x[i,j]:=-1;

e[h]:=i; g[h]:=j;

a[i]:=r; b[j]:=0;

if j<n then j:=j+1

end else

begin w:=a[i];

if w<>0 then x[i,j]:=w else x[i,j]:=-1;

e[h]:=i; g[h]:=j;

a[i]:=0; b[j]:=-r;

if i<m then i:=i+1

end

end;

end;

procedure print;

var F:integer;

begin F:=0; writeln;

writeln(' оптимальный план перевозок: ':30); writeln;

writeln('станция':10,'пункт ':12,'количество':12);

for i:=1 to 40 do write('-'); writeln;

for i:=1 to m do

for j:=1 to n do

if x[i,j]>0 then

begin F:=F+x[i,j]*z[i,j];

writeln(i:10,j:10,x[i,j]:10)

end; writeln;

writeln('min F=':25,F)

end;

procedure potencials; {здесь a и b-массивы потенциалов пунктов}

begin t:=bb; {xx,yy-координаты своб. клетки}

for i:=1 to m do a[i]:=t; for j:=1 to n do b[j]:=t;

a[1]:=0;

repeat r:=0;

for h:=1 to m+n-1 do

begin i:=e[h]; j:=g[h];

if x[i,j]<>0 then

begin xx:=a[i]; yy:=b[j];

if (xx=bb) and (yy<>bb) then

begin a[i]:=z[i,j]-yy;

r:=1

end else

if (xx<>bb) and (yy=bb) then

begin b[j]:=z[i,j]-xx;

r:=1

end

end

end

until r=0;

end;

function proverka:boolean;

begin p:=true; r:=0;

for i:=1 to m do

for j:=1 to n do

begin t:=a[i]+b[j]-z[i,j];

if t>r then

begin p:=false; xx:=i;

yy:=j; r:=t

end

end; proverka:=p

end;

procedure cancel; {здесь a и b-кол. баз. клеток в строках и столбцах}

begin t:=0;

for i:=1 to m do a[i]:=t; for j:=1 to n do b[j]:=t;

for i:=1 to m do for j:=1 to n do

if x[i,j]<>0 then

begin a[i]:=a[i]+1;

b[j]:=b[j]+1

end;

repeat r:=0;

for i:=1 to m do

if (a[i]<>-1) and (a[i]<=1) and (i<>xx) then

begin a[i]:=-1; r:=1;

for j:=1 to n do

if (b[j]<>-1) and (x[i,j]<>0) then

begin b[j]:=b[j]-1;

if b[j]=0 then b[j]:=-1

end

end;

for j:=1 to n do

if (b[j]<>-1) and (b[j]<=1) and (j<>yy) then

begin b[j]:=-1; r:=1;

for i:=1 to m do

if (a[i]<>-1) and (x[i,j]<>0) then

begin a[i]:=a[i]-1;

if a[i]=0 then a[i]:=-1

end

end

until r=0

end;

procedure zikl;

procedure vert;

begin k:=i; i:=1;

while (a[i]=-1) or (i=k) or (x[i,j]=0) do i:=i+1;

r:=x[i,j];

if w>r then w:=r;

end;

begin i:=xx; j:=yy; w:=bb;

vert;

while i<>xx do

begin k:=j; j:=1;

while (b[j]=-1) or (j=k) or (x[i,j]=0) do j:=j+1;

vert;

end;

end;

procedure mo;

begin h:=1;

while h<=n+m-1 do

begin if (e[h]=i) and (g[h]=j) then

begin e[h]:=xx; g[h]:=yy;

h:=m+n

end else h:=h+1

end

end;

procedure move;

label 1;

procedure vert1;

begin k:=i; i:=1;

while (a[i]=-1) or (i=k) or (x[i,j]=0) do i:=i+1

end;

begin i:=xx; j:=yy; v:=0;

if w=-1 then w:=0;

vert1;

1:r:=x[i,j];

if r<0 then

begin mo; x[i,j]:=0; x[xx,yy]:=-1

end {выход}

else

begin if r<=w then

if v<>0 then x[i,j]:=-1 else

begin mo; x[i,j]:=0; v:=1

end

else x[i,j]:=r-w;

if i=xx then x[xx,yy]:=w {выход}

else

begin k:=j; j:=1;

while (b[j]=-1) or (j=k) or (x[i,j]=0) do j:=j+1;

if x[i,j]>0 then

begin x[i,j]:=x[i,j]+w;

vert1; goto 1

end else

if w>0 then

begin x[i,j]:=w;

vert1

end; goto 1

end

end

end;

begin clrscr;

readf; t:=0; v:=0;

for i:=1 to m do t:=t+a[i];

for j:=1 to n do v:=v+b[j];

if t<>v then writeln('задача не сбалансирована':30) else

begin for i:=1 to m do

for j:=1 to n do x[i,j]:=0;

nordwest; potencials;

while proverka=false do

begin cancel;

zikl;

move;

potencials

end; print

end; readkey;

end.