Оптимальний розкрій матеріалу з максимальним прибутком

[ виправити ] текст може містити помилки, будь ласка перевіряйте перш ніж використовувати.

скачати

Зміст

Введення

1. Постановка і аналіз завдання

2. Рішення завдання

3. Опис алгоритму

4. Опис програми

5. Контрольний приклад

Висновок

Текст програми

Література

1. Введення

Зазвичай при виробництві виробів матеріал надходить у вигляді рулонів, смуг, прямокутних листів, стержнів і т. д. Вступник матеріал розкроюється на частини заданих розмірів і певної конфігурації, що представляють собою в одних випадках заготовки, в інших - готові деталі. До завдань розкрою, відносяться і завдання щільного розміщення сукупності предметів на заданих ділянках.

Завдання раціонального розкрою описуються схожими математичними моделями. Істотна відмінність цих моделей визначається головним чином двома факторами:

1) конфігурацією одержуваних при розкрої заготовок;

2) обсягом продукції, що випускається.

Завдання розкрою, визначаються першим чинником, поділяють на два класи. До першого класу належать завдання фігурного розкрою, до другого - завдання нефігурного розкрою. При фігурному розкрої матеріал розкроюється на заготовки самих різних конфігурацій. До класу задач нефігурного розкрою належать завдання лінійного і прямокутного розкрою. У першому випадку матеріал розкроюють на заготовки різної довжини, для яких задається тільки один лінійний розмір. У другому випадку отримують заготовки прямокутної форми, для яких задаються два розміри.

Завдання розкрою, зумовлені другим фактором, також поділяють на два класи: задачі розкрою в умовах масового (великосерійного) випуску виробів і завдання розкрою в умовах одиничного (дрібносерійного) виробництва. До обох класів можуть належати як завдання фігурного, так і завдання нефігурного розкрою. Завдання розкрою в умовах масового виробництва описуються безперервними моделями лінійного програмування, а в умовах одиничного виробництва - цілочисельними. У зв'язку з цим задачі розкрою в зазначених умовах часто називають відповідно безперервними і цілочисельними.

Завдання раціонального розкрою в умовах масового виробництва відносяться до класу задач лінійного програмування, з неявно заданими стовпцями (способами розкрою). При вирішенні таких завдань методами лінійного програмування виникає необхідність у генеруванні розкриємо на кожному кроці процесу. Нижче розглянуто задачу генерування лінійних розкрою.

1. Постановка і аналіз завдання

Вирішити завдання гільйотинного розкрою матеріалу (довгомірного прокату) з максимальним прибутком: шматок матеріалу довжиною L розкроюється на заготовки m найменувань, для кожної заготівлі з номером i = відомі її довжина l i і оцінка з i. Потрібно знайти розкрій з максимальною оцінкою одержуваного набору заготовок.

Задача оптимального розкрою довгомірного прокату носить різний характер в залежності від типу виробництва. Наприклад, для великосерійного виробництва характерні наступні завдання: прагнення отримати значне число заготовок однакової довжини, мінімізувати залишок, отримати максимальний прибуток від розкрою і т.д. У цій роботі буде розглянуто рішення задачі оптимального розкрою матеріалу з максимальним прибутком методом динамічного програмування з використанням так званої "сітковим методом", при якому виникає необхідність генерування розкриємо на кожному кроці процесу.

2. Рішення завдання

Припустимо, що шматок матеріалу довжиною L розкроюється на заготовки m найменувань. Для кожної заготівлі з номером i = відомі її довжина l i і оцінка з i. Потрібно знайти розкрій з максимальною оцінкою одержуваного набору заготовок.

Розкрій може містити будь-яке число кожної із заготовок. Тоді набір заготовок характеризується m-вимірним вектором

X = (x 1, x 2, ..., x m), (1)

Елементи якого являють собою цілі невід'ємні компоненти, що вказують на число заготовок кожного виду. При цьому потрібно максимізувати сумарну оцінку

(2)

набору заготовок (1) за єдиної лінійному обмеження

. (3)

Генерування розкрою будемо розглядати як багатокроковий циклічний процес, що складається з послідовного вибору окремих заголовок.

Для вирішення поставленого завдання розглянемо функцію

(4)

x Î X l

де через X i позначено множину невід'ємних векторів х, що відповідають розкрою, в яких загальна довжина заготовок не перевершує довжини l. Нехай l 0 = min l i, де i = 1 ... m.

