Консультация № 180136
03.10.2010, 16:55
0.00 руб.
0 20 1
Уважаемые эксперты.
У меня такой вопрос к вам.
Помогите запрограммировать на паскале Симплекс метод.

Обсуждение

Неизвестный
05.10.2010, 16:22
общий
Вам важен принцип решения? Или нужно решить конкретную задачу?
Неизвестный
05.10.2010, 19:34
общий
мне нужна программка для решения,любый задач)
а то в инэте везде на делфи..на паскале нигде нет)
Неизвестный
05.10.2010, 23:35
общий
это ответ
Здравствуйте, Курсаков Андрей Сергеевич.
Ну тогда посмотрите этот код. Исходные данные считываются из файла, поэтому прикреплен архив, в котором исходный текст и исходные данные.

Приложение:
program simple_sim;
uses CRT;

const mm = 50; nn = 50;

var A : array[1..mm, 1..nn] of double;
fun : array[1..nn] of integer; { Коэффициенты целевой функции }
m, n : integer; { m ограничений, n переменных }

basis : array[1..nn] of integer;
{ Здесь храним номера базисных переменных }
i, j : integer;
x : array[1..nn] of double;
{ Здесь будут значения переменных при расшифровке плана }

procedure solve;
{На каждом шаге алгоритма:
1) Выбираем первый "слева" столбец j0, в котором в последней
строке - отрицательное число. Если такого столбца нет,
то заканчиваем работу алгоритма
2) Выбираем строку, для которой отношение
<элемент последнего столбца> / A[i, j0] минимально.
3) Выполняем со всей таблицей преобразование Жордана-Гаусса
с ведущим столбцом j0 и ведущей строкой i0, то есть добиваемся,
чтобы в столбце j0 все элементы стали равными 0, кроме
i0-го элемента, который будет равен 1

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

Замечание: в найденном решении будет m (а то и меньше)
неотрицательных элементов, а не n. Такое решение называется базисным.

Как вариант, можно выбирать столбец j0 как столбец с максимальным
по модулю отрицательным нижним элементом. Так алгоритм потребует
меньше итераций, но может зациклиться (а то правило выбора пары
i0, j0, которое используется в этом алгоритме, гарантирует, что
зацикливаться программа не будет.
Правило называется правилом Бленда).}

var i, j, i0, j0 : integer;
tmp : double;
opt : boolean;
begin
opt := false;
repeat
j0 := 1; i0 := 0;
while (j0 < m+n+1) and (A[m+1, j0] >= 0) do inc(j0);
if A[m+1, j0] >= 0 then opt := true;

if not opt then begin
tmp := 10000;
for i := 1 to m do
if (A[i, j0] > 0) and (A[i, m+n+1] / A[i, j0] < tmp) then
begin
tmp := A[i, m+n+1] / A[i, j0]; i0 := i
end;
{ i0 - выводим, j0 - добавляем }
basis[i0] := j0;
{ Ввод нового элемента в базис }
{ [i0, j0] - ведущий эл-т в Гауссе }
for i := 1 to m + 1 do
if i <> i0 then
begin
tmp := A[i, j0];
for j := 1 to m + n + 1 do
A[i,j] := A[i,j] - A[i0,j]*tmp/A[i0,j0];
end;
tmp := A[i0, j0];
for j := 1 to m + n + 1 do
A[i0, j] := A[i0, j] / tmp;
end;
until opt;
end;

begin
ClrScr;
assign(input, 'input.txt'); reset(input);
{ -------Ввод данных--------------------------- }
read(n); read(m);
if (n > nn) or (m > mm) then
begin
WriteLn('Определено слишком больше число переменных ',n);
WriteLn(' или ограничений ',m);
WriteLn('должно быть не больше 50');
Halt(0)
end;

for i := 1 to n do read(fun[i]);
{ Читаем коэффициенты целевой функции }

for i := 1 to m do
for j := 1 to n do read(A[i, j]);

for i := 1 to m do read(A[i, n+m+1]); { Читаем правые части ограничений }

for i := 1 to m do A[i, n+i] := 1;
{ Вводим дополнительные переменные }
fillchar(A[m+1], sizeof(A[m+1]), 0);

{ базис из доп. переменных }
for i := 1 to m do basis[i] := n + i;
for j := 1 to n do A[m+1,j] := -fun[j];
{ Оценки для небазисных переменных = -fun[j], для базисных - 0 }

