Качественные оценки
|
Очень плохо
|
Плохо
|
Удовлетворительно
|
Хорошо
|
Отлично
|
Количественные оценки
|
0.0 - 0.2
|
0.2 - 0.36
|
0.36 - 0.63
|
0.63 - 0.8
|
0.8 - 1.0
|
Оценки типа «да/нет» так же
переводятся в числовую форму, причём оценке «да» соответствует значение - 0.67,
а «нет» - 0.33.
Все числовые оценки переводятся в
безразмерный вид (представить оценки в долях единицы) и при этом лучшей оценке
соответствует большее значение. Для осуществления такого перевода необходимо
разделить все значения оценок по данному критерию на максимальное значение
этого критерия.
. Необходимо реализовать метод
экспертного анализа - метод предпочтений. Данный метод основан на ранжировании
альтернатив, выполняемом группой экспертов. Каждый из экспертов (независимо от
других) выполняет ранжирование альтернатив, т.е. указывает, какая из
альтернатив, по его мнению, является лучшей, какая следующей за ней, и т.д.
Пусть имеется m экспертов: Э1, Э2,
..., Эm и n критериев: Z1, Z2, ..., Zn
Каждый эксперт проводит оценку
критериев, пользуясь числами натурального ряда. Наиболее важной цели
присваивается значение 1, менее важной -
2 и т.д. В этих условиях веса критериев определяются следующим образом:
составляется исходная матрица
k предпочтений размером m×n, причём 1 ≤
kij ≤ n, где ;
составляется модифицированная
матрица K предпочтений. С оценками:
; (2.1)
находятся суммарные оценки
предпочтений по каждому критерию:
; (2.2)
вычисляются исходные веса критериев:
(2.3)
Наиболее предпочтительной
является альтернатива, имеющая максимальный вес.
Для данного метода существует
возможность проверки согласованности экспертных оценок. Для этого вычисляется
коэффициент конкордации по следующему алгоритму. Сначала находятся суммы
оценок, указанных экспертами для каждой из альтернатив: , где . Затем
находится вспомогательная величина α:
(2.4)
Находится . Находится
коэффициент конкордации:
(2.5)
При υ ≥
0.5, степень согласованности экспертных оценок считается достаточной, в
противном случае требуется уточнение и согласование экспертных оценок.
. Реализуется метод Парето
для отбора бесперспективных альтернатив.
Суть данного метода
заключается в следующем: одна альтернатива превосходит вторую, если она
превосходит ее, по крайней мере, по одной компоненте и не хуже второй по любой
другой компоненте. Если альтернатива удовлетворяет этому свойству относительно
всех других альтернатив, то ее называют парето-оптимальной [7].
Парето позволяет из множества
всех возможных исключить заведомо неприемлемые решения, т.е. те, которые
никогда не могут оказаться выбранными, если выбор осуществляется достаточно
«разумно». После такого исключения остается множество, которое называют
множеством Парето или областью компромиссов.
Выбор множества Парето
производится следующим образом. Все альтернативы попарно сравниваются друг с
другом по всем критериям. Если при сравнении каких-либо альтернатив
оказывается, что одна из них не лучше другой ни по одному критерию, то ее можно
исключить из рассмотрения.
Данный метод позволяет
сократить количество альтернатив, но не позволяет получить окончательное
решение.
. Определяем лучшую
альтернативу методом анализа иерархий (МАИ). Рассмотрим более подробно данный
метод.
Метод анализа иерархий,
разработанный под руководством американского специалиста по исследованию операций
Т. Саати, применяется в настоящее время при решении самых разнообразных
проблем, среди которых, в частности: проектирование транспортных систем крупных
городов, разработка планов обеспечения энергетическими ресурсами отраслей
промышленности, оценка сценария развития высшего образования, определение
приоритетных направлений научных исследований и др.
МАИ
не предписывает лицу, принимающему решение (ЛПР), какого-либо «правильного»
решения, а позволяет ему в интерактивном режиме найти такой вариант (альтернативу),
который наилучшим образом согласуется с его пониманием сути проблемы и
требованиями к ее решению.
Анализ проблемы принятия решений в
МАИ начинается с построения иерархической структуры, которая включает цель,
критерии, альтернативы и другие рассматриваемые факторы, влияющие на выбор. Эта
структура отражает понимание проблемы лицом, принимающим решение. Каждый
элемент иерархии может представлять различные аспекты решаемой задачи, причем
во внимание могут быть приняты как материальные, так и нематериальные факторы,
измеряемые количественные параметры и качественные характеристики, объективные
данные и субъективные экспертные оценки. Иными словами, анализ ситуации выбора
решения в МАИ напоминает процедуры и методы аргументации, которые используются
на интуитивном уровне.
Следующим этапом анализа является
определение приоритетов, представляющих относительную важность или
предпочтительность элементов построенной иерархической структуры, с помощью
процедуры парных сравнений. Безразмерные приоритеты позволяют обоснованно
сравнивать разнородные факторы, что является отличительной особенностью МАИ.
На заключительном этапе анализа
выполняется синтез (линейная свертка) приоритетов на иерархии, в результате
которой вычисляются приоритеты альтернативных решений относительно главной
цели. Лучшей считается альтернатива с максимальным значением приоритета.
Иерархические структуры,
используемые в МАИ, представляет собой инструмент для качественного
моделирования сложных проблем. Вершиной иерархии является главная цель;
элементы нижнего уровня представляют множество вариантов достижения цели
(альтернатив); элементы промежуточных уровней соответствуют критериям или
факторам, которые связывают цель с альтернативами.
После построения иерархии участники
процесса используют МАИ для определения приоритетов всех узлов структуры.
Информация для расстановки приоритетов собирается со всех участников и
математически обрабатывается.
Приоритеты - это числа, которые
связаны с узлами иерархии. Они представляют собой относительные веса элементов
в каждой группе. Подобно вероятностям, приоритеты - безразмерные величины,
которые могут принимать значения от нуля до единицы. Чем больше величина
приоритета, тем более значимым является соответствующий ему элемент. Сумма
приоритетов элементов, подчиненных одному элементу выше лежащего уровня
иерархии, равна единице.
.3 Описание схемы алгоритма метода
Саати
Рассмотрим одну из основных схем
алгоритма созданного программного обеспечения - схему метода Саати,
представленную в приложении А и на рисунке 2.1. Метод Саати предназначен для
поиска весов критериев на основе оценок экспертов.
Рисунок 2.1 - Схема алгоритма
метода Саати
Данная схема состоит из восьми
основных блоков, два из них являются подпрограммами. Алгоритмы подпрограмм
представлены на рисунках 2.2 и 2.3 соответственно. Рассмотрим данные
подпрограммы более подробно.
Для вычисления весов критериев
необходимо для начала найти сумму экспертных оценок по каждому критерию, т.е.
по каждому столбцу матрицы оценок. Реализация данных действий отражена в схеме
алгоритма, представленной на рисунке 2.2 и является первой подпрограммой. В
результате работы данного алгоритма будет получен массив сумм по каждому
критерию.
Рисунок 2.2 - Схема алгоритма
вычисления сумм оценок по столбцам
Затем необходимо найти общую сумму
значений сформированного после работы предыдущей подпрограммы массива.
Реализация данных действий отражена в схеме алгоритма, представленной на
рисунке 2.3 и является второй подпрограммой. В результате работы данного
алгоритма получаем общую сумму оценок (числовое значение).
Рисунок 2.3 - Схема алгоритма
вычисления суммы значений массива
После завершения работы описанных
подпрограмм их результаты используются основным алгоритмом непосредственно для
вычисления весов критериев.
3. Описание разработанного
приложения
.1 Структура программного комплекса
Программное обеспечение для решения
поставленной задачи было реализовано в среде разработки MS Visual Studio на
языке C#. Данная среда разработки позволяет быстро, эффективно и просто создать
полноценное и многофункциональное приложение.
Созданное приложение состоит из семи
пользовательских классов, реализующих методы, описанные в разделе 2.2.
Рассмотрим каждый класс более подробно.
Класс Odnomernaj - содержит методы
для организации однокритериальной оптимизации методом полного перебора по
заданному критерию с учётом ограничений. Рассмотрим структуру класса.
Данный класс включает следующие
поля:- содержит технические характеристики всех альтернатив. Тип поля
DataGridView.- содержит технические характеристики альтернатив подходящих по
заданному критерию. Тип поля DataGridView.-
количество часов на изготовление изделий в месяц. Тип поля double.- максимально
возможная потребляемая мощность станками в месяц. Тип поля double.- количество
изделий, выпускаемых предприятием в год. Тип поля double.- максимально
возможная общая стоимость станков. Тип поля double.
В классе реализован конструктор,
инициализирующий поля, описанные выше. Так же в классе определены следующие
методы:- реализует метод полного перебора по критерию «Производительность». В
данном методе так же реализована проверка на соответствие альтернатив
ограничениям. Результатом метода является список альтернатив, в которых
значение критерия «Производительность» удовлетворяет ограничениям.- реализует
метод полного перебора по критерию «Стоимость». В данном методе так же
реализована проверка на соответствие альтернатив ограничениям. Результатом
метода является список альтернатив, в которых значение критерия «Стоимость»
удовлетворяет ограничениям.- реализует метод полного перебора по критерию
«Энергоэффективность». В данном методе так же реализована проверка на
соответствие альтернатив ограничениям. Результатом метода является список
альтернатив, в которых значение критерия «Энергоэффективность» удовлетворяет
ограничениям.- сортирует список, полученный в методе Proiz или Stoim,или Energ,
по убаванию или возрастанию знасения выбранного критерия (например, если выбран
критерий «Стоимость», то список отсортируется по возростанию). На вход подается
список альтернатив, а на выходе получаем отсортированный список, причем первый
элемент списка - лучшая альтернатива по выбранному критерию.
Класс Mnogomernaj - реализует
методы, необходимые для организации многокритериальной оптимизации. Рассмотрим
данный класс более подробно.
Данный класс включает следующие
поля:- содержит технические характеристики всех альтернатив. Тип поля
DataGridView.- содержит технические характеристики альтернатив подходящих по
заданному критерию. Тип поля DataGridView., oc2 - матрицы экспертных оценок
первого и второго экспертов соответственно. Тип поля double [ ,];- содержит веса
критериев. Тип поля double [ ];- содержит итоговые оценки альтернатив. Тип поля
double [ ];- коэффициент согласованности. Тип поля double.
В классе реализован конструктор для
инициализации вышеперечисленных полей. В классе определены следующие методы:-
реализует метод Парето для отбора бесперспективных альтернатив. На вход
подаются приведённые в безразмерный вид характеристики станков двух типов. В
результате работы метода из сформированных ранее альтернатив удаляются
бесперспективные альтернативы;- предназначен для сравнения одной альтернативы с
оставшимися. На вход передается номер альтернативы, которую неоюходимо сравнить
с оставшимися. - перевод количественных оценок в безразмерный вид. В качестве
параметров метод получает массив исходных оценок (которые нужно перевести),
переменную типа bool, которая принимает значение true - если по значению оценка
чем больше, тем лучше и false - иначе (например, если рассматривать оценки по
критерию «Стоимость», то чем ниже оценка по данному критерию, тем лучше эта альтернатива
для нас, а если - оценки по критерию «Производительность», то чем ниже оценка,
тем хуже данная альтернатива);- перевод оценок типа «Да/Нет» и перевод
качественных оценок по шкале Харрингтона. В качестве параметров метод принимает
строковое представление исходный оценки.- вычесляет коэффициент
соглассованности выставленных экспертами оценок. Возвращает число типа double;-
расчитывает значения весов по каждому критерию.- реализует метод экспертного
аннализа Саати и метод анализа иерархий. Для реализации метода Саати
используются методы Soglas и Veskrit, описанные выше. Результатом выполнения
метода является массив, содержащий итогорые оценки каждой альтернативы.
Класс Vizual - содержит методы для
отображения результатов работы, как однокритериальной, так и многокритериальной
оптимизации.
Класс Form4 - содержит графический
интерфейс пользователя для ввода оценок экспертом.
Класс Form2 - содержит графический
интерфейс пользователя и использует методы класса Odnomernaj. В результате
выдается конечный результат работы приложения по однокритериальной оптимизации.
Класс Form1 - содержит графический
интерфейс пользователя и использует классы Form2 и Form3.
Исходный код приложения представлен
в приложении А.
.2 Инструкция пользователя
Разработанный пользовательский
интерфейс является простым и интуитивно-понятным для обычного пользователя.
Созданное приложение предназначено
помочь принять решение о покупке станков двух типов лицу принимающему решение.
После запуска exe-файла появляется основное окно, представленное на рисунке
3.1.
Рисунок 3.1 - Вид главного окна
приложения
Всё приложение разделено на две
основные области. Рассмотрим их:
) Область «Технические
характеристики станков» -
предназначена для ввода технических характеристик станков. В первую таблицу
заносятся параметры станков первого типа, во вторую - второго типа. Так же в
данных таблицах можно редактировать данные. Для редактирования необходимо
выбрать нужную ячейку, кликнуть по ней два раза и ввести новое значение вместо
старого.
) Область «Меню» -
это основная часть приложения. Как видно из рисунка 3.1 она состоит из двух
вкладок «Однокритериальная оптимизация» и «Многокритериальная оптимизация».
Рассмотрим данную часть приложения более подробно.
Вкладка «Однокритериальная
оптимизация» предназначена для проведения одномерной оптимизации. Чтобы
программа провела оптимизацию для начала необходимо выбрать один из трёх
предлагаемых критериев: производительность, энергоэффективность и стоимость.
После выбора критерия нужно нажать кнопку «Оптимизировать» после чего
приложение выдаст результат проведенной оптимизации, т.е. лучшую пару станков,
которые будут выделены красным (лучшая альтернатива по выбранному параметру) и
оранжевым (вторая и третья альтернативы, после лучшей) цветами в соответствии с
рисунком 3.2.
Рисунок 3.2 - Результат работы
одномерной оптимизации
Вкладка «Многокритериальная
оптимизация» предназначена для проведения многомерной оптимизации. Для
проведения многомерной оптимизации, необходимо, чтобы два эксперта дали оценки
критериям, необходимые для решения задачи.
Для того, чтобы ввести оценки
экспертов, нужно нажать на кнопку «Оптимизировать», после чего появится новое
окно, что позволит нам ввести оценки первого эксперта. После ввода оценок жмем
кнопку «Ок», после чего выскакивает новое окно, которое позволяет ввести оценки
второго эксперта. Если оценки не будут введены, при закрытии окон будет выдано
сообщение, представленное на рисунке 3.3
Рисунок 3.3 - Окно, появляющееся,
если не введены оценки экспертов
Для закрытия данного окна нужно
нажать кнопку «OK», после чего снова появится главное окно приложения и в нём
можно снова нажать кнопку «Оптимизировать» и ввести оценки экспертов.
После задания оценок нужно нажать
кнопку «Оптимизировать» и приложение выдаст результат оптимизации как
представлено на рисунке 3.4.
Рисунок 3.4 - Результат работы
многомерной оптимизации
Таким образом были рассмотрены
основные функции и возможности пользовательского приложения, а так же детально
разъяснена работа с данным приложением и указаны основные ошибки, которые могут
возникать при работе приложения и описаны пути их устранения.
.3 Анализ исходных данных и
верификация результатов работы программы
В поставленной задаче в качестве
исходных данных выступают технические характеристики двух типов станков по
следующим шести критериям: производительность, энергоэффективность, стоимость
станка, сервисное обслуживание, надёжность и удобство в использовании. По
данным характеристикам и происходит выбор двух станков разного типа, но так же
по условию задачи мало, чтобы станки соответствовали максимальным
характеристикам по всем критериям, они должны соответствовать следующим
ограничениям: стоимость двух станков не должна превышать 1000 млн. рублей,
максимальная потребляемая мощность не должна превышать 50000 кВт-ч в месяц,
количество изготавливаемых изделий в год должно быть не менее 10000 штук в год,
на изготовление изделия тратиться не более 200 часов в месяц. На основе всех
вышеописанных данных производится отбор лучшей пары станков.
Для проверки правильности работы
программы нужно сравнить работу приложения при однокритериальной и
многокритериальной оптимизации. Причём, выбранному критерию в одномерной
оптимизации должны быть выставлены максимальные оценки в многокритериальной
оптимизации. Если результаты первых альтернатив совпадают, то можно утверждать,
что приложение работает верно. Проведение верификации приложения представлено
на примере.
Для начала проведём одномерную
оптимизацию по критерию производительность. Приложение выдаст результат в
соответствии с рисунком 3.5.
Затем необходимо провести
многокритериальную оптимизацию. После выполнения оптимизации приложение выдаст
результат в соответствии с рисунком 3.6.
После выполнения оптимизаций
необходимо сравнить сравнение результатов. Но так как при многокритериальной
оптимизации, производительность пусть и основной критерий, но с учетом всех
шести критериев результаты однокритериальной оптимизации и многокритериальной
могут не совпадать, что мы и можем наблюдать в данном случае.
Рисунок 3.5 - Окно, показывающее
правильность работы однокритериальной оптимизации по критерию
производительность.
Рисунок 3.6 - Окно, показывающее
правильность работы многокритериальной оптимизации по критерию
энергоэффективности.
Заключение
В соответствии с заданием по
курсовому проекту, было спроектировано и реализовано приложение, позволяющее
производить однокритериальную и многокритериальную оптимизацию. Результаты
работы данного приложения были хорошо проанализированы и была проведена
успешная верификация полученных результатов, что даёт основания для
использования данного приложения на практике.
Разработанное приложение содержит
простой и интуитивно понятный пользовательский интерфейс, что достигается путём
использования принятых концепций проектирования интерфейса, при разработке
приложения. Однако для подготовки к использованию данного приложения была
разработана инструкция пользователя, которую рекомендуется прочесть перед
началом использования.
Так же приложение позволяет,
выводить не только самый лучший результат, но и второй и третий результат по
степени оптимальности. Это позволяет хотя бы немного учитывать человеческий
фактор при оптимизации.
Теоретическая значимость данного
курсового проекта состоит в том, что были изучены методы многокритериальной
оптимизации, такие как метод анализа иерархий, метод Саати, метод выбора
множества Парето. Знание этих методов нужно не только для того, что бы уметь
писать приложения для оптимизации проектных решений, знание этих методов
заставляет смотреть на принятие решений в нашей жизни более рационально,
принимая во внимание все возможные факторы. Данная курсовая работа значительно
расширила обзор в области принятия решения и показала, что даже в этой области
может успешно применяться автоматизация.
Список использованных источников
1. Горбунов, В.М. Теория
принятия решений. Учебное пособие / В.М. Горбунов. -
Томск: Национальный исследовательский томский политехнический университет,
2010. - 67 с.
2. Матузко, Ю.О. Теория
принятия решений. Учебно-методическое пособие / Ю.О. Матузко. -
Запорожье: Запорожская государственная инженерная академия, 2009. -
61 с.
. Лесин В.В., Лисовец
Ю.П. Основы методов оптимизации. - М.: Изд-во МАИ, 1995. - 344 с.
. Информационные
технологии оптимальных решений. Учебный курс для специальности «Государственное
управление и экономика». - Минск:
Академия управления при Президенте Республики Беларусь, 2003. -
241 с.
. Шикин, Е.В.
Исследование операций / Е.В. Шикин, Г.Е. Шикина.-
М.: ТК Велби, Изд-во Проспект, 2006. -
280 с.
. Саати, Т. Л. Принятие
решений. Метод анализа иерархий / Т. Саати. -
М.: Радио и связь, 1993. - 278 с.
. Подиновский, В.В.
Парето-оптимальные решения многокритериальных задач. / В. В. Подиновский, В.Д.
Ногин.- М.: Наука. Главная редакция, 2007.
- 256 с.
Приложение А
Листинг программы
Класс
OdnomernajSystem;System.Collections.Generic;System.Linq;System.Text;System.Drawing;System.Windows.Forms;WindowsFormsApplication1
{
class Odnomernaj
{
DataGridView dataGridView1;
DataGridView dataGridView2;
double koluz, chasmes, stoim,
moshnmes;
public Odnomernaj(DataGridView
dataGridView1, DataGridView dataGridView2, double koluz, double chasmes, double
stoim, double moshnmes)
{
this.dataGridView1 = dataGridView1;
this.dataGridView2 = dataGridView2;
this.koluz = koluz;
this.moshnmes = moshnmes;
this.stoim = stoim;
this.chasmes = chasmes;
}
public void Proiz() //поиск
альтернатив подходящих по производительности
{
int k = 0;
Sort(1, false);
for (int i = 0; i < dataGridView1.RowCount;
i++)
if (double.Parse(dataGridView1[1,
i].Value.ToString()) >= (koluz / 12) / chasmes)
{
dataGridView2.RowCount = k + 1;
dataGridView2[0, k].Value =
dataGridView1[0, i].Value;
dataGridView2[1, k].Value =
dataGridView1[1, i].Value;
dataGridView2[2, k].Value =
dataGridView1[2, i].Value;
dataGridView2[3, k].Value =
dataGridView1[3, i].Value;
k++;
}
Vizual.viz(dataGridView2);
}
public void Stoim() //поиск
альтернатив подходящих по стоимости
{
int k = 0;
Sort(2, true);
for (int i = 0; i <
dataGridView1.RowCount; i++)
if (double.Parse(dataGridView1[2,
i].Value.ToString()) <= stoim)
{
dataGridView2.RowCount = k + 1;
dataGridView2[0, k].Value =
dataGridView1[0, i].Value;
dataGridView2[1, k].Value =
dataGridView1[1, i].Value;
dataGridView2[2, k].Value =
dataGridView1[2, i].Value;
dataGridView2[3, k].Value =
dataGridView1[3, i].Value;
k++;
}
Vizual.viz(dataGridView2);
}
public void Energ() //поиск
альтернатив подходящих по энергоэффективности
{
int k = 0;
Sort(3, true);
for (int i = 0; i <
dataGridView1.RowCount; i++)
if (moshnmes >= chasmes *
double.Parse(dataGridView1[1, i].Value.ToString()) *
double.Parse(dataGridView1[3, i].Value.ToString()))
{
dataGridView2.RowCount = k + 1;
dataGridView2[0, k].Value =
dataGridView1[0, i].Value;
dataGridView2[1, k].Value =
dataGridView1[1, i].Value;
dataGridView2[2, k].Value =
dataGridView1[2, i].Value;
dataGridView2[3, k].Value =
dataGridView1[3, i].Value;
k++;
}
Vizual.viz(dataGridView2);
}
public void Sort(int ii, bool f)
//метод сортировки по заданному столбцу
{
object temp = 0;
if (f)
for (int i = 0; i <
dataGridView1.RowCount; i++)
for (int j = i; j <
dataGridView1.RowCount; j++)
{
if (double.Parse(dataGridView1[ii,
i].Value.ToString()) > double.Parse(dataGridView1[ii, j].Value.ToString()))
{
for (int k = 0; k <
dataGridView1.ColumnCount; k++)
{
temp = dataGridView1[k, i].Value;
dataGridView1[k, i].Value =
dataGridView1[k, j].Value;
dataGridView1[k, j].Value = temp;
}
}
}
else
for (int i = 0; i <
dataGridView1.RowCount; i++)
for (int j = i; j <
dataGridView1.RowCount; j++)
if (double.Parse(dataGridView1[ii,
i].Value.ToString()) < double.Parse(dataGridView1[ii, j].Value.ToString()))
{
for (int k = 0; k <
dataGridView1.ColumnCount; k++)
{
temp = dataGridView1[k, i].Value;
dataGridView1[k, i].Value =
dataGridView1[k, j].Value;
dataGridView1[k, j].Value = temp;
}
}
}
}
}
Класс
MnogomernajSystem;System.Collections.Generic;System.Linq;System.Text;System.Windows.Forms;WindowsFormsApplication1
{
class Mnogomernaj
{
double temp;
object[,] A; //массив альтернатив
double[,] oc1, oc2; //массивы оценок
double[] ves, //веса альтернатив
A1, //оценки ольтернативы
soglas;
DataGridView dataGridView1,
dataGridView2;
ListBox listBox1;
Label label1;
object DGVR;
Form5 f5;
Form4 f4;
public Mnogomernaj(DataGridView
dataGridView1, DataGridView dataGridView2, ListBox listBox1, Label label1)
{
this.dataGridView1 = dataGridView1;
this.dataGridView2 = dataGridView2;
this.listBox1 = listBox1;
this.label1 = label1;
f5 = new Form5();
f4 = new Form4();
}
void Altern() //запись всех
альтернатив в матрицу
{
A = new
object[dataGridView1.RowCount, dataGridView1.ColumnCount];
A1 = new double[A.GetLength(0)];
for (int i = 0; i <
dataGridView1.RowCount; i++)
for (int k = 0; k <
dataGridView1.ColumnCount; k++)
A[i, k] = dataGridView1[k, i].Value;
}
public void Pareto()//метод Парето
{
Altern();
int kk = 0;
for (int i = 0; i <
A.GetLength(0); i++)
if (Sravnenie(i))
{
dataGridView1.RowCount = kk + 1;
for (int g = 0; g <
A.GetLength(1); g++)
dataGridView1[g, kk].Value = A[i,
g];
kk++;
}
}
bool Sravnenie(int ii) //метод
сравнения альтернатив
{
bool f = true;
for (int i = 0; i <
A.GetLength(0) && f; i++)
if (ii != i &&
Convert.ToDouble(A[ii, 1]) <= Convert.ToDouble(A[i, 1]) &&
Convert.ToDouble(A[ii, 2]) >= Convert.ToDouble(A[i, 2]) &&
Convert.ToDouble(A[ii, 3]) >= Convert.ToDouble(A[i, 3]) &&
Convert.ToDouble(A[ii, 4]) <= Convert.ToDouble(A[i, 4]) &&
Convert.ToDouble(A[ii, 5]) <= Convert.ToDouble(A[i, 5]) &&
Convert.ToDouble(A[ii, 6]) <= Convert.ToDouble(A[i, 6]))
f = false;
return f;
}
void Perev() //метод перевода
значений критериев в безразмерные величины
{
double temp = 0;
dataGridView2.RowCount =
dataGridView1.RowCount;
dataGridView2.ColumnCount =
dataGridView1.ColumnCount;
for (int i = 0; i <
A.GetLength(1); i++)
{
if (i == 1 || i == 5)
{
for (int k = 0; k <
A.GetLength(0); k++)
if (temp < Convert.ToDouble(A[k,
i]))
temp = Convert.ToDouble(A[k, i]);
for (int k = 0; k <
A.GetLength(0); k++)
dataGridView2[i, k].Value =
String.Format("{0:f2}", (Convert.ToDouble(dataGridView1[i, k].Value)
/ temp));
}
else
if (i == 2 || i == 3)
{
for (int k = 0; k <
A.GetLength(0); k++)
if (temp < Convert.ToDouble(A[k,
i]))
temp = Convert.ToDouble(A[k, i]);
for (int k = 0; k <
A.GetLength(0); k++)
dataGridView2[i, k].Value =
String.Format("{0:f2}", (1 - (Convert.ToDouble(dataGridView1[i,
k].Value) / temp)));
}
else
{
for (int k = 0; k <
A.GetLength(0); k++)
dataGridView2[i, k].Value =
dataGridView1[i, k].Value;
}
temp = 0;
}
}
double Soglas() //метод проверки соглассованности
выставленных оценок
{
soglas = new
double[oc1.GetLength(1)];
ves = new double[oc2.GetLength(1)];
double pr = 0;
for (int i = 0; i <
oc1.GetLength(1); i++)//вычисление суммы оценок по столбцам
{
for (int k = 0; k <
oc1.GetLength(0); k++)
pr = pr + Math.Abs(oc1[k, i] -
oc2[k, i]);
soglas[i] = pr;
pr = 0;
}
double sog = 0;
for (int i = 0; i <
soglas.Length; i++)
{
sog = sog + Math.Pow(soglas[i], 2);
}
double W = 1 - ((12 * sog) / (2 * 2
* (6 * 6 * 6 - 6)));//расчет коэффициента согласованности
return W;
}
void veskrit() //метод вычисления
веса каждого из критериев
{
double pr = 0;
for (int i = 0; i <
oc2.GetLength(1); i++)
{
for (int k = 0; k <
oc2.GetLength(0); k++)
pr = pr + oc2[i, k]+ oc1[i,k];
ves[i] = pr;
pr = 0;
}
for (int i = 0; i < ves.Length;
i++)
pr += ves[i];
listBox1.Items.Clear();
for (int i = 0; i < ves.Length;
i++)
{
ves[i] = ves[i] / pr;
listBox1.Items.Add(dataGridView2.Columns[i
+ 1].HeaderText + " " + ves[i].ToString("f3"));
}
}
void Sort()
{
for (int i = 0; i < A1.Length;
i++)
for (int j = 0; j < A1.Length;
j++)
if (A1[i] > A1[j])
{
temp = A1[i];
A1[i] = A1[j];
A1[j] = temp;
for (int ii = 0; ii <
dataGridView2.ColumnCount; ii++)
{
DGVR = dataGridView2[ii, i].Value;
dataGridView2[ii, i].Value =
dataGridView2[ii, j].Value;
dataGridView2[ii, j].Value = DGVR;
}
for (int ii = 0; ii <
dataGridView1.ColumnCount; ii++)
{
DGVR = dataGridView1[ii, i].Value;
dataGridView1[ii, i].Value =
dataGridView1[ii, j].Value;
dataGridView1[ii, j].Value = DGVR;
}
}
}
public void Saati()
{
bool f1, f2;
f1 = false;
f2 = false;
Altern();
Perev();
P1:
f4.Text = "Эксперт 1";
if (f4.ShowDialog() ==
DialogResult.OK)
{
oc1 = new
double[f4.dataGridView1.RowCount, f4.dataGridView1.ColumnCount];
for (int i = 0; i <
f4.dataGridView1.RowCount; i++)
for (int k = 0; k <
f4.dataGridView1.ColumnCount; k++)
{
oc1[i, k] =
Convert.ToDouble(f4.dataGridView1[k, i].Value);
}
f1 = true;
}
f4.Text = "Эксперт 2";
if (f4.ShowDialog() ==
DialogResult.OK)
{
oc2 = new
double[f4.dataGridView1.RowCount, f4.dataGridView1.ColumnCount];
for (int i = 0; i <
f4.dataGridView1.RowCount; i++)
for (int k = 0; k <
f4.dataGridView1.ColumnCount; k++)
{
oc2[i, k] =
Convert.ToDouble(f4.dataGridView1[k, i].Value);
}
f2 = true;
}
if (f1 && f2)
{
if (Soglas() >= 0.5)
{
veskrit();
double pr = 0;
for (int i = 0; i < A1.Length;
i++)//расчет итоговых весов альтернатив
{
for (int k = 0; k < ves.Length;
k++)
{
pr = pr + ves[k] *
Convert.ToDouble(dataGridView2[k + 1, i].Value);
}
A1[i] = pr;
pr = 0;
}
dataGridView2.ColumnCount =
dataGridView2.ColumnCount + 1;
dataGridView2.Columns[7].HeaderText
= "Оценка";
for (int i = 0; i < A1.Length;
i++)
{
dataGridView2[dataGridView2.ColumnCount
- 1, i].Value = A1[i].ToString("f4"); ;
}
Sort();
Vizual.viz(dataGridView2,
dataGridView1);
label1.Text = "Лучшая
альтернатива многомерной оптимизации - " + dataGridView2[0,
0].Value.ToString();
dataGridView2.Visible = true;
dataGridView1.Visible = false;
}
else
MessageBox.Show("Оценки
экспертов не согласованны");
goto P1;
}
}
else MessageBox.Show("Оценки
экспертов не введены");
}
}
}
Класс
VizualSystem;System.Collections.Generic;System.Linq;System.Text;System.Drawing;System.Windows.Forms;WindowsFormsApplication1
{
class Vizual
{
public static void viz(DataGridView
dataGridView2)
{
for (int i = 0; i <
dataGridView2.RowCount; i++)
for (int k = 0; k <
dataGridView2.ColumnCount; k++)
{
if (i == 0)
{
dataGridView2[k, i].Style.BackColor
= Color.Red;
}
else if (i == 1 || i == 2)
{
dataGridView2[k, i].Style.BackColor
= Color.Gold;
}
else
{
dataGridView2[k, i].Style.BackColor
= Color.White;
}
}
}
public static void viz(DataGridView
dataGridView2, DataGridView dgv1)
{
for (int i = 0; i <
dataGridView2.RowCount; i++)
for (int k = 0; k <
dgv1.ColumnCount; k++)
{
dataGridView2[k, i].Value = dgv1[k,
i].Value;
if (i == 0)
{
dataGridView2[k, i].Style.BackColor
= Color.Red;
}
else if (i == 1 || i == 2)
{
dataGridView2[k, i].Style.BackColor
= Color.Gold;
}
else
{
dataGridView2[k, i].Style.BackColor
= Color.White;
}
}
}
}
}
Класс
Form1System;System.Collections.Generic;System.ComponentModel;System.Data;System.Drawing;System.Linq;System.Text;System.Windows.Forms;System.IO;WindowsFormsApplication1
{
public partial class Form1 : Form
{
int n;
Form2 f2;
Form3 f3;
public object[,] S1, S2;
public double koluz, chasmes, stoim,
moshnmes;
public Form1()
{
InitializeComponent();
dataGridView1.RowCount = 5;
dataGridView1.ColumnCount = 7;
dataGridView2.RowCount = 5;
dataGridView2.ColumnCount = 7;
n = 0;
S1 = new object[5, 6];
S2 = new object[5, 6];
//чтение данных из файла
StreamReader strim = new
StreamReader("Stanki1.mdb");
while (!strim.EndOfStream)
{
string str = strim.ReadLine();
string[] st = str.Split();
for (int i = 0; i < st.Length;
i++)
{
dataGridView1[i, n].Value = st[i];
}
n++;
}
strim.Close();
for(int g=0; g < S1.GetLength(0);
g++)
for(int i=0; i < S1.GetLength(1);
i++)
S1[g, i] =
dataGridView1[i+1,g].Value;
strim = new
StreamReader("Stanki2.mdb");
n = 0;
while (!strim.EndOfStream)
{
string str = strim.ReadLine();
string[] st = str.Split();
for (int i = 0; i < st.Length;
i++)
dataGridView2[i, n].Value = st[i];
n++;
}
strim.Close();
for (int g = 0; g <
S1.GetLength(0); g++)
for (int i = 0; i <
S1.GetLength(1); i++)
S2[g, i] = dataGridView2[i+1,
g].Value;
koluz = 15000;
chasmes = 150;
stoim = 2000;
moshnmes = 100000;
f2 = new Form2();
f3 = new Form3();
}
private void
выходToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
}
private void
одномернаяОптимизацияэToolStripMenuItem_Click(object sender, EventArgs e)
{
f2.dataGridView1.RowCount =
dataGridView1.RowCount * dataGridView2.RowCount;
for (int i=0; i <
S1.GetLength(0); i++)
for (int j = 0; j <
S2.GetLength(0); j++)
{
f2.dataGridView1[0, i *
S2.GetLength(0) + j].Value = "ST1" + (i+1).ToString() + " +
ST2" + (j+1).ToString();
if (int.Parse(S1[i, 0].ToString())
> int.Parse(S2[j, 0].ToString()))
f2.dataGridView1[1, i *
S2.GetLength(0) + j].Value = S2[j, 0];
else
f2.dataGridView1[1, i *
S2.GetLength(0) + j].Value = S1[i, 0];
f2.dataGridView1[2, i *
S2.GetLength(0) + j].Value = int.Parse(S1[i, 1].ToString()) + int.Parse(S2[j,
1].ToString());
f2.dataGridView1[3, i *
S2.GetLength(0) + j].Value = double.Parse(S1[i, 2].ToString()) +
double.Parse(S2[j, 2].ToString());
}
f2.koluz = koluz;
f2.chasmes = chasmes;
f2.stoim = stoim;
f2.moshnmes = moshnmes;
f2.dataGridView1.Visible = true;
f2.dataGridView2.Visible = false;
f2.ShowDialog();
}
private void
многомернаяОптимизацияToolStripMenuItem_Click(object sender, EventArgs e)
{
f3.dataGridView1.RowCount =
dataGridView1.RowCount * dataGridView2.RowCount;
for (int i = 0; i <
S1.GetLength(0); i++)
for (int j = 0; j <
S2.GetLength(0); j++)
{
f3.dataGridView1[0, i *
S2.GetLength(0) + j].Value = "ST1" + (i + 1).ToString() + " +
ST2" + (j + 1).ToString();
if (int.Parse(S1[i, 0].ToString())
> int.Parse(S2[j, 0].ToString()))
f3.dataGridView1[1, i *
S2.GetLength(0) + j].Value = S2[j, 0];
else
f3.dataGridView1[1, i *
S2.GetLength(0) + j].Value = S1[i, 0];
f3.dataGridView1[2, i *
S2.GetLength(0) + j].Value = int.Parse(S1[i, 1].ToString()) + int.Parse(S2[j,
1].ToString());
f3.dataGridView1[3, i *
S2.GetLength(0) + j].Value = double.Parse(S1[i, 2].ToString()) +
double.Parse(S2[j, 2].ToString());
f3.dataGridView1[4, i *
S2.GetLength(0) + j].Value = (Perevod(S1[i, 3].ToString()) + Perevod(S2[j,
3].ToString())) / 2;
if (int.Parse(S1[i, 4].ToString())
> int.Parse(S2[j, 4].ToString()))
f3.dataGridView1[5, i *
S2.GetLength(0) + j].Value = S2[j, 4];
else
f3.dataGridView1[5, i *
S2.GetLength(0) + j].Value = S1[i, 4];
f3.dataGridView1[6, i *
S2.GetLength(0) + j].Value = (Perevod(S1[i, 5].ToString()) + Perevod(S2[j,
5].ToString())) / 2;
}
f3.dataGridView1.Visible = true;
f3.dataGridView2.Visible = false;
f3.ShowDialog();
}
public double Perevod(string str)
//метод перевода аналитических оценок
{
if (str.CompareTo("Да") ==
0) return 0.67;
if (str.CompareTo("Нет")
== 0) return 0.33;
if (str.CompareTo("Плохо")
== 0) return 0.25;
if
(str.CompareTo("Отлично") == 0) return 0.9;
if
(str.CompareTo("Хорошо") == 0) return 0.63;
if
(str.CompareTo("Очень_хорошо") == 0) return 0.8;
else return -1;
}
}
}