Побудова розкладу роботи обладнання виробничої системи

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
Не вказано
Факультет:
Не вказано
Кафедра:
Кафедра програмного забезпечення

Інформація про роботу

Рік:
2009
Тип роботи:
Звіт
Предмет:
Моделювання
Група:
ПІ

Частина тексту файла (без зображень, графіків і формул):

МІНІСТЕРСТВО ОСВІТИ УКРАЇНИ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА” КАФЕДРА ПРОГРАМНОГО ЗАБЕЗПЕЧЕННЯ  Звіт До лабораторної роботи № 2 На тему: “ Побудова розкладу роботи обладнання виробничої системи ” З дисципліни : "Моделювання програмного забезпечення" Мета роботи: побудувати розклад роботи обладнання виробничої системи. Завдання: Виробнича система складає m верстатів, настроєних на виконання певної технологічної операції. На обробку надходить n партій заготовок з однаковими технологічними маршрутами, що передбачають обробку заготовок на всіх m верстатах. Для заданих у варіанті значень m і n, а також матриці T=tij нормативних значень часу на виконання операцій побудувати розклад роботи обладнання виробничої системи двома способами: а) повним перебором всіх можливих послідовностей виконання робіт, що надійшли на обробку; б) за алгоритмом Дудека. Розклад оптимізувати за критерієм мінімуму затрат часу на виконання всіх робіт. Код програми using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace Lab2_MPZ { public partial class Form1 : Form { public int[,] InputTimeAllocation; public int[][] Sequence; public class TimePosition { public int Value; public int Row; public int Column; public TimePosition(int Time, int x, int y) { Value = Time; Row = x; Column = y; } } public class TimePositionComparer : IComparer<TimePosition> { #region IComparer<TimePosition> Members public int Compare(TimePosition x, TimePosition y) { if (x.Value == y.Value) return 0; if (x.Value < y.Value) return -1; if (x.Value > y.Value) return 1; return x.ToString().CompareTo(y.ToString()); } #endregion } public Form1() { InitializeComponent(); dataGridView1.Rows.Add(); dataGridView1.Rows.Add(); dataGridView1.Rows.Add(); dataGridView1.Rows.Add(); dataGridView1.Rows[0].Cells[0].Value = "14"; dataGridView1.Rows[0].Cells[1].Value = "8"; dataGridView1.Rows[0].Cells[2].Value = "3"; dataGridView1.Rows[0].Cells[3].Value = "1"; dataGridView1.Rows[0].Cells[4].Value = "2"; dataGridView1.Rows[1].Cells[0].Value = "3"; dataGridView1.Rows[1].Cells[1].Value = "6"; dataGridView1.Rows[1].Cells[2].Value = "10"; dataGridView1.Rows[1].Cells[3].Value = "5"; dataGridView1.Rows[1].Cells[4].Value = "1"; dataGridView1.Rows[2].Cells[0].Value = "1"; dataGridView1.Rows[2].Cells[1].Value = "4"; dataGridView1.Rows[2].Cells[2].Value = "6"; dataGridView1.Rows[2].Cells[3].Value = "3"; dataGridView1.Rows[2].Cells[4].Value = "3"; dataGridView1.Rows[3].Cells[0].Value = "6"; dataGridView1.Rows[3].Cells[1].Value = "20"; dataGridView1.Rows[3].Cells[2].Value = "3"; dataGridView1.Rows[3].Cells[3].Value = "5"; dataGridView1.Rows[3].Cells[4].Value = "6"; InputTimeAllocation = new int[dataGridView1.RowCount - 1, dataGridView1.ColumnCount]; } private void DudecCount_Click(object sender, EventArgs e) { InputTimeAllocation = new int[dataGridView1.RowCount - 1, dataGridView1.ColumnCount]; // зчитування даних з таблиці for (int i = 0; i < dataGridView1.RowCount - 1; i++) for (int j = 0; j < dataGridView1.ColumnCount; j++) try { InputTimeAllocation[i, j] = int.Parse((string)dataGridView1.Rows[i].Cells[j].Value); } catch { MessageBox.Show(string.Format("Помилка при вводі даних в комірку ({0}, {1})", i, j)); return; } int MachineCount = InputTimeAllocation.GetLength(1); int DetailCount = InputTimeAllocation.GetLength(0); List<Point>[] JonsonInput = new List<Point>[MachineCount - 1]; for (int i = 0; i < (MachineCount - 1); i++) JonsonInput[i] = new List<Point>(); // генеруємо вхідні дані для задачі Джонсона з двома верстатами for (int i = 0; i < (MachineCount - 1); i++) for (int j = 0; j < DetailCount; j++) { int A = 0; int B = 0; for (int k = 0; k <= i; k++) { A += InputTimeAllocation[j, k]; B += InputTimeAllocation[j, MachineCount - k - 1]; } JonsonInput[i].Add(new Point(A, B)); } #region Метод Джонсона для двох машин для MachineCount-1 випадків int OptionIndex = 0; int[][] result = new int[MachineCount - 1][]; int[] result_time = new int[MachineCount - 1]; for (int i = 0; i < (MachineCount - 1); i++) { result[i] = new int[DetailCount]; } do { List<TimePosition> TimeAllocation = new List<TimePosition>(); for (int i = 0; i < DetailCount; i++) { TimeAllocation.Add(new TimePosition(JonsonInput[OptionIndex][i].X, i, 0)); TimeAllocation.Add(new TimePosition(JonsonInput[OptionIndex][i].Y, i, 1)); } TimeAllocation.Sort(new TimePositionComparer()); bool[] used = new bool[DetailCount]; List<int>[] result_tmp = new List<int>[2]; result_tmp[0] = new List<int>(); result_tmp[1] = new List<int>(); for (int i = 0; i < 2 * DetailCount; i++) { if (!used[TimeAllocation[i].Row]) { used[TimeAllocation[i].Row] = true; result_tmp[TimeAllocation[i].Column].Add(TimeAllocation[i].Row); } } result_tmp[0].CopyTo(result[OptionIndex]); result_tmp[1].Reverse(); result_tmp[1].CopyTo(result[OptionIndex], result_tmp[0].Count); #region Обрахунок часу роботи лінії int timeA = 0, timeB = 0; for (int i = 0; i < DetailCount; i++) { int curr_pos = result[OptionIndex][i]; timeA += JonsonInput[OptionIndex][curr_pos].X; if (timeB < timeA) timeB = timeA; timeB += JonsonInput[OptionIndex][curr_pos].Y; } if (timeA > timeB) result_time[OptionIndex] = timeA; else result_time[OptionIndex] = timeB; #endregion OptionIndex++; } while (OptionIndex < (MachineCount - 1)); #endregion int MinTime = int.MaxValue; int MinIndex = 0; for (int i = 0; i < result_time.Length; i++) { if (result_time[i] < MinTime) { MinTime = result_time[i]; MinIndex = i; } } MinTime = WorkingTimeCounting(InputTimeAllocation, result[MinIndex]); label1.Text = string.Format("Мінімальні затрати по часу для обробки всіх деталей складуть {0} сек\r\nпри такій послідовності обробки деталей:\r\n", MinTime); foreach (int t in result[MinIndex]) label1.Text = label1.Text + string.Format("{0}, ", (t + 1).ToString()); Sequence = new int[result.GetLength(0)][]; listBox2.Items.Clear(); for (int i = 0; i < result.Length; i++) { Sequence[i] = result[i]; StringBuilder sb = new StringBuilder(); foreach (int t in result[i]) sb.AppendFormat("{0}, ", t+1); sb.AppendFormat(" {0} сек", WorkingTimeCounting(InputTimeAllocation, result[i])); listBox2.Items.Add(sb.ToString()); } /* MachineCount = 2; int[,] DrawInput = new int[DetailCount, MachineCount]; for (int i = 0; i < DetailCount; i++) { DrawInput[i, 0] = JonsonInput[MinIndex][i].X; DrawInput[i, 1] = JonsonInput[MinIndex][i].Y; } */ WorkGraphicDrawing(InputTimeAllocation, result[MinIndex], MinTime, pictureBox1); } public int WorkingTimeCounting(int[,] InputTimeAllocation, int[] Sequence) { #region Обрахунок часу роботи лінії для основної задачі int DetailCount = InputTimeAllocation.GetLength(0); int MachineCount = InputTimeAllocation.GetLength(1); int[] Time = new int[MachineCount]; // загальний час роботи кожного верстата int time; for (int i = 0; i < DetailCount; i++) for (int j = 0; j < MachineCount; j++) { time = InputTimeAllocation[Sequence[i], j]; Time[j] += time; for (int k = j + 1; k < MachineCount; k++) if (Time[j] - Time[k] > 0) Time[k] += Time[j] - Time[k]; } return Time.Max(); #endregion } public void WorkGraphicDrawing(int[,] DrawInput, int[] Sequence, double TotalTime, PictureBox PB) { #region малювання графіка завантженості PB.Refresh(); // зчитуємо вихідні дані Graphics gr = Graphics.FromHwnd(PB.Handle); int X0 = 30; int Y0 = PB.Height - 20; int GraphicWidth = PB.Width - 20 - X0; int GraphicHeigth = PB.Height - 20 - Y0; int DetailCount = DrawInput.GetLength(0); int MachineCount = DrawInput.GetLength(1); // малюємо осі координат gr.DrawLine(new Pen(Color.Black, 2), X0, 20, X0, Y0); gr.DrawLine(new Pen(Color.Black, 2), X0, Y0, GraphicWidth + X0, Y0); gr.DrawString("T", new Font("Arial", 14), Brushes.BlueViolet, X0 + GraphicWidth - 10, Y0 + 5); // рахуємо висоту на якій буде знаходитися відповідна лінія кожного верстату int[] HeightX = new int[MachineCount]; for (int i = 1; i <= MachineCount; i++) { HeightX[i - 1] = (PB.Height / (MachineCount + 1)) * i; gr.DrawString("В " + i.ToString(), new Font("Arial", 10), Brushes.Fuchsia, X0 - 30, HeightX[i - 1] - 7); } // генеруємо кольори для кожної деталі Color[] DetailsColor = new Color[DetailCount]; Random rand = new Random((int)DateTime.Now.Ticks); for (int i = 0; i < DetailCount; i++) { DetailsColor[i] = new Color(); DetailsColor[i] = Color.FromArgb(rand.Next(255), rand.Next(255), rand.Next(255)); } int[] MachineXPosition = new int[MachineCount]; // позиції графіків для кожного верстата int[] MachineStandTime = new int[MachineCount]; // простої кожного верстата int[] Time = new int[MachineCount]; // загальний час роботи кожного верстата int time; // обраховуємо масштаб графіка double scale = (GraphicWidth-15) / TotalTime; Pen DashPen = new Pen(Color.Silver, 2); // перо для пунктирної лінії DashPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; // малюємо сам графік for (int i = 0; i < DetailCount; i++) { for (int k = 0; k < MachineCount; k++) { time = DrawInput[Sequence[i], k]; Time[k] += time; for (int j = k + 1; j < MachineCount; j++) { if ((int)(time * scale) + MachineXPosition[k] - MachineXPosition[j] > 0) { MachineXPosition[j] += ((int)(time * scale) + MachineXPosition[k] - MachineXPosition[j]); Time[j] += Time[k] - Time[j]; } } gr.DrawLine(new Pen(DetailsColor[Sequence[i]], 5), MachineXPosition[k] + X0 + (int)(MachineStandTime[k] * scale), HeightX[k], MachineXPosition[k] + (int)(time * scale) + (int)(MachineStandTime[k] * scale) + X0, HeightX[k]); gr.DrawLine(DashPen, MachineXPosition[k] + (int)(time * scale) + X0, HeightX[k], MachineXPosition[k] + (int)(time * scale) + X0, Y0); gr.DrawString(Time[k].ToString(), new Font("Arial", 10), new SolidBrush(DetailsColor[Sequence[i]]), MachineXPosition[k] + (int)(time * scale) + X0 - 10, Y0 + 7); MachineXPosition[k] += (int)(time * scale) + (int)(MachineStandTime[k] * scale); } } #endregion } private void ColumnCounter_ValueChanged(object sender, EventArgs e) { if (dataGridView1.Columns.Count == ColumnCounter.Value) return; if (dataGridView1.Columns.Count < ColumnCounter.Value) { for (int i = dataGridView1.Columns.Count; i < ColumnCounter.Value; i++) dataGridView1.Columns.Add("Column" + (i+1).ToString(), ""); } if (dataGridView1.Columns.Count > ColumnCounter.Value) { for (int i = (int)ColumnCounter.Value; i < dataGridView1.Columns.Count; ) dataGridView1.Columns.Remove("Column" + dataGridView1.Columns.Count.ToString()); } } #region Ф-ції для генерації перестановок private double Factor(double n) { if (n <= 1) return 1; else return n * Factor(n - 1); } private void Swap(ref int a, ref int b) { int t; t = a; a = b; b = t; } private void Reverse(ref int[] P, int m) { int i = 0, j = m; while (i < j) { Swap(ref P[i], ref P[j]); ++i; --j; } } private void Antilex(ref int[] P, int m, ref int[][] Result, ref int index) { int i; int N = P.GetLength(0); if (m == 0) { for (i = 0; i < N; ++i) Result[index][i] = P[i]; index++; } else { for (i = 0; i <= m; ++i) { Antilex(ref P, m - 1, ref Result, ref index); if (i < m) { Swap(ref P[i], ref P[m]); Reverse(ref P, m - 1); } } } } #endregion private void BruteForseMethod_Click(object sender, EventArgs e) { InputTimeAllocation = new int[dataGridView1.RowCount - 1, dataGridView1.ColumnCount]; // зчитування даних з таблиці for (int i = 0; i < dataGridView1.RowCount - 1; i++) for (int j = 0; j < dataGridView1.ColumnCount; j++) try { InputTimeAllocation[i, j] = int.Parse((string)dataGridView1.Rows[i].Cells[j].Value); } catch { MessageBox.Show(string.Format("Помилка при вводі даних в комірку ({0}, {1})", i, j)); return; } int MachineCount = InputTimeAllocation.GetLength(1); int DetailCount = InputTimeAllocation.GetLength(0); int N = (int)Factor(DetailCount); int[] P = new int[DetailCount]; for(int i=0; i<DetailCount; ++i) P[i] = i; Sequence = new int[N][]; for(int i=0; i<N; i++) Sequence[i] = new int[DetailCount]; int index = 0; Antilex(ref P, DetailCount - 1, ref Sequence, ref index); int[] Time = new int[N]; int MinTime = int.MaxValue; int MinIndex = 0; for (int i = 0; i < N; i++) { Time[i] = WorkingTimeCounting(InputTimeAllocation, Sequence[i]); if (Time[i] < MinTime) { MinTime = Time[i]; MinIndex = i; } } label3.Text = string.Format("Мінімальні затрати по часу для обробки всіх деталей складуть {0} сек\r\nпри такій послідовності обробки деталей:\r\n", MinTime); foreach (int t in Sequence[MinIndex]) label3.Text = label3.Text + string.Format("{0}, ", (t + 1).ToString()); WorkGraphicDrawing(InputTimeAllocation, Sequence[MinIndex], MinTime, pictureBox2); listBox1.Items.Clear(); for (int i = 0; i < N; i++) { StringBuilder sb = new StringBuilder(); foreach(int t in Sequence[i]) sb.AppendFormat("{0}, ",t+1); sb.AppendFormat(" {0} сек",WorkingTimeCounting(InputTimeAllocation,Sequence[i])); listBox1.Items.Add(sb.ToString()); } } private void listBox1_Click(object sender, EventArgs e) { WorkGraphicDrawing(InputTimeAllocation, Sequence[listBox1.SelectedIndex], WorkingTimeCounting(InputTimeAllocation,Sequence[listBox1.SelectedIndex]), pictureBox2); } private void listBox2_Click(object sender, EventArgs e) { WorkGraphicDrawing(InputTimeAllocation, Sequence[listBox2.SelectedIndex], WorkingTimeCounting(InputTimeAllocation, Sequence[listBox2.SelectedIndex]), pictureBox1); } } } Результат виконання завдання:   Висновок: в даній роботі я навчився будувати розклад роботи обладнання виробничої системи методами Дудека та повним перебором всіх можливих послідовностей виконання робіт, що надійшли на обробку. Обчислення проводились за такими вхідними даними: кількість верстатів, настроєних на виконання певної технологічної операції, кількість партій заготовок з однаковими технологічними маршрутами, що передбачають обробку заготовок на всіх m верстатах, а також матриці T=tij нормативних значень часу на виконання операцій.
Антиботан аватар за замовчуванням

01.01.1970 03:01-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!