{ базис из доп. переменных }
for i := 1 to m do basis[i] := n + i;
for j := 1 to n do A[m+1,j] := -fun[j];
{ Оценки для небазисных переменных = -fun[j], для базисных - 0 }

solve;

{ -- вывод базиса -- }
for i := 1 to m do
if basis[i] <= n then x[basis[i]] := A[i, m+n+1];

for i := 1 to n do writeLn('x[', i, '] = ', x[i]:0:3);
writeLn('min f(x) = ', A[m+1, m+n+1]:0:3);

WriteLn('Расчет законен. Нажмите любую клавишу ...'); ReadKey
end.

Прикрепленные файлы:
Неизвестный
06.10.2010, 13:17
общий
Boriss:
у меня несколько вопросов к Вам по задаче)
1. У меня при запуке появляется ошибка 116. в этом месте while (j0 < m+n+1) and (A[m+1, j0] >= 0) do inc(j0);
2. Что за переменная tmp,зачем?)
Неизвестный
06.10.2010, 14:47
общий
Курсаков Андрей Сергеевич:
1. 116 │Must be in 8087 mode to compile - то есть, нужно включить поддержку математического сопроцессора. Это же старая штука, Borland Pascal. Тогда еще не подозревали, что сопроцессор будет на всех процессорах:
Options -> Compiler -> крестик в правом нижнем углу поставьте, вторая строчка снизу (и запомните установки)
Это из-за использования типа переменной double для обечпечения повышенной точности вычислений.

2. Переменная tmp используется ниже
Неизвестный
06.10.2010, 16:02
общий
Boriss:
вот еще...вот этой программе..можно сделать,что бы распечатывала промежуточные таблицы?
Неизвестный
06.10.2010, 16:10
общий
Boriss:
еще..объясните как вводить в файле..систему уравнений и целевую фунцию..а то ввожу ввожу..всегда ноль получается.
и еще момент,вводить сразу в каномической форме?
Неизвестный
06.10.2010, 16:20
общий
мне нужно решить например такую задачку.
F=2x1+3x2(max)

система.
x1+3x2[$8804$]18
2x1+x2[$8804$]16
x2[$8804$]5
3x1[$8804$]21
Неизвестный
06.10.2010, 22:00
общий
По-моему, должно быть так (извини, не являюсь специалистом в этой области, ориентируюсь на алгоритм):
Файл исходных условий:
Код:
2 4
2 3
1 3
2 1
0 1
3 0
18 16 5 21

В первой строке размерность: 2 переменных, 4 условия
Во второй строке коэффициенты целевой функции.
Далее четыре строки коэффициентов при переменных в 4-х условиях.
В последней строке правые части условий

В результате получим:
Код:
x[1] = 6.000
x[2] = 4.000
min f(x) = 24.000
Расчет законен. Нажмите любую клавишу ...
Неизвестный
06.10.2010, 22:24
общий
Что-то невнимателен я сейчас . Все не те коэффициенты, было, записывал
Неизвестный
06.10.2010, 22:25
общий
Промежуточный вывод можно ставить в процедуре solve перед until opt;
Неизвестный
07.10.2010, 13:16
общий
Boriss:
что не получается..постоянно выводит по одному стобцу..
Неизвестный
07.10.2010, 13:19
общий
Хорошо, к вчеру посмотрю. А решение Вас удовлетворяет?
Неизвестный
07.10.2010, 14:12
общий
да,удовлетворяет)
если погли бы,можно сделать таблицы по шагово.
если итераций 3..то 3 таблицы.
Неизвестный
07.10.2010, 20:39
общий
хотелось бы так)
Неизвестный
07.10.2010, 21:36
общий
Как так?
Неизвестный
08.10.2010, 06:05
общий
Boriss:
как изображено на картинке,которая расположена выше)
Неизвестный
08.10.2010, 07:38
общий
Курсаков Андрей Сергеевич:
Я ничего не вижу! Хотя все куки-джавы включены у меня тут. Размести на rfpro или просто словами опиши
Неизвестный
08.10.2010, 13:03
общий
вот этот файл
https://rfpro.ru/upload/3224
Неизвестный
08.10.2010, 13:04
общий
где x1,x2...x6 -все переменные
1 столбец это базисы а второй это стобец свободных членов.
Форма ответа