Тоді при всіх l Î [0, l 0] відповідні множини X l складаються з одного нульового елемента і, отже, f (l) = 0 для всіх таких l. Для l Î [0, L 0], справедливі наступні рекурентні співвідношення:

, (5)

i Î I l

де через I l позначено безліч тих i, при яких l i £ l.

Спираючись на рекурентні співвідношення (5), можна для вирішення завдання запропонувати простий чисельний метод, який представляє собою перебір всіх допустимих розкрою. Реалізація всього процесу грунтується на двох етапах:

Перший етап

На першому етапі здійснюється так званий прямий хід: за формулами (5) для всіх l = послідовно обчислюються функції f (l) і при цьому фіксуються індекси i (l), при яких досягається максимум у виразі (5). Отримана при цьому інформація l, f (l) і i (l) запам'ятовується і підрядник записується в таблицю:

l

l 0

l 0 + 1

l 0 + 2

...

L

f (l)

f (l 0)

f (l 0 + 1)

f (l 0 + 2)

...

f (L)

i (l)

i (l 0)

i (l 0 + 1)

i (l 0 + 2)

...

i (L)

Другий етап

На другому етапі здійснюється так званий зворотний хід: для отримання шуканого вектора х (1), для якого виконується рівність m (x) = f (L), в розкрій в першу чергу включаються заготовка з номером i (l 1), де l 1 = L, і підраховується значення l 2 = l 1 - l i (l 1).

Якщо l 2 ³ l 0, то в розкрій включається заготовка з номером i (l 2) і підраховується значення l 3 = l 2 - l i (l 2) і т.д. Так як при кожному k ³ 1 очевидно, що l k +1 £ l k - l 0, то через кінцеве число описаних кроків виявиться, що l k +1 <l 0. На цьому генерування шуканого розкрою закінчується і виводиться результат.

3. Опис алгоритму

1. Визначається поточне значення довжини розкрою l від мінімальної довжини деталі до довжини матеріалу.

2. Обчислюється максимальний індекс (номер) деталі, додавання якої можливо.

3. Якщо немає деталей, які можна додати в розкрій, то перевіряється не досягнуть чи максимум ціни розкрою для поточного значення довжини розкрою l.

Якщо максимум досягнуто, то він запам'ятовується. Остання додана деталь видаляється з розкрою і додається наступна (п. 4). Якщо немає деталей які можна додати в розкрій, відбувається вихід з циклу.

4. Запам'ятовується поточний розкрій. Довжина розкрою зменшується на довжину деталі. Ціна розкрою збільшується на ціну деталі. Визначаються деталі, додавання яких до розкрій можливо (п. 2).

5. Береться початкова довжина розкрою, рівна довжині матеріалу. Береться деталь, на якій було досягнуто максимум для даної довжини матеріалу. З довжини матеріалу віднімається довжина деталі, до вартості розкрою додається ціна деталі. П.5 повторюється, поки є деталі, додавання яких до розкрою не перевищить довжини матеріалу.

6. Знаючи кількість деталей для кожного їх виду, складових раціональний розкрій, формується шуканий вектор х.

/ / Процедура обчислення раціонального розкрою

procedure searchRationalCut (

materialLength: integer;

detailAmount: integer;

var details: array of TDetail;

var x: array of integer);

var

l0, l, i: integer;

currCut: TCutRecord;

maxCut: TCutRecord;

cutRecords: array [0 .. MAX_CUTRECORD_AMOUNT-1] of TCutRecord;

cutRecords1: array [1 .. MAX_CUTRECORD_AMOUNT] of TCutRecord;

i1, j1: integer;

begin

l0: = details [0]. l;

for l: = l0 to materialLength do

begin

currCut.l: = l;

currCut.c: = 0;

currCut.i: = 0;

currCut.max_i: =- 1;

maxCut.l: = 0;

maxCut.c: = 0;

maxCut.i: = 0;

maxCut.max_i: = 0;

j1: = 0;

while true do

begin

if currCut.max_i =- 1 then

begin

for i1: = 0 to detailAmount-1 do

begin

if details [i1]. l <= currCut.l then

begin

currCut.max_i: = i1;

currCut.i: = 0;

end;

end;

end;

if (currCut.max_i =- 1) or (currCut.i> currCut.max_i) then

begin

if j1 <> 0 then

begin

if currCut.c> maxCut.c then

