
- •Введение
- •Постановка задачи
- •Качественное описание исследуемой операции
- •Концептуальная модель операции
- •Математическая постановка задачи
- •Алгоритмизация решения задачи
- •Анализ методов решения задачи
- •Выбор и описание метода
- •Конструирование алгоритма решения задачи
- •Выполнение третьего шага
- •Проектирование сценария диалога
- •Описание структур данных
- •Структурная схема алгоритма сценария диалога и описание его программной реализации
- •Структурная схема функционального алгоритма решения задачи
- •Численные эксперименты
- •Ручная реализация алгоритма решения задачи
- •Машинные эксперименты с разработанными данными
- •Сравнение результатов ручного и машинного расчетов
- •Заключение
- •Список используемой литературы
- •Приложение а – листинг программы
Машинные эксперименты с разработанными данными
При расчете исходных данных, программой были получены ледующие результаты представленные на рисунках 3.1-3.
Рисунок 3.1 – Задание таблицы времени
Рисунок 3.2 – Вывод ответа
Рисунок 3.3 – Распределение бригад на 1 и 2 шагах
Рисунок 3.4 - Распределение бригад на 3 и 4 шагах
Рисунок 3.4 - Распределение бригад на 5 шаге
Сравнение результатов ручного и машинного расчетов
При ручном расчете время выполнения всех разгрузочно-погрузочных работ составит Т=8. Для этого потребуется :
на 5 склад отправить 6 грузчиков,
на 4 склад отправить 2 грузчика,
на 3 склад отправить 5 грузчиков,
на 2 склад отправить 4 грузчика,
на 1 склад отправить 21-(6+2+5+4)=4 грузчика.
Машинные расчеты дали аналогичные результаты, как на отдельном шаге, так и в конечном итоге.
Заключение
Результатом выполнения настоящей курсовой работы является программный продукт, реализующий решение задачи распределения программных модулей между процессорами. Сравнение ручного расчёта и машинных экспериментов говорит о том, что разработанная программа соответствует требованиям технического задания.
Использование программного продукта помогает принять оптимальное решение при минимаксной задаче оптимального распределения программных модулей между процессорами.
Список используемой литературы
Черноморов Г.А. Теория принятия решений: Учебное пособие / Юж. – Рос. гос. техн. ун-т. Новочеркасск: Ред. журн. «Изв. вузов. Электромеханика» 2002, 276 с.
Черноморов Г.А. Методические указания к выполнению курсовой работы по дисциплине “Системный анализ и исследование операций”/ Новочерк. гос. техн. ун-т. Новочеркасск: НГТУ, 1998. С. 76.
Приложение а – листинг программы
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
namespace Kursovaya
{
public partial class Form1 : Form
{
int N , M , str;
public Form1()
{
InitializeComponent();
N = 21; M = 5; str = 5; //N - количество грузчиков, М - складов, str - строк в исходной таблице
// матрица по умолчанию
int[,] T = new int[5, 6] { { 2, 10, 12, 14, 8, 18 }, { 4, 6, 8, 9, 5, 12 }, { 5, 5, 6, 6, 3, 10 }, { 6, 3, 4, 4, 2, 8 }, { 8, 2, 3, 2, 1, 4 } };
dataGridView1.Columns.Add("","Количество грузчиков");
for (int i = 1; i < M+1; i++)dataGridView1.Columns.Add("", "№" + i);
for (int j = 0; j < str; j++)
{
dataGridView1.Rows.Add();
}
for (int j = 0; j < M+1; j++)
for (int i = 0; i < str; i++)
dataGridView1[j, i].Value = T[i, j];
dataGridView1.AutoResizeColumns();
}
private void button1_Click(object sender, EventArgs e)
{
textBox1.Clear();
// размер исходной матрицы
int M = dataGridView1.ColumnCount-1; // столбцы
int str = dataGridView1.RowCount - 1; // строки
int N = 21; //количество рабочих
int i = 0, j = 0, s = 0, p = N, t = 0;
string text = " "; // сюда будет помещаться решение
string answ = " "; // сюда будет помещен ответ
int[,] a = new int[str, M+1]; // исходная матрица
int[,] T = new int[str, M]; // матрица времени выполнения
int[] rabs = new int[N + 1]; // массив с количеством работников
int[] U = new int[str]; // массив управления
int[] sost2, sost3, sost4, sost5, sost6;
int step = 0; // шаги
int[] difMas1 = new int[] { 0 }; // временные массивы для хранения уникальных состояний (количеств работников)
int[] difMas2 = new int[] { 0 };
int[] difMas3 = new int[] { 0 };
int n=0;
int[,] temp21, temp22; // временные матрицы для 2 шага
int[,] tab2; // итоговая т-ца для 2 шага
int[,] temp31, temp32, tab3, temp41, temp42, tab4, temp51, temp52, tab5, temp61, temp62, tab6;
int[] answer= new int[M];
bool ans = false;
text += "\r\nРазмерность: M =" + (M+1) + " str =" + str + "\r\nИсходная матрица:\r\n";
for (j = 0; j < str; j++)
{
for (i = 0; i < M+1; i++)
{
a[j, i] = Convert.ToInt32(dataGridView1[i, j].Value);
text += a[j, i].ToString() + " ";
}
text += " \r\n";
}
text += "\r\nМатрица времени выполнения:\r\n";
for (j = 0; j < str; j++)
{
for (i = 1; i < M+1; i++)
{
T[j, i-1] = Convert.ToInt32(dataGridView1[i, j].Value);
text += T[j, i-1].ToString() + " ";
}
text += " \r\n";
}
//Заполенение матрицы работников
for (i = 0; i <= N; i++)
rabs[i] = i;
//Заполенение матрицы управления
for (i = 0; i < str; i++)
U[i] = a[i,0];
// ШАГ 1
step = 1;
text += "\r\n\tШаг1: Распределение работников для выполнения работ на первом складе\r\n";
int[,] tab1 = new int[str, 3];
for (i = 0; i < str; i++)
{
tab1[i, 0] = a[i, 0];
tab1[i, 1] = a[i, 0];
tab1[i, 2] = T[i, 0];
}
text += "\r\nИтоговая таблица после "+step+" шага";
text +=print(tab1);
// ШАГ 2
if (step + 1 <= M)
{
step = 2;
text += "\r\n\tШаг2: Распределение работников между первым и вторым складами\r\n";
n = tab1.GetLength(0); //кол-во строк предыдущей т-цы
temp21 = new int[str, n]; // количество столбцов равно кол-ву строк предыдущей т-цы
temp22 = new int[str, n];
sost2 = new int[1];
// заполнение матрицы, соответствующей значениям в нижней части клетки
text += "\r\nМатрица, соответствующая значениям в нижней части клетки\r\n";
for (i = 0; i < str; i++)
for (j = 0; j < n; j++)
{
temp21[i, j] = a[i, 0] + tab1[j, 0];
if (temp21[i, j] > N) temp21[i, j] = -1;
}
text += print(temp21);
// заполнение матрицы, соответствующей значениям в верхней части клетки
text += "\r\nМатрица, соответствующая значениям в верхней части клетки\r\n";
for (i = 0; i < str; i++)
for (j = 0; j < n; j++)
if (temp21[i, j] != -1)
temp22[i, j] = max(a[i, 2], a[j, 1]);
else temp22[i, j] = -1;
text += print(temp22);
// Вызов функции для нахождения уникальных значений количества работников и минимального времени
countDifEl(temp21, temp22, U, tab1, ref difMas1, ref difMas2, ref difMas3, ref sost2);
tab2 = new int[difMas1.Length, 3];
for (i = 0; i < difMas1.Length; i++)
{
tab2[i, 0] = difMas1[i]; tab2[i, 1] = difMas3[i]; tab2[i, 2] = difMas2[i];
}
text += "\r\nИтоговая таблица после " + step + " шага";
text += print(tab2);
if (step + 1 <= M)
{
// ШАГ 3
step = 3;
text += "\r\n\tШаг3: Распределение работников между первым, вторым и третьим складами\r\n";
n = tab2.GetLength(0); //кол-во строк предыдущей т-цы
temp31 = new int[str, n]; // количество столбцов равно кол-ву строк предыдущей т-цы
temp32 = new int[str, n];
sost3 = new int[1];
// заполнение матрицы, соответствующей значениям в нижней части клетки
text += niz(ref temp31, a, tab2);
// заполнение матрицы, соответствующей значениям в верхней части клетки
text += verh(temp31, ref temp32, a, difMas2, step);
Array.Resize(ref difMas1, 1); Array.Resize(ref difMas2, 1); Array.Resize(ref difMas3, 1);
// Вызов функции для нахождения уникальных значений количества работников и минимального времени
countDifEl(temp31, temp32, U, tab2, ref difMas1, ref difMas2, ref difMas3, ref sost3);
tab3 = new int[difMas1.Length, 3];
for (i = 0; i < difMas1.Length; i++)
{
tab3[i, 0] = difMas1[i]; tab3[i, 1] = difMas3[i]; tab3[i, 2] = difMas2[i];
}
text += "\r\nИтоговая таблица после " + step + " шага";
text += print(tab3);
if (step + 1 <= M)
{
// ШАГ 4
step = 4;
text += "\r\n\tШаг4: Распределение работников между первым, вторым, третьим и 4 складами\r\n";
n = tab3.GetLength(0); //кол-во строк предыдущей т-цы
temp41 = new int[str, n]; // количество столбцов равно кол-ву строк предыдущей т-цы
temp42 = new int[str, n];
sost4 = new int[1];
// заполнение матрицы, соответствующей значениям в нижней части клетки
text += niz(ref temp41, a, tab3);
// заполнение матрицы, соответствующей значениям в верхней части клетки
text += verh(temp41, ref temp42, a, difMas2, step);
Array.Resize(ref difMas1, 1); Array.Resize(ref difMas2, 1); Array.Resize(ref difMas3, 1);
// Вызов функции для нахождения уникальных значений количества работников и минимального времени
countDifEl(temp41, temp42, U, tab3, ref difMas1, ref difMas2, ref difMas3, ref sost3);
tab4 = new int[difMas1.Length, 3];
for (i = 0; i < difMas1.Length; i++)
{
tab4[i, 0] = difMas1[i]; tab4[i, 1] = difMas3[i]; tab4[i, 2] = difMas2[i];
}
text += "\r\nИтоговая таблица после " + step + " шага";
text += print(tab4);
if (step + 1 <= M)
{
// ШАГ 5
step = 5;
text += "\r\n\tШаг5: Распределение работников между 1,2,3,4 и 5 складами\r\n";
n = tab4.GetLength(0); //кол-во строк предыдущей т-цы
temp51 = new int[str, n]; // количество столбцов равно кол-ву строк предыдущей т-цы
temp52 = new int[str, n];
sost5 = new int[1];
// заполнение матрицы, соответствующей значениям в нижней части клетки
text += niz(ref temp51, a, tab4);
// заполнение матрицы, соответствующей значениям в верхней части клетки
text += verh(temp51, ref temp52, a, difMas2, step);
Array.Resize(ref difMas1, 1); Array.Resize(ref difMas2, 1); Array.Resize(ref difMas3, 1);
// Вызов функции для нахождения уникальных значений количества работников и минимального времени
countDifEl(temp51, temp52, U, tab4, ref difMas1, ref difMas2, ref difMas3, ref sost5);
tab5 = new int[difMas1.Length, 3];
for (i = 0; i < difMas1.Length; i++)
{
tab5[i, 0] = difMas1[i];
tab5[i, 1] = difMas3[i];
tab5[i, 2] = difMas2[i];
}
text += "\r\nИтоговая таблица после " + step + " шага";
text += print(tab5);
if (step + 1 <= M)
{
// ШАГ 6
step = 6;
text += "\r\n\tШаг6: Распределение работников между 1,2,3,4,5 и 6 складами\r\n";
n = tab5.GetLength(0); //кол-во строк предыдущей т-цы
temp61 = new int[str, n]; // количество столбцов равно кол-ву строк предыдущей т-цы
temp62 = new int[str, n];
sost6 = new int[1];
// заполнение матрицы, соответствующей значениям в нижней части клетки
text += niz(ref temp61, a, tab5);
// заполнение матрицы, соответствующей значениям в верхней части клетки
text += verh(temp61, ref temp62, a, difMas2, step);
Array.Resize(ref difMas1, 1); Array.Resize(ref difMas2, 1); Array.Resize(ref difMas3, 1);
// Вызов функции для нахождения уникальных значений количества работников и минимального времени
countDifEl(temp61, temp62, U, tab5, ref difMas1, ref difMas2, ref difMas3, ref sost6);
tab6 = new int[difMas1.Length, 3];
for (i = 0; i < difMas1.Length; i++)
{
tab6[i, 0] = difMas1[i];
tab6[i, 1] = difMas3[i];
tab6[i, 2] = difMas2[i];
}
text += "\r\nИтоговая таблица после " + step + " шага";
text += print(tab6);
text += "\r\nОбратный просмотр таблиц\r\n";
// Обратный просмотр на 6 шаге
step--;
text += minTime(step, tab6, ref answer, ref t); step--;
search(temp61, temp62, p, t, ref s);
answer[step] = tab5[s, 1];
step--;
p = tab5[s, 0];
t = tab5[s, 2];
search(temp51, temp52, p, t, ref s);
answer[step] = tab4[s, 1];
step--;
p = tab4[s, 0];
t = tab4[s, 2];
search(temp41, temp42, p, t, ref s);
answer[step] = tab3[s, 1];
step--;
p = tab3[s, 0];
t = tab3[s, 2];
search(temp31, temp32, p, t, ref s);
answer[step] = tab2[s, 1];
step--;
p = tab2[s, 0];
t = tab2[s, 2];
search(temp21, temp22, p, t, ref s);
answer[step] = tab1[s, 1];
text += printAnswer(answer);
answ = printAnswer(answer);
ans = true;
}
if (!ans)
{
text += "\r\nОбратный просмотр таблиц\r\n";
// Обратный просмотр на 5 шаге
step--;
text += minTime(step, tab5, ref answer, ref t); step--;
search(temp51, temp52, p, t, ref s);
answer[step] = tab4[s, 1];
step--;
p = tab4[s, 0];
t = tab4[s, 2];
search(temp41, temp42, p, t, ref s);
answer[step] = tab3[s, 1];
step--;
p = tab3[s, 0];
t = tab3[s, 2];
search(temp31, temp32, p, t, ref s);
answer[step] = tab2[s, 1];
step--;
p = tab2[s, 0];
t = tab2[s, 2];
search(temp21, temp22, p, t, ref s);
answer[step] = tab1[s, 1];
text += printAnswer(answer);
answ = printAnswer(answer);
ans = true;
}
}
if (!ans)
{
text += "\r\nОбратный просмотр таблиц\r\n";
// Обратный просмотр на 4 шаге
step--;
text += minTime(step, tab4, ref answer, ref t); step--;
search(temp41, temp42, p, t, ref s);
answer[step] = tab3[s, 1];
step--;
p = tab3[s, 0];
t = tab3[s, 2];
search(temp31, temp32, p, t, ref s);
answer[step] = tab2[s, 1];
step--;
p = tab2[s, 0];
t = tab2[s, 2];
search(temp21, temp22, p, t, ref s);
answer[step] = tab1[s, 1];
text += printAnswer(answer);
answ = printAnswer(answer);
ans = true;
}
}
if (!ans)
{
text += "\r\nОбратный просмотр таблиц\r\n";
// Обратный просмотр на 3 шаге
step--;
text += minTime(step, tab3, ref answer, ref t); step--;
search(temp31, temp32, p, t, ref s);
answer[step] = tab2[s, 1];
step--;
p = tab2[s, 0];
t = tab2[s, 2];
search(temp21, temp22, p, t, ref s);
answer[step] = tab1[s, 1];
text += printAnswer(answer);
answ = printAnswer(answer);
ans = true;
}
}
if (!ans)
{
text += "\r\nОбратный просмотр таблиц\r\n";
// Обратный просмотр на 2 шаге
step--;
text += minTime(step, tab2, ref answer, ref t); step--;
search(temp21, temp22, p, t, ref s);
answer[step] = tab2[s, 1];
text += printAnswer(answer);
answ = printAnswer(answer);
ans = true;
}
}
StreamWriter sw = new StreamWriter("new.txt");
sw.WriteLine(text);
sw.Close();
textBox1.Text += answ;
buttonSteps.Enabled = true;
}
// Функция для вывода двумерного массива
public string print(int[,] mas)
{
int i = 0, j = 0;
string sol="";
int x = mas.GetLength(0), y = mas.GetLength(1);
sol += "\r\n";
for (i = 0; i < x; i++)
{
for (j = 0; j < y; j++)
{
sol += mas[i, j] + " ";
}
sol += "\r\n";
}
return sol;
}
// функция для заполнения матрицы, соответствующей значениям в нижней части клетки
public string niz(ref int[,] temp1, int[,] a, int[,] tab)
{
string text = "\r\nМатрица, соответствующая значениям в нижней части клетки\r\n";
for (int i = 0; i < temp1.GetLength(0); i++)
for (int j = 0; j < temp1.GetLength(1); j++)
{
temp1[i, j] = a[i, 0] + tab[j, 0];
if (temp1[i, j] > N) temp1[i, j] = -1;
}
text += print(temp1);
return text;
}
// функция для заполнения матрицы, соответствующей значениям в верхней части клетки
public string verh(int[,] temp1, ref int[,] temp2, int[,] a, int[] difMas, int step)
{
string text = "\r\nМатрица, соответствующая значениям в верхней части клетки\r\n";
for (int i = 0; i < temp1.GetLength(0); i++)
for (int j = 0; j < temp1.GetLength(1); j++)
{
if (temp1[i, j] != -1)
temp2[i, j] = max(a[i, step], difMas[j]);
else temp2[i, j] = -1;
}
text += print(temp2);
return text;
}
// Функция нахождения максимального элемента из двух
public int max(int a, int b)
{
if (b > a) return b;
else return a;
}
// Функция нахождения минимального элемента из двух (0 не учитывается)
public int min(int a, int b)
{
if ((a > 0) & (b < a)) return b;
else return a;
}
// Функция нахождения различных значений (количеств работников) в нижней части клетки и минимальных в верхней
public void countDifEl(int[,] mas, int[,] mas2, int [] U, int[,] tab, ref int[] difMas1, ref int[] difMas2, ref int[] difMas3, ref int[] sost)
{
int a = 0;
int count=0;
difMas1[0] = mas[0, 0];
difMas2[0] = mas2[0, 0];
difMas3[0] = U[0];
sost[0] = tab[0, 0];
for (int i = 0; i < mas.GetLength(0); i++)
for (int j = 0; j < mas.GetLength(1); j++)
{
if (mas[i, j] != -1)
{
count = 0;
for (int k = 0; k < difMas1.Length; k++)
if (mas[i, j] == difMas1[k]) // проверяется, нет ли такого элемента в массиве с различными элементами
{ // если есть, то выбрать минимальное значение для верхней части клетки
a = difMas2[k];
difMas2[k] = min(difMas2[k], mas2[i, j]);
if (a > difMas2[k])
{
difMas3[k] = U[i];
sost[k] = tab[j, 0];
}
break;
}
else count++;
if (count == difMas1.Length)
{
Array.Resize(ref difMas1, difMas1.Length + 1); // увеличение размера массива на 1
Array.Resize(ref difMas2, difMas2.Length + 1);
Array.Resize(ref difMas3, difMas3.Length + 1);
Array.Resize(ref sost, sost.Length + 1);
difMas1[difMas1.Length - 1] = mas[i, j];
difMas2[difMas2.Length - 1] = mas2[i, j];
difMas3[difMas3.Length - 1] = U[i];
sost[sost.Length-1]=tab[j,0];
}
}
}
}
// Функция поиска состояния (количества работников) для обратного просмотра
public void search(int[,] mas, int[,] mas2, int a, int b, ref int f)
{
for (int i = 0; i < mas.GetLength(0); i++)
for (int j = 0; j < mas.GetLength(1); j++)
if ((mas[i, j] != -1) & (mas[i, j] == a) & (mas2[i, j] == b))
{ f = j; break; }
}
public string minTime(int step, int[,] tab, ref int[] answer, ref int t)
{
string text=" ";
for (int i = 0; i < tab.GetLength(0); i++)
if (tab[i, 0] == N)
{
text += "Минимальное время, за которое будут выполнены работы, составляет T = " + tab[i, 2];
answer[step] = tab[i, 1];
t = tab[i, 2];
return text;
}
return text;
}
public string printAnswer(int[] answer)
{
string text = " ";
text += "Бригады следует сформировать следующим образом:\r\n";
for (int i = 0; i < answer.Length; i++) text += "На " + (i + 1) + " склад - " + answer[i] + "\r\n";
return text;
}
// Кнопка задания размеров таблицы
private void button2_Click(object sender, EventArgs e)
{
textBox1.Clear();
dataGridView1.Columns.Clear();
M = int.Parse(numM.Text);
N = int.Parse(numN.Text);
str = int.Parse(numStr.Text);
dataGridView1.Columns.Add("","Количество грузчиков");
for (int i = 1; i < M+1; i++)dataGridView1.Columns.Add("", "№" + i);
for (int j = 0; j < str; j++)
{
dataGridView1.Rows.Add();
}
label5.Text = "Заполните таблицу";
buttonResh.Enabled = true;
buttonSteps.Enabled = false;
}
// матрица по умолчанию
private void buttonDemo_Click(object sender, EventArgs e)
{
textBox1.Clear();
dataGridView1.Columns.Clear();
N = 21; M = 5; str = 5; //N - количество грузчиков, М - складов, str - строк в исходной таблице
int[,] T = new int[5, 6] { { 2, 10, 12, 14, 8, 18 }, { 4, 6, 8, 9, 5, 12 }, { 5, 5, 6, 6, 3, 10 }, { 6, 3, 4, 4, 2, 8 }, { 8, 2, 3, 2, 1, 4 } };
dataGridView1.Columns.Add("", "Количество грузчиков");
for (int i = 1; i < M + 1; i++) dataGridView1.Columns.Add("", "№" + i);
for (int j = 0; j < str; j++)
{
dataGridView1.Rows.Add();
}
for (int j = 0; j < M + 1; j++)
for (int i = 0; i < str; i++)
dataGridView1[j, i].Value = T[i, j];
dataGridView1.AutoResizeColumns();
buttonResh.Enabled = true;
buttonSteps.Enabled = false;
}
private void buttonSteps_Click(object sender, EventArgs e)
{
Process.Start("C:\\Windows\\System32\\notepad.exe", "new.txt");
}
}
}