begin

maxCut: = currCut;

end;

currCut: = cutRecords1 [j1];

j1: = j1-1;

currCut.i: = currCut.i +1;

end

else

begin

break;

end;

end

else

begin

if (currCut.l> = l0) and (currCut.l <l) then

begin

if cutRecords [currCut.l]. c + currCut.c> maxCut.c then

begin

maxCut: = cutRecords [currCut.l];

maxCut.c: = maxCut.c + currCut.c;

end;

currCut.i: = currCut.i +1;

continue;

end;

j1: = j1 +1;

cutRecords1 [j1]: = currCut;

currCut.l: = currCut.l-details [currCut.i]. l;

currCut.c: = currCut.c + details [currCut.i]. c;

currCut.max_i: =- 1;

end;

end;

cutRecords [l]: = maxCut;

cutRecords [l]. l: = l;

end;

for i: = 0 to detailAmount-1 do

begin

x [i]: = 0;

end;

l: = materialLength;

while l> = details [0]. l do

begin

x [cutRecords [l]. i]: = x [cutRecords [l]. i] +1;

l: = l-details [cutRecords [l]. i]. l;

end;

end;

4. Опис програми

Вид головного вікна програми наведено на малюнку:

Після запуску програми користувачеві пропонується ввести довжину матеріалу і кількість типів деталей, потім потрібно заповнити поля таблиці з довжиною і вартістю кожної деталі.

Після введення даних для вирішення потрібно натиснути кнопку "Обчислити", програма видасть результат у вигляді таблиці з оптимальними значеннями кількості типів деталей. Також виводиться загальна оцінка розкрою, залишок матеріалу і наочна карта розкрою прокату в графічній формі. Білі частини розкрою позначають типи деталей, червоні лінії - лінії відрізу матеріалу. У випадку залишку, відповідна частина розкрою відображається сірим кольором:

5. Контрольний приклад

Нехай у задачі генерування лінійного розкрою задані наступні параметри: довжина прокату L = 40, кількість типів деталей m = 4, а значення довжин l i і вартості c i кожної деталі наведені в таблиці:

i

1

2

3

4

l i

7

11

13

17

c i

9

14

16

22

Вирішуємо задачу сітковим методом: спочатку виконуємо прямий хід. Вибираємо початкове значення довжини розкрою, рівне мінімальній довжині деталі: l 0 = min l i = 7 і послідовно "крокуємо" до кінця прокату, тобто 40.

Щоб знайти максимальну вартість на кожному кроці, ми перебираємо всі деталі, які можуть поміститися в поточний розкрій, починаючи з мінімальної по довжині. Для підрахунку вартості розкрою на поточному кроці ми віднімаємо довжину черговий обраної деталі з поточного розкрою і по таблиці знаходимо розкрій з довжиною, рівній отриманому залишку і підсумовуємо його оцінку з оцінкою обраної деталі. З обчислених оцінок вибираємо максимальну і заносимо її в таблицю, разом з номером деталі, при якій ця оцінка була отримана.

Далі в таблиці наведено результати першого етапу (прямого ходу) процесу:

l

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

f (l)

9

9

9

9

14

14

16

18

18

18

22

23

23

25

27

28

28

i (l)

1

1

1

1

2

2

3

1

1

1

4

1

1

1

1

2

2

l

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

f (l)

31

32

32

34

36

37

38

40

41

42

44

45

46

47

49

50

51

i (l)

1

1

1

1

1

1

3

1

1

2

4

1

1

1

1

1

1

Тут і далі i (l) - номер деталі, якій відповідає максимальна оцінка розкрою (сума вартості всіх деталей, що входять в розкрій) f (l) на кроці l.

Розглянемо більш детально послідовне заповнення таблиці на прикладі кроків

l = 7 ... 14, 22.

1) l = 7

Вибираємо першу деталь: i = 1. Довжина деталі 7, оцінка 9.

Обчислюємо залишок від розкрою: 7 - 7 = 0. Оскільки залишок нульовий, то деталей, які можна додати в розкрій, немає. Отже, максимальна оцінка поточного розкрою дорівнює f = 9. Заносимо в таблицю значення i (7) = 1, f (7) = 9 і переходимо до наступного кроку розкрою.

2) l = 8

Знову беремо першу деталь: i = 1. Довжина деталі 7, оцінка 9.

Залишок: 8 - 7 = 1. Так як деталей з такою довжиною немає, максимальна оцінка розкрою f = 9. Заносимо в таблицю i (8) = 1, f (8) = 9.

3) l = 9

i = 1, залишок 9 - 7 = 2, f = 9.

Заносимо в таблицю i (9) = 1, f (9) = 9.

4) l = 10

i = 1, залишок 10 - 7 = 3, f = 9.

Заносимо в таблицю i (10) = 1, f (10) = 9.

5) l = 11

i = 1, залишок 11 - 7 = 4, f = 9.

Враховуючи, що в поточний розкрій також вміститься деталь i = 2 c довжиною 11, отримаємо: i = 2, залишок 11 - 11 = 0, f = 14.

Порівняємо оцінки розкрою. Виберемо максимальну оцінку (f = 14) і відповідну їй деталь (i = 2).

Заносимо в таблицю i (11) = 2, f (11) = 14.

6) l = 12

i = 1, залишок 12 - 7 = 5, f = 9.

i = 2, залишок 12 - 11 = 1, f = 14 (максимум)

Заносимо в таблицю i (12) = 2, f (12) = 14.

7) l = 13

i = 1, залишок 13 - 7 = 6, f = 9.

i = 2, залишок 13 - 11 = 2, f = 14.

i = 3, залишок 13 - 13 = 0, f = 16 (максимум)

Заносимо в таблицю i (13) = 3, f (13) = 16.

8) l = 14

i = 1, залишок 14 - 7 = 7.

Якщо ми бачимо, що довжина залишку розкрою більше або дорівнює початковому значенням довжини розкрою (l 0 = 7), тобто в залишок може поміститися яка-небудь деталь (в даному випадку з індексом i = 1), з таблиці зчитуємо значення оцінки розкрою f (i) при i, рівному значенням залишку: f (7) = 9, тоді сумарна оцінка розкрою f = f (7) + 9 = 9 + 9 = 18 (максимум)

i = 2, залишок 14 - 11 = 3, f = 14.

i = 3, залишок 14 - 13 = 1, f = 16.

Заносимо в таблицю i (14) = 1, f (14) = 18.

... 16) l = 22

i = 1, залишок 22 - 7 = 15, f (15) = 18, f = 18 + 9 = 27.

i = 2, залишок 22 - 11 = 11, f (11) = 14, f = 14 + 14 = 28 (максимум)

i = 3, залишок 22 - 13 = 9, f (9) = 9, f = 9 + 16 = 25.

i = 4, залишок 22 - 17 = 5, f = 22.

Заносимо в таблицю i (22) = 2, f (22) = 28. і т.д., поки не досягнуть кінець прокату.

Виконуємо зворотний хід (починаємо рухатися з кінця таблиці):

1) l = 40

З таблиці отримуємо індекс деталі, доданої в поточний розкрій: i (40) = 1.

Знаходимо довжину деталі з отриманим індексом: l 1 = 7.

Обчислюємо залишок розкрою: 40 - 7 = 33. Цей залишок використовуємо для наступного кроку зворотного ходу.

2) l = 33

Індекс деталі: i (33) = 2.

Довжина деталі: l 2 = 11.

Залишок розкрою: 33 - 11 = 22.

3) l = 22

Індекс деталі: i (22) = 2.

Довжина деталі: l 2 = 11.

Залишок розкрою: 22 - 11 = 11.

4) l = 11

Індекс деталі: i (11) = 2.

Довжина деталі: l 2 = 11.

Залишок розкрою: 11 - 11 = 0. Зворотний хід закінчений.

Тепер підраховуємо кількість деталей кожного типу, які ми отримали при зворотному ході. Деталь з індексом i = 1 зустрілася 1 раз, деталь з індексом i = 2 зустрілася 3 рази.

Таким чином, шуканий оптимальний розкрій характеризується наступним чотиривимірним вектором x = (1; 3; 0; 0).

У вищенаведеній таблиці з результатами прямого ходу виділені номери заготовок, які при зворотному ході послідовно включалися в оптимальний розкрій.

Результат роботи програми (перевірка алгоритму):

Вихідні дані

Довжина прокату: 40

Кількість типів деталей: 4

Довжина деталі № 1 ....: 7 Ціна деталі № 1 ....: 9

Довжина деталі № 2 ....: 11 Ціна деталі № 2 ....: 14

Довжина деталі № 3 ....: 13 Ціна деталі № 3 ....: 16

Довжина деталі № 4 ....: 17 Ціна деталі № 4 ....: 22

Результат

Оптимальна кількість деталей кожного типу:

Деталь № 1 ....: 1 шт.

Деталь № 2 ....: 3 шт.

Деталь № 3 ....: 0 шт.

Деталь № 4 ....: 0 шт.

Оцінка розкрою: 51 грошових одиниць

Залишок матеріалу: 0

Результати ручного і машинного обчислень збігаються, що говорить про працездатність розробленого алгоритму для ЕОМ.

Висновок

У даній роботі поставлена ​​задача була вирішена за допомогою сіткового методу. Як показала проведена робота, цей метод ефективний і простий для програмної реалізації на ЕОМ. Результат, отриманий за допомогою цього методу, є оптимальним. У ньому реалізується цілеспрямований перебір за кінцеве число кроків, в результаті чого знаходиться раціональний розкрій з максимумом прибутку.

У роботі були зроблені ручні обчислення і по них перевірено роботу запрограмованого алгоритму на ЕОМ. Розроблена програма і сітковий метод оптимізації розкрою досить універсальні. Вони можуть застосовуватися в різних галузях промисловості при масовому виробництві, при цьому в алгоритм слід вносити корективи, пов'язані з обліком технології виробництва та обладнання.

Текст програми

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls, Grids, ComCtrls, ExtCtrls;

type

/ / Деталь

TDetail = record

l: integer; / / довжина

c: integer; / / ціна

end;

/ / Запис розкрою

TCutRecord = record

l: integer; / / довжина

c: integer; / / ціна

i: integer; / / індекс деталі

max_i: integer; / / максимальний індекс деталі для поточної довжини матеріалу

end;

TForm_Main = class (TForm)

GroupBox1: TGroupBox;

Edit_MaterialLength: TEdit;

Label_MaterialLength: TLabel;

UpDown_MaterialLength: TUpDown;

Label_DetailAmount: TLabel;

UpDown_DetailAmount: TUpDown;

Edit_DetailAmount: TEdit;

StringGrid_In: TStringGrid;

GroupBox2: TGroupBox;

StringGrid_Out1: TStringGrid;

Button_Calculate: TButton;

Button_Exit: TButton;

GroupBox3: TGroupBox;

Image_Cut: TImage;

Edit1: TEdit;

Edit2: TEdit;

Label1: TLabel;

Label2: TLabel;

Button1: TButton;

procedure Button_ExitClick (Sender: TObject);

procedure Edit_DetailAmountChange (Sender: TObject);

procedure FormCreate (Sender: TObject);

procedure Edit_MaterialLengthChange (Sender: TObject);

procedure Button_CalculateClick (Sender: TObject);

procedure Button1Click (Sender: TObject);

private

{Private declarations}

public

{Public declarations}

end;

const

MAX_DETAIL_AMOUNT = 10; / / максимальна к - ть деталей

MAX_CUTRECORD_AMOUNT = 10000; / / максимальна к - ть записів розкрою

MAX_MATERIAL_LENGTH = 10000; / / максимальна довжина матеріалу

var

Form_Main: TForm_Main;

materialLength: integer; / / довжина матеріалу

detailAmount: integer; / / к - ть деталей

details: array [1 .. MAX_DETAIL_AMOUNT] of TDetail; / / деталі

x: array [1 .. MAX_DETAIL_AMOUNT] of integer; / / результат

implementation

uses Unit2;

{$ R *. DFM}

/ / Процедура обчислення раціонального розкрою

procedure searchRationalCut (

materialLength: integer;

detailAmount: integer;

var details: array of TDetail;

var x: array of integer);

var

l0, l, i: integer;

currCut: TCutRecord;

maxCut: TCutRecord;

cutRecords: array [0 .. MAX_CUTRECORD_AMOUNT-1] of TCutRecord;

cutRecords1: array [1 .. MAX_CUTRECORD_AMOUNT] of TCutRecord;

i1, j1: integer;

begin

l0: = details [0]. l;

for l: = l0 to materialLength do

begin

currCut.l: = l;

currCut.c: = 0;

currCut.i: = 0;

currCut.max_i: =- 1;

maxCut.l: = 0;

maxCut.c: = 0;

maxCut.i: = 0;

maxCut.max_i: = 0;

j1: = 0;

while true do

begin

if currCut.max_i =- 1 then

begin

for i1: = 0 to detailAmount-1 do

begin

if details [i1]. l <= currCut.l then

begin

currCut.max_i: = i1;

currCut.i: = 0;

end;

end;

end;

if (currCut.max_i =- 1) or (currCut.i> currCut.max_i) then

begin

if j1 <> 0 then

begin

if currCut.c> maxCut.c then

begin

maxCut: = currCut;

end;

currCut: = cutRecords1 [j1];

j1: = j1-1;

currCut.i: = currCut.i +1;

end

else

begin

break;

end;

end

else

begin

if (currCut.l> = l0) and (currCut.l <l) then

begin

if cutRecords [currCut.l]. c + currCut.c> maxCut.c then

begin

maxCut: = cutRecords [currCut.l];

maxCut.c: = maxCut.c + currCut.c;

end;

currCut.i: = currCut.i +1;

continue;

end;

j1: = j1 +1;

cutRecords1 [j1]: = currCut;

currCut.l: = currCut.l-details [currCut.i]. l;

currCut.c: = currCut.c + details [currCut.i]. c;

currCut.max_i: =- 1;

end;

end;

cutRecords [l]: = maxCut;

cutRecords [l]. l: = l;

end;

for i: = 0 to detailAmount-1 do

begin

x [i]: = 0;

end;

l: = materialLength;

while l> = details [0]. l do

begin

x [cutRecords [l]. i]: = x [cutRecords [l]. i] +1;

l: = l-details [cutRecords [l]. i]. l;

end;

end;

/ / Введення даних користувача з таблиці

procedure updateData;

var

i: integer;

begin

materialLength: = strToInt (Form_Main.Edit_MaterialLength.Text);

detailAmount: = strToInt (Form_Main.Edit_DetailAmount.Text);

for i: = 1 to detailAmount do

begin

details [i]. l: = strToInt (Form_Main.StringGrid_In.Cells [1, i]);

details [i]. c: = strToInt (Form_Main.StringGrid_In.Cells [2, i]);

end;

end;

/ / Графічне відображення раціонального розкрою

procedure drawRationalCut (

image: TImage;

materialLength: integer;

detailAmount: integer;

details: array of TDetail;

x: array of integer);

var

i, j: integer;

sum: integer;

k_x: real;

curr_x: integer;

curr_x_scr: real;

begin

sum: = 0;

for i: = 0 to detailAmount-1 do

begin

sum: = sum + x [i] * details [i]. l;

end;

k_x: = image.width / materialLength;

with image.Canvas do

begin

brush.Style: = bsSolid;

brush.Color: = clBtnFace;

fillRect (rect (0, 0, image.width, image.height));

brush.Color: = clGray;

pen.Color: = clGray;

rectangle (trunc (k_x * sum), 0, trunc (k_x * materialLength), 50);

brush.Color: = clWhite;

pen.Color: = clGray;

rectangle (0, 0, trunc (k_x * sum), 50);

pen.Color: = clRed;

brush.Style: = bsClear;

textOut (0,51, '0 ');

curr_x: = 0;

curr_x_scr: = 0;

for i: = 0 to detailAmount-1 do

begin

for j: = 0 to x [i] -1 do

begin

curr_x: = curr_x + details [i]. l;

curr_x_scr: = curr_x_scr + k_x * details [i]. l;

if curr_x <> materialLength then

begin

moveTo (trunc (curr_x_scr), 0);

lineTo (trunc (curr_x_scr), 50);

textOut (trunc (curr_x_scr), 51, intToStr (curr_x));

/ / TextOut (trunc (curr_x_scr-15), 21, '(' + intToStr (i +1 )+')');

end;

end;

end;

end;

end;

/ / Вихід з програми

procedure TForm_Main.Button_ExitClick (Sender: TObject);

begin

close;

end;

/ / Зміна кількості детеалей

procedure TForm_Main.Edit_DetailAmountChange (Sender: TObject);

var

new_d_a: integer;

i: integer;

begin

new_d_a: = strToInt (Form_Main.Edit_DetailAmount.Text);

if (new_d_a> = 1) then

begin

if (new_d_a <= MAX_DETAIL_AMOUNT) then

begin

Form_Main.StringGrid_In.RowCount: = new_d_a +1;

for i: = 1 to new_d_a do

begin

Form_Main.StringGrid_In.Cells [0, i]: = intToStr (i);

end;

end

else

begin

Form_Main.Edit_DetailAmount.Text: = intToStr (MAX_DETAIL_AMOUNT);

end;

end

else

begin

Form_Main.Edit_DetailAmount.Text: = intToStr (1);

end;

end;

/ / Ініціалізація програми

procedure TForm_Main.FormCreate (Sender: TObject);

begin

Form_Main.UpDown_MaterialLength.Min: = 1;

Form_Main.UpDown_MaterialLength.Max: = MAX_MATERIAL_LENGTH;

Form_Main.UpDown_DetailAmount.Min: = 1;

Form_Main.UpDown_DetailAmount.Max: = MAX_DETAIL_AMOUNT;

Form_Main.StringGrid_In.Cells [0,0]: = '№ деталі';

Form_Main.StringGrid_In.Cells [1,0]: = 'Довжина';

Form_Main.StringGrid_In.Cells [2,0]: = 'Ціна';

Form_Main.StringGrid_In.Cells [0,1]: = '1 ';

Form_Main.StringGrid_Out1.Cells [0,0]: = '№ деталі';

Form_Main.StringGrid_Out1.Cells [1,0]: = 'Кількість';

end;

/ / Зміна довжини матеріалу

procedure TForm_Main.Edit_MaterialLengthChange (Sender: TObject);

var

new_m_l: integer;

begin

new_m_l: = strToInt (Form_Main.Edit_MaterialLength.Text);

if (new_m_l> = 1) then

begin

if not (new_m_l <= MAX_MATERIAL_LENGTH) then

begin

Form_Main.Edit_MaterialLength.Text: = intToStr (MAX_MATERIAL_LENGTH);

end;

end

else

begin

Form_Main.Edit_MaterialLength.Text: = intToStr (1);

end;

end;

/ / Сортування даних за зростанням довжини деталі

procedure StrGridSort;

var

i: integer;

do_next: boolean;

begin

do_next: = true;

while do_next do

begin

do_next: = false;

for i: = 1 to Form_Main.StringGrid_In.RowCount-2 do

begin

if strToInt (Form_Main.StringGrid_In.Cells [1, i])>

strToInt (Form_Main.StringGrid_In.Cells [1, i +1]) then

begin

Form_Main.StringGrid_In.cols [1]. Exchange (i, i +1);

Form_Main.StringGrid_In.cols [2]. Exchange (i, i +1);

do_next: = true;

end;

end;

end;

end;

/ / Обчислення раціонального розкрою і відображення результату

procedure TForm_Main.Button_CalculateClick (Sender: TObject);

var

i, sum, cost: integer;

begin

strGridSort;

updateData;

searchRationalCut (materialLength, detailAmount, details, x);

Form_Main.StringGrid_Out1.RowCount: = detailAmount +1;

sum: = 0; cost: = 0;

for i: = 1 to detailAmount do

begin

Form_Main.StringGrid_Out1.Cells [0, i]: = intToStr (i);

Form_Main.StringGrid_Out1.Cells [1, i]: = intToStr (x [i]);

sum: = sum + x [i] * details [i]. l;

cost: = cost + x [i] * details [i]. c;

end;

Form_Main.Edit1.Text: = intToStr (cost);

Form_Main.Edit2.Text: = intToStr (materialLength-sum);

drawRationalCut (Form_Main.Image_Cut, materialLength, detailAmount, details, x);

end;

procedure TForm_Main.Button1Click (Sender: TObject);

begin

Form2.Show;

end;

end.

Література

1. Е.А. Мухачева "Раціональний розкрій промислових матеріалів". Москва, Машинобудування, 1984 р.

2. Е.А. Мухачева, Г.Ш. Рубінштейн "Математичне програмування". Новосибірськ, Наука, 1977 р.


Додати в блог або на сайт

Цей текст може містити помилки.

Програмування, комп'ютери, інформатика і кібернетика | Курсова
123кб. | скачати


Схожі роботи:
Аналіз газетного матеріалу Отримали урок від чемпіона Оцінений композиційної побудови матеріалу
Оптимальний рівень інфляції
Оптимальний варіант сенсорної лабораторії
Оптимальний портфель цінних паперів
Управління прибутком
Функція корисності Оптимальний план споживання
Оптимальний розподіл коштів на розширення виробництва
Управління прибутком підприємства
Управління прибутком на підприємстві
© Усі права захищені
написати до нас