Информационная система поддержки принятия решений в условиях многокритериальной оптимизации
Основные понятия теории принятия решений. Формализация задач принятия решений. Однокритериальные и многокритериальные задачи в условиях определенности. Методы оценки многокритериальных альтернатив. Методы построения аддитивной функции полезности.
Рубрика | Менеджмент и трудовые отношения |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 08.07.2014 |
Размер файла | 2,9 M |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Рис. 5.3.1 Объекты и контейнеры.
На рис. 5.3.2 приведены сформированные слои Парето, выделенные из исходного множества на основании предпочтений ЛПР. Объекты внутри слоёв отсортированы по полезности. Полезность объекта при упаковке прямо пропорциональна значениям оценок по критериям и обратно пропорциональна массе и объёму.
Рис. 5.3.2 Слои Парето, отсортированные по полезности.
На рис. 5.3.3 показаны слои Парето, отсортированные по объёму и массе.
Рис. 5.3.3 Слои Парето, отсортированные по объёму и массе.
Результаты упаковки для сортировки по полезности и по объёму и массе показаны на рисунках 5.3.4 и 5.3.5 соответственно.
Рис. 5.3.4 Результат упаковки при сортировке по полезности.
Рис. 5.3.5 Результат упаковки при сортировке по объёму и весу.
Заключение
В процессе работы над дипломным проектом разработана и написана программа, реализующая процесс упаковки предметов с заданными параметрами (масса и объем) по контейнерам в условиях недостаточности контейнеров для упаковки всех предметов. После процесса упаковки возможен просмотр полученных данных (результатов) в виде текстовой информации. В ходе выполнения работы были описаны методы оценки многомерных альтернатив и один из методов решения многокритериальных задач.
Было рассмотрено и решено два варианта задачи об упаковке. В первом случае полученная информация позволяет определить порядок упаковки многокритериальных объектов, а во втором позволяет определить, каким образом можно упаковать парные объекты.
Список использованных источников
1. Ногин В.Д. Принятие решений в многокритериальной среде: количественный подход, М.: ФИЗМАТЛИТ, 2004, 176с.
2. Ларичев О.И. Объективные модели и субъективные решения. М.: Изд-во "Наука", 1987. 480с.
3. П. Ноутон, Г. Шилдт Java 2 в подлиннике, БХВ-Петербург, 2008 г., 1072 стр.
Приложения
Приложение 1
Классы предметной области.
При чтении кода рекомендуется обращать внимание на комментарии (текст после последовательностей " // " и между последовательностями "/**" и "*/"). Код, к которому относится конкретный комментарий, расположен ниже него.
Класс "Упаковываемый объект". Параметры этого класса - ID, объём, вес, оценки по пяти критериям и ссылка на парный объект.
/**
* Упаковываемый объект.
* @author AtemB
*
*/
public class Item {
/** ID. */
String id;
/** Объём. */
int volume;
/** Вес. */
int weight;
/** Критерий 1. */
int rate1;
/** Критерий 2. */
int rate2;
/** Критерий 3. */
int rate3;
/** Критерий 4. */
int rate4;
/** Критерий 5. */
int rate5;
/** Ссылка на парный объект. */
private Item pair;
public Item (String id,
int volume,
int weight,
int rate1,int rate2,int rate3,int rate4,int rate5) {
super ();
this. id = id;
this. volume = volume;
this. weight = weight;
this. rate1 = rate1;
this. rate2 = rate2;
this. rate3 = rate3;
this. rate4 = rate4;
this. rate5 = rate5;
}
/***/
public Item () {
this. id = 0 + "";
this. volume = 0;
this. weight = 0;
this. rate1 = 0;
this. rate2 = 0;
this. rate3 = 0;
this. rate4 = 0;
this. rate5 = 0;
}
public String getId () {
return id;
}
public Item getPair () {
return pair;
}
public void setPair (Item pair) {
this. pair = pair;
}
public boolean hasPair () {
return pair! = null;
}
/**
* @return the volume
*/
public int getVolume () {
return volume;
}
/**
* @return the weight
*/
public int getWeight () {
return weight;
}
/**
* @return the rate1
*/
public int getRate1 () {
return rate1;
}
/**
* @return the rate2
*/
public int getRate2 () {
return rate2;
}
/**
* @return the rate3
*/
public int getRate3 () {
return rate3;
}
/**
* @return the rate4
*/
public int getRate4 () {
return rate4;
}
/**
* @return the rate5
*/
public int getRate5 () {
return rate5;
}
/**
* @param volume the volume to set
*/
public void setVolume (int volume) {
this. volume = volume;
}
/**
* @param weight the weight to set
*/
public void setWeight (int weight) {
this. weight = weight;
}
/**
* @param rate1 the rate1 to set
*/
public void setRate1 (int rate1) {
this. rate1 = rate1;
}
/**
* @param rate2 the rate2 to set
*/
public void setRate2 (int rate2) {
this. rate2 = rate2;
}
/**
* @param rate3 the rate3 to set
*/
public void setRate3 (int rate3) {
this. rate3 = rate3;
}
/**
* @param rate4 the rate4 to set
*/
public void setRate4 (int rate4) {
this. rate4 = rate4;
}
/**
* @param rate5 the rate5 to set
*/
public void setRate5 (int rate5) {
this. rate5 = rate5;
}
/* (non-Javadoc)
* @see java. lang. Object#equals (java. lang. Object)
*/
@Override
public boolean equals (Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (! (obj instanceof Item)) {
return false;
}
Item other = (Item) obj;
if (rate1! = other. rate1) {
return false;
}
if (rate2! = other. rate2) {
return false;
}
if (rate3! = other. rate3) {
return false;
}
if (rate4! = other. rate4) {
return false;
}
if (rate5! = other. rate5) {
return false;
}
if (volume! = other. volume) {
return false;
}
if (Double. doubleToLongBits (weight)! = Double
. doubleToLongBits (other. weight)) {
return false;
}
return true;
}
@Override
public Item clone () {
Item clone = new Item (id, volume, weight, rate1, rate2, rate3, rate4, rate5);
return clone;
}
/* (non-Javadoc)
* @see java. lang. Object#toString ()
*/
@Override
public String toString () {
return "Объект" +
"\nID: " + id + ",\nОбъём: " + volume + ",\nВес: " + weight
+ ",\nКр.1: " + rate1 + ",\nКр.2: " + rate2 + ",\nКр.3: " + rate3
+ ",\nКр.4: " + rate4 + ",\nКр.5" + rate5 + ",\nID парного объекта: " + pair. id;
}
Класс "Контейнер". Его параметры - это ID, объём и грузоподъёмность.
/**
* Контейнер.
* @author AtemB
*
*/
public class Container {
/** ID. */
private int id;
/** Объём. */
private int volume;
/** Грузоподъёмность. */
private int cargo;
public Container (int id, int volume, int cargo) {
this. id = id;
this. volume = volume;
this. cargo = cargo;
}
public int getVolume () {
return volume;
}
public int getCargo () {
return cargo;
}
public int getId () {
return id;
}
/**
* @param volume the volume to set
*/
public void setVolume (int volume) {
this. volume = volume;
}
/**
* @param cargo the cargo to set
*/
public void setCargo (int cargo) {
this. cargo = cargo;
}
/**
* @param id the id to set
*/
public void setId (int id) {
this. id = id;
}
@Override
public Container clone () {
Container clone = new Container (id, volume, cargo);
return clone;
}
/* (non-Javadoc)
* @see java. lang. Object#toString ()
*/
@Override
public String toString () {
return "Контейнер" +
",\nID: " + id +
"\nОбъём: " + volume +
",\nГрузоподъёмность: " + cargo;
}
}
Класс ЛПР. У этого класса всего одно поле - список весов критериев, используемая им при расчёте полезности объекта. ЛПР умеет сравнивать объекты, используя вложенный класс "Бинарное отношение", умеет отображать пару объектов в один объект и получать значение полезности любого объекта. Для ЛПР в данном случае полезность объекта прямо пропорциональна значениям оценок по критериям объекта и обратно пропорциональна его массе и объёму.
/**
* ЛПР (лицо, принимающее решения).
* @author AtemB
*
*/
public class Boss {
class BossBinaryRelation implements BinaryRelation<Item> {
@Override
public Item compare (Item i1, Item i2) {
// Конечно, не самая пряморукая реализация, зато относительно понятна для восприятия.
// В этот список заносятся разности оценок по критериям.
List<Double> rates = new LinkedList<Double> ();
rates. add ( (double) (i1. rate1 - i2. rate1));
rates. add ( (double) (i1. rate2 - i2. rate2));
// Флаги в этом списке означают, положителен или отрицателен
// результат сравнения критериев.
// Одинаковые значения в список не заносятся.
List<Boolean> flags = new LinkedList<Boolean> ();
for (Double d: rates) {
if (d. doubleValue () > 0) {
flags. add (true);
} else if (d. doubleValue () < 0) {
flags. add (false);
}
}
// Если спиок флагов пуст, значит, объекты по проверяемым критериям равны.
if (flags. isEmpty ()) {
return null;
} else {
boolean resultFlag = false;
for (int i = 1; i < flags. size (); i++) {
resultFlag = flags. get (i);
// Если в списке встречаются разные значения флагов, значит,
// объекты несравнимы по значимым критериям
// (один лучше по одним критериям, другой по другим).
if (flags. get (i - 1)! = flags. get (i)) {
return null;
}
}
// Если предыдущий цикл выполнился до конца, значит,
// один из объектов оказался лучше другого.
// Проверяем значение результирующего флага
// и возвращаем доминирующий объект.
if (resultFlag) {
return i1;
} else {
return i2;
}
}
}
}
private List<Double> weights;
public Boss () {
weights = new ArrayList<Double> ();
{
weights. add (0.45);
weights. add (0.45);
weights. add (0.04);
weights. add (0.04);
weights. add (0.02);
}
}
/**
* Получить полезность объекта.
* @param i Объект.
* @return Оценка объекта.
*/
public double getUtility (Item i) {
double ratesSum = i. rate1 * weights. get (0) +
i. rate2 * weights. get (1) +
i. rate3 * weights. get (2) +
i. rate4 * weights. get (3) +
i. rate5 * weights. get (4);
return ratesSum / i. weight / i. volume; // ( (i. weight + i. volume) / 2);
}
/**
* Отобразить пару объектов в один объект.
* @param i Любой объект из пары.
* @return Результирующий объект.
*/
public static Item mapPair (Item i) {
Item first = i;
Item second = i. getPair ();
Item resultItem = new Item (first. id + ": " + second. id,
first. volume + second. volume,
first. weight + second. weight,
first. rate1 + second. rate1,first. rate2 + second. rate2,first. rate3 + second. rate3,first. rate4 + second. rate4,first. rate5 + second. rate5);
return resultItem;
}
/**
* Получить бинарное отношение, определённое ЛПР.
* @return Бинарное отношение.
*/
public BinaryRelation<Item> getBinaryRelation () {
return new BossBinaryRelation ();
}
}
Класс "Склад". Его поля - список упаковываемых объектов, список контейнеров, сформированные слои Парето (при создании объекта это поле равно null), карта упакованных объектов и остаток, представляющий из себя список объектов. Также есть поле типа java. math. Random, использующееся при инициализации упаковываемых объектов и контейнеров.
/**
* Склад.
* @author AtemB
*
*/
public class Store {
class MapKeysComparator implements Comparator<Container> {
@Override
public int compare (Container c1, Container c2) {
return c1. getId () - c2. getId ();
}
}
private List<Item> items;
private List<Container> containers;
private Random r = new Random ();
private List<List<Item>> paretoSet;
private SortedMap<Container, List<Item>> map;
private List<Item> rest;
public Store () {
containers = new ArrayList<Container> ();
items = new ArrayList<Item> ();
rest = new ArrayList<Item> ();
map = new TreeMap<Container, List<Item>> (new MapKeysComparator ());
}
public void createContainers (int containersNum, ContainerTemplate ct, int maxVolume, int maxCargo) {
Random r = new Random ();
int volumeDiapasonLength = maxVolume - ct. getVolume (). getBegin ();
int cargoDiapasonLength = maxCargo - ct. getCargo (). getBegin ();
for (int i = 0; i < containersNum; i++) {
containers. add (new Container (i,
r. nextInt (volumeDiapasonLength + 1) + ct. getVolume (). getBegin (),
r. nextInt (cargoDiapasonLength + 1) + ct. getCargo (). getBegin ()));
}
for (Container c: containers) {
map. put (c, new LinkedList<Item> ());
}
}
public void createItems (int itemsNum, ItemTemplate it, int maxVolume, int maxWeight) {
int volumeDiapasonLength = maxVolume - it. getVolume (). getBegin ();
int weightDiapasonLength = maxWeight - it. getWeight (). getBegin ();
int r1DiapasonLength = it. getRate1 (). getEnd () - it. getRate1 (). getBegin ();
int r2DiapasonLength = it. getRate2 (). getEnd () - it. getRate2 (). getBegin ();
int r3DiapasonLength = it. getRate3 (). getEnd () - it. getRate3 (). getBegin ();
int r4DiapasonLength = it. getRate4 (). getEnd () - it. getRate4 (). getBegin ();
int r5DiapasonLength = it. getRate5 (). getEnd () - it. getRate5 (). getBegin ();
for (int i = 0; i < itemsNum; i++) {
items. add (new Item (i + "", r. nextInt (volumeDiapasonLength + 1) + it. getVolume (). getBegin (),
r. nextInt (weightDiapasonLength + 1) + it. getWeight (). getBegin (),
r. nextInt (r1DiapasonLength + 1) + it. getRate1 (). getBegin (),
r. nextInt (r2DiapasonLength + 1) + it. getRate2 (). getBegin (),
r. nextInt (r3DiapasonLength + 1) + it. getRate3 (). getBegin (),
r. nextInt (r4DiapasonLength + 1) + it. getRate4 (). getBegin (),
r. nextInt (r5DiapasonLength + 1) + it. getRate5 (). getBegin ()));
}
}
/**
* @return the containers
*/
public List<Container> getContainers () {
return containers;
}
/**
* @return the items
*/
public List<Item> getItemsClones () {
List<SimpleEntry<String, String>> itemPairs = new ArrayList<SimpleEntry<String, String>> ();
List<Item> newItems = new ArrayList<Item> ();
for (Item i: items) {
newItems. add (i. clone ());
if (i. hasPair ()) {
itemPairs. add (new SimpleEntry<String, String> (i. getId (), i. getPair (). getId ()));
}
}
for (Entry<String, String> e: itemPairs) {
getItemFromListByID (e. getKey (), newItems). setPair (getItemFromListByID (e. getValue (), newItems));
}
return newItems;
}
public List<Item> getItemsInstance () {
return items;
}
public void setEmpty () {
items. clear ();
containers. clear ();
}
/**
* @return the paretoSet
*/
public List<List<Item>> getParetoSetInstance () {
return paretoSet;
}
/**
* @return the paretoSet
*/
public List<List<Item>> getParetoSetClone () {
List<List<Item>> clone = new ArrayList<List<Item>> ();
List<SimpleEntry<String, String>> itemPairs = new ArrayList<SimpleEntry<String, String>> ();
for (List<Item> paretoLayer: paretoSet) {
List<Item> newParetoLayer = new ArrayList<Item> ();
for (Item i: paretoLayer) {
newParetoLayer. add (i. clone ());
if (i. hasPair ()) {
itemPairs. add (new SimpleEntry<String, String> (i. getId (), i. getPair (). getId ()));
}
}
clone. add (newParetoLayer);
}
for (Entry<String, String> e: itemPairs) {
getItemFromParetoSetByID (e. getKey (), clone). setPair (getItemFromParetoSetByID (e. getValue (), clone));
}
return clone;
}
/**
* @param paretoSet the paretoSet to set
*/
public void setParetoSet (List<List<Item>> paretoSet) {
this. paretoSet = paretoSet;
}
private Item getItemFromListByID (String id, List<Item> items) {
for (Item i: items) {
if (i. getId (). equals (id)) {
return i;
}
}
return null;
}
private Item getItemFromParetoSetByID (String id, List<List<Item>> paretoSet) {
for (List<Item> items: paretoSet) {
for (Item i: items) {
if (i. getId (). equals (id)) {
return i;
}
}
}
return null;
}
/**
* @return the map
*/
public SortedMap<Container, List<Item>> getMapInstance () {
return map;
}
/**
* @return the map
*/
public SortedMap<Container, List<Item>> getMapClone () {
SortedMap<Container, List<Item>> clone = new TreeMap<Container, List<Item>> (new MapKeysComparator ());
Set<Entry<Container, List<Item>>> set = map. entrySet ();
for (Entry<Container, List<Item>> e: set) {
List<Item> items = new ArrayList<Item> ();
for (Item i: e. getValue ()) {
items. add (i. clone ());
}
clone. put (e. getKey (). clone (), items);
}
return clone;
}
/**
* @param map the map to set
*/
public void setMap (SortedMap<Container, List<Item>> map) {
this. map = map;
}
public boolean paretoSetIsEmpty () {
boolean result = false;
return result;
}
/**
* @return the rest
*/
public List<Item> getRest () {
return rest;
}
/**
* @param rest the rest to set
*/
public void setRest (List<Item> rest) {
this. rest = rest;
}
}
Класс Упаковщик. Поля этого класса - ЛПР и Склад. Также в нём объявлены два перечисления, в которых указаны тип сортировки объектов и алгоритм упаковки. Этот класс оперирует с упаковываемыми объектами на основе информации ЛПР (обрабатывает парные объекты, создаёт слои Парето), сортирует указанным образом, и упаковывает объекты.
/**
* Упаковщик.
* @author AtemB
*
*/
public class Packer {
/**
* Алгоритм упаковки.
* @author AtemB
*
*/
public enum ALGORYTHM {
/** В первый подходящий. */
FIRST,
/** В первый подходящий с убыванием. */
FIRST_DECREASE,
/** В лучший из подходящих. */
BEST,
/** В лучший из подходящих с убыванием. */
BEST_DECREASE
}
/**
* Тип сортировки.
* @author AtemB
*
*/
public enum SORT_TYPE {
/** По весу. */
WEIGHT,
/** По объёму. */
VOLUME,
/** По полезности. */
UTILITY,
/** По величине. */
SIZE
}
private Store store;
private Boss boss;
public Packer (Store store, Boss boss) {
this. store = store;
this. boss = boss;
}
public void breakPair (Item i1, Item i2) {
i1. setPair (null);
i2. setPair (null);
}
public void createPair (Item i1, Item i2) {
i1. setPair (i2);
i2. setPair (i1);
}
/**
* Обработать парные объекты.
* @param items Исходное множество объектов.
* @return Результирующее множество объектов.
*/
public List<Item> processPairs (List<Item> items) {
List<Item> listForRemove = new ArrayList<Item> ();
// Отображаем все пары в монолитные объекты.
for (int i = 0; i < items. size (); i++) {
Item current = items. get (i);
if (current. hasPair ()) {
// Помещаем парный текущему объект в список на удаление,
// т.к. теперь его параметры будут отражены в результирующем объекте.
listForRemove. add (current. getPair ());
Item resultItem = Boss. mapPair (current);
// Замещаем исходный объект по текущему индексу результирующим.
items. set (i, resultItem);
current. getPair (). setPair (null);
}
}
// Удаляем парные объекты из списка.
for (Item i: listForRemove) {
items. remove (i);
}
return items;
}
/**
* Создать слой Парето.
* @param boss ЛПР.
* @param items Исходное множество.
* @return Слой парето.
*/
public List<Item> extractParetoLayer (List<Item> items) {
BinaryRelation<Item> relation = boss. getBinaryRelation ();
if (items. isEmpty ()) {
return null;
} else {
// Сначала извлекаем первый попавшийся недоминируемый объект на исходном множестве.
List<Item> bestItems = new ArrayList<Item> ();
Item best = items. get (0);
for (Item i: items) {
// Сравниваем текущий элемент с каждым из элементов последовательности.
// Если новый элемент лучше текущего - инициализируем им ссылку на лучший объект.
if (relation.compare (best, i) == i) {
best = i;
}
}
// Удаляем недоминируемый объект из исходного множества.
items. remove (best);
// Добавляем его в слой Парето.
bestItems. add (best);
// Теперь нужно найти все несравнимые с ним элементы исходного множества.
List<Item> equalItems = new ArrayList<Item> ();
for (Item i: items) {
// Если очередной элемент несравним с ранее полученным лучшим,
// добавляем его в результирующее множество.
if (relation.compare (best, i) == null) {
equalItems. add (i);
}
}
// Удаляем из исходного множества все ссылки на недоминируемые объекты.
for (Item i: equalItems) {
items. remove (i);
}
// Добавляем недоминируемые объекты в слой Парето.
for (Item i: equalItems) {
bestItems. add (i);
}
return bestItems;
}
}
/**
* Получить множества (слои) Парето.
* @param boss ЛПР.
* @param items Исходное множество.
* @return Слои Парето.
*/
public List<List<Item>> createParetoSet (List<Item> items) {
List<List<Item>> layers = new ArrayList<List<Item>> ();
while (! (items. isEmpty ())) {
List<Item> paretoLayer = extractParetoLayer (items);
layers. add (paretoLayer);
}
return layers;
}
/**
* Упаковать очередной слой Парето. Инкапсулирует логику алгоритма упаковки.
* @param map Карта, содержащая информацию о контейнерах и об упакованных объектах.
* @param paretoLayer Слой Парето.
* @return Ту же карту с очередным добавленным слоем.
*/
public SortedMap<Container, List<Item>> pack (SortedMap<Container, List<Item>> map, List<Item> paretoLayer, ALGORYTHM algorythm) {
// Получаем массу и объём слоя Парето.
double layerWeight = 0.0;
double layerVolume = 0.0;
for (Item i: paretoLayer) {
layerWeight += i. weight;
layerVolume += i. volume;
}
if (algorythm == ALGORYTHM. FIRST_DECREASE || algorythm == ALGORYTHM. BEST_DECREASE) {
sort (paretoLayer, SORT_TYPE. SIZE);
}
// Если он в полном составе не упаковывается, его нужно сортировать по эффективности.
if (layerWeight > getFreeCargo (map) ||
layerVolume > getFreeSpace (map)) {
sort (paretoLayer, Packer. SORT_TYPE. UTILITY);
}
List<Item> forRemove = new ArrayList<Item> ();
for (Item item: paretoLayer) {
if (! tryToPack (map, item, algorythm)) {
store. getRest (). add (item);
forRemove. add (item);
}
}
for (Item i: forRemove) {
paretoLayer. remove (i);
}
return map;
}
/**
* Попробовать паковать объект.
* @param map
* @param item Объект.
* @return Флаг удачного завершения операции.
*/
private boolean tryToPack (SortedMap<Container, List<Item>> map, Item item, ALGORYTHM algorythm) {
Set<Container> containers = map. keySet ();
if (algorythm == ALGORYTHM. BEST || algorythm == ALGORYTHM. BEST_DECREASE) {
Container bestContainer = getBest (containers, item, map);
if (bestContainer == null) {
return false;
} else {
map. get (bestContainer). add (item);
return true;
}
}
for (Container container: containers) {
if (canPack (container, item, map)) {
map. get (container). add (item);
return true;
}
}
return false;
}
/**
* Получить свободное место в контейнерах.
* @param map Карта, содержащая информацию о контейнерах и об упакованных объектах.
* @return Свободное место.
*/
private double getFreeSpace (SortedMap<Container, List<Item>> map) {
double freeSpace = 0.0;
for (Container c: map. keySet ()) {
double itemsVolume = 0.0;
for (Item i: map. get (c)) {
itemsVolume += i. volume;
}
freeSpace += (c. getVolume () - itemsVolume);
}
return freeSpace;
}
/**
* Получить оставшуюся грузоподъёмность контейнеров.
* @param map Карта, содержащая информацию о контейнерах и об упакованных объектах.
* @return Оставшуюся грузоподъёмность контейнеров.
*/
private double getFreeCargo (SortedMap<Container, List<Item>> map) {
double freeCargo = 0.0;
for (Container c: map. keySet ()) {
double itemsWeight = 0.0;
for (Item i: map. get (c)) {
itemsWeight += i. weight;
}
freeCargo += (c. getCargo () - itemsWeight);
}
return freeCargo;
}
/**
* Проверить возможность упаковки объекта в контейнер.
* @param c Контейнер.
* @param i Объект.
* @param map Карта, содержащая информацию об упакованных объектах.
* @return Флаг проверки.
*/
private boolean canPack (Container c, Item i, SortedMap<Container, List<Item>> map) {
// Получаем список объектов, упакованных в этот контейнер.
List<Item> items = map. get (c);
int totalVolume = 0;
double totalWeight = 0.0;
// Получаем суммарный вес и объём объектов, упакованных в этот контейнер.
for (Item item: items) {
totalVolume += item. volume;
totalWeight += item. weight;
}
// Если масса или объём проверяемого объекта
// больше оставшейся грузоподъёмности
// или свободного места в контейнере,
// объект в него упаковать нельзя.
if (c. getVolume () - totalVolume < i. volume ||
c. getCargo () - totalWeight < i. weight) {
return false;
}
return true;
}
/**
* Создать парные объекты на исходном множестве.
* @param pairsNum Необходимое количество пар.
* @param items Исходное множество.
*/
public void createPairs (int pairsNum, List<Item> items) {
Random r = new Random ();
int pairCounter = 0;
while (pairCounter < pairsNum) {
findPair (items. get (r. nextInt (items. size ())), items);
pairCounter = countPairs (items);
}
}
/**
* Найти парный объект.
* @param i Объект, для которого ищется парный объект.
* @param items Исходное множество.
*/
private void findPair (Item i, List<Item> items) {
if (! (i. hasPair ())) {
Random r = new Random ();
Item pair;
do {
pair = items. get (r. nextInt (items. size ()));
} while (pair. hasPair () || pair == i);
i. setPair (pair);
pair. setPair (i);
}
}
/**
* Сосчитать парные объекты.
* @param items Исходное множество.
* @return Количество пар.
*/
public int countPairs (List<Item> items) {
int pairsCounter = 0;
for (Item i: items) {
if (i. hasPair ()) {
pairsCounter++;
}
}
return pairsCounter / 2;
}
/**
* Извлечь наиболее тяжёлый объект. <p>
* Полученный объект удаляется из списка.
* @param items Список объектов.
* @return Самый тяжёлый объект.
*/
public Item extractHardest (List<Item> items) {
Item hardest = items. get (0);
for (Item i: items) {
if (i. weight > hardest. weight) {
hardest = i;
}
}
items. remove (hardest);
return hardest;
}
/**
* Извлечь наиболее объёмный объект. <p>
* Полученный объект удаляется из списка.
* @param items Список объектов.
* @return Самый объёмный объект.
*/
public Item extractLargest (List<Item> items) {
Item largest = items. get (0);
for (Item i: items) {
if (i. volume > largest. volume) {
largest = i;
}
}
items. remove (largest);
return largest;
}
public void sort (List<Item> items, SORT_TYPE. template) {
int itemsSize = items. size ();
int templateLength = template. length;
for (int i = 0; i < itemsSize; i++) {
SORT_TYPE type = template [i % templateLength];
for (int j = i; j < itemsSize; j++) {
for (int k = i; k < itemsSize; k++) {
switch (type) {
case VOLUME:
if (items. get (j). volume < items. get (k). volume) {
Item buffer = items. get (j);
items. set (j, items. get (k));
items. set (k, buffer);
}
break;
case WEIGHT:
if (items. get (j). weight < items. get (k). weight) {
Item buffer = items. get (j);
items. set (j, items. get (k));
items. set (k, buffer);
}
break;
case UTILITY:
if (boss. getUtility (items. get (j)) < boss. getUtility (items. get (k))) {
Item buffer = items. get (j);
items. set (j, items. get (k));
items. set (k, buffer);
}
break;
case SIZE:
if (countSize (items. get (j)) > countSize (items. get (k))) {
Item buffer = items. get (j);
items. set (j, items. get (k));
items. set (k, buffer);
}
break;
default:
break;
}
}
}
}
}
/**
* Рассчитать размер. Расчёт производится по массе и объёму.
* @param i Объект.
*/
private double countSize (Item i) {
return i. volume * i. weight;
}
/**
* Получить лучший контейнер из подходящих. <p>
* Лучшим контейнер с минимальным свободным местом (грузоподъёмность или объём) под упаковку объекта.
* @param containers Контейнеры.
* @param i Объект.
* @param map Карта упаковки.
* @return Лучший контейнер.
*/
private Container getBest (Collection<Container> containers, Item i, SortedMap<Container, List<Item>> map) {
return getValid (getValidContainers (containers, i, map), i, map);
}
/**
* Получить контейнеры, пригодные для упаковки объекта.
* @param containers Контейнеры.
* @param i Объект.
* @param map Карта упаковки.
* @return Список контейнеров, в которые можно упаковать объект.
*/
private List<Container> getValidContainers (Collection<Container> containers, Item i, SortedMap<Container, List<Item>> map) {
List<Container> validContainers = new ArrayList<Container> ();
for (Container c: containers) {
if (canPack (c, i, map)) {
validContainers. add (c);
}
}
return validContainers;
}
/**
* Получить контейнер, в котором осталось наименьшее количество места для упаковки объекта.
* @param containers Контейнеры.
* @param i Объект.
* @param map Карта упаковки.
* @return Контейнер.
*/
private Container getValid (List<Container> containers, Item i, SortedMap<Container, List<Item>> map) {
double minimalRests = 0;
for (Container c: containers) {
double rests = getRests (c, i, map);
if (rests > minimalRests) {
minimalRests += rests;
}
}
for (Container c: containers) {
double rests = getRests (c, i, map);
if (rests == 0) {
return c;
}
if (rests < minimalRests) {
minimalRests = rests;
}
}
for (Container c: containers) {
if (getRests (c, i, map) == minimalRests) {
return c;
}
}
return null;
}
/**
* Получить остаток. <p>
* Остатком считается наименьшее значение из остатка по грузоподъёмности или остатка по объёму.
* @param c Контейнер.
* @param i Объект.
* @param map Карта упаковки.
* @return Остаток.
*/
private double getRests (Container c, Item i, SortedMap<Container, List<Item>> map) {
double totalVolume = 0;
double totalWeight = 0;
for (Item item: map. get (c)) {
totalVolume += item. volume;
totalWeight += item. weight;
}
double volumeRests = c. getVolume () - totalVolume;
double cargoRests = c. getCargo () - totalWeight;
if (volumeRests < cargoRests) {
return volumeRests;
} else if (cargoRests < volumeRests) {
return cargoRests;
}
return 0;
}
}
Также в программе присутствуют классы графического интерфейса и отдельный класс, содержащий метод main ().
Полный исходный код программы.
Исходный код программы на Java.
Пакет core.
BinaryRelation. java
package core;
/**
* Бинарное отношение.
* @author AtemB
*
* @param <T> Тип элементов множества.
*/
public interface BinaryRelation<T> {
/**
* Сравнить два элемента множества. Этот метод инкапсулирует логику бинарного отношения.
* @param t1 Первый элемент.
* @param t2 Второй элемент.
* @return Доминирующий элемент или null, если элементы несравнимы.
*/
public T compare (T t1, T t2);
}
Boss. java
package core;
import java. util. ArrayList;
import java. util. LinkedList;
import java. util. List;
import java. util. Map;
/**
* ЛПР (лицо, принимающее решения).
* @author AtemB
*
*/
public class Boss {
class BossBinaryRelation implements BinaryRelation<Item> {
@Override
public Item compare (Item i1, Item i2) {
// Конечно, не самая пряморукая реализация, зато относительно понятна для восприятия.
// В этот список заносятся разности оценок по критериям.
List<Double> rates = new LinkedList<Double> ();
rates. add ( (double) (i1. rate1 - i2. rate1));
rates. add ( (double) (i1. rate2 - i2. rate2));
// Флаги в этом списке означают, положителен или отрицателен
// результат сравнения критериев.
// Одинаковые значения в список не заносятся.
List<Boolean> flags = new LinkedList<Boolean> ();
for (Double d: rates) {
if (d. doubleValue () > 0) {
flags. add (true);
} else if (d. doubleValue () < 0) {
flags. add (false);
}
}
// Если спиок флагов пуст, значит, объекты по проверяемым критериям равны.
if (flags. isEmpty ()) {
return null;
} else {
boolean resultFlag = false;
for (int i = 1; i < flags. size (); i++) {
resultFlag = flags. get (i);
// Если в списке встречаются разные значения флагов, значит,
// объекты несравнимы по значимым критериям
// (один лучше по одним критериям, другой по другим).
if (flags. get (i - 1)! = flags. get (i)) {
return null;
}
}
// Если предыдущий цикл выполнился до конца, значит,
// один из объектов оказался лучше другого.
// Проверяем значение результирующего флага
// и возвращаем доминирующий объект.
if (resultFlag) {
return i1;
} else {
return i2;
}
}
}
}
private List<Double> weights;
public Boss () {
weights = new ArrayList<Double> ();
{
weights. add (0.45);
weights. add (0.45);
weights. add (0.04);
weights. add (0.04);
weights. add (0.02);
}
}
/**
* Получить полезность объекта.
* @param i Объект.
* @return Оценка объекта.
*/
public double getUtility (Item i) {
double ratesSum = i. rate1 * weights. get (0) +
i. rate2 * weights. get (1) +
i. rate3 * weights. get (2) +
i. rate4 * weights. get (3) +
i. rate5 * weights. get (4);
return ratesSum / i. weight / i. volume;
}
private double getCriterialUtility (Item i) {
return i. rate1 * weights. get (0) +
i. rate2 * weights. get (1) +
i. rate3 * weights. get (2) +
i. rate4 * weights. get (3) +
i. rate5 * weights. get (4);
}
/**
* Отобразить пару объектов в один объект.
* @param i Любой объект из пары.
* @return Результирующий объект.
*/
public static Item mapPair (Item i) {
Item first = i;
Item second = i. getPair ();
Item resultItem = new Item (first. id + ": " + second. id,
first. volume + second. volume,
first. weight + second. weight,
first. rate1 + second. rate1,first. rate2 + second. rate2,first. rate3 + second. rate3,first. rate4 + second. rate4,first. rate5 + second. rate5);
return resultItem;
}
/**
* Получить бинарное отношение, определённое ЛПР.
* @return Бинарное отношение.
*/
public BinaryRelation<Item> getBinaryRelation () {
return new BossBinaryRelation ();
}
public double getPackUtility (Map<Container, List<Item>> map) {
double utility = 0;
for (Container c: map. keySet ()) {
for (Item i: map. get (c)) {
utility += getCriterialUtility (i);
}
}
return utility;
}
}
Container. java
package core;
/**
* Контейнер.
* @author AtemB
*
*/
public class Container {
/** ID. */
private int id;
/** Объём. */
private int volume;
/** Грузоподъёмность. */
private int cargo;
public Container (int id, int volume, int cargo) {
this. id = id;
this. volume = volume;
this. cargo = cargo;
}
public int getVolume () {
return volume;
}
public int getCargo () {
return cargo;
}
public int getId () {
return id;
}
/**
* @param volume the volume to set
*/
public void setVolume (int volume) {
this. volume = volume;
}
/**
* @param cargo the cargo to set
*/
public void setCargo (int cargo) {
this. cargo = cargo;
}
/**
* @param id the id to set
*/
public void setId (int id) {
this. id = id;
}
@Override
public Container clone () {
Container clone = new Container (id, volume, cargo);
return clone;
}
/* (non-Javadoc)
* @see java. lang. Object#toString ()
*/
@Override
public String toString () {
return "Контейнер" +
",\nID: " + id +
"\nОбъём: " + volume +
",\nГрузоподъёмность: " + cargo;
}
}
Item. java
package core;
/**
* Упаковываемый объект.
* @author AtemB
*
*/
public class Item {
/** ID. */
String id;
/** Объём. */
int volume;
/** Вес. */
int weight;
/** Критерий 1. */
int rate1;
/** Критерий 2. */
int rate2;
/** Критерий 3. */
int rate3;
/** Критерий 4. */
int rate4;
/** Критерий 5. */
int rate5;
/** Ссылка на парный объект. */
private Item pair;
public Item (String id,
int volume,
int weight,
int rate1,int rate2,int rate3,int rate4,int rate5) {
super ();
this. id = id;
this. volume = volume;
this. weight = weight;
this. rate1 = rate1;
this. rate2 = rate2;
this. rate3 = rate3;
this. rate4 = rate4;
this. rate5 = rate5;
}
/***/
public Item () {
this. id = 0 + "";
this. volume = 0;
this. weight = 0;
this. rate1 = 0;
this. rate2 = 0;
this. rate3 = 0;
this. rate4 = 0;
this. rate5 = 0;
}
public String getId () {
return id;
}
public Item getPair () {
return pair;
}
public void setPair (Item pair) {
this. pair = pair;
}
public boolean hasPair () {
return pair! = null;
}
/**
* @return the volume
*/
public int getVolume () {
return volume;
}
/**
* @return the weight
*/
public int getWeight () {
return weight;
}
/**
* @return the rate1
*/
public int getRate1 () {
return rate1;
}
/**
* @return the rate2
*/
public int getRate2 () {
return rate2;
}
/**
* @return the rate3
*/
public int getRate3 () {
return rate3;
}
/**
* @return the rate4
*/
public int getRate4 () {
return rate4;
}
/**
* @return the rate5
*/
public int getRate5 () {
return rate5;
}
/**
* @param volume the volume to set
*/
public void setVolume (int volume) {
this. volume = volume;
}
/**
* @param weight the weight to set
*/
public void setWeight (int weight) {
this. weight = weight;
}
/**
* @param rate1 the rate1 to set
*/
public void setRate1 (int rate1) {
this. rate1 = rate1;
}
/**
* @param rate2 the rate2 to set
*/
public void setRate2 (int rate2) {
this. rate2 = rate2;
}
/**
* @param rate3 the rate3 to set
*/
public void setRate3 (int rate3) {
this. rate3 = rate3;
}
/**
* @param rate4 the rate4 to set
*/
public void setRate4 (int rate4) {
this. rate4 = rate4;
}
/**
* @param rate5 the rate5 to set
*/
public void setRate5 (int rate5) {
this. rate5 = rate5;
}
/* (non-Javadoc)
* @see java. lang. Object#equals (java. lang. Object)
*/
@Override
public boolean equals (Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (! (obj instanceof Item)) {
return false;
}
Item other = (Item) obj;
if (rate1! = other. rate1) {
return false;
}
if (rate2! = other. rate2) {
return false;
}
if (rate3! = other. rate3) {
return false;
}
if (rate4! = other. rate4) {
return false;
}
if (rate5! = other. rate5) {
return false;
}
if (volume! = other. volume) {
return false;
}
if (Double. doubleToLongBits (weight)! = Double
. doubleToLongBits (other. weight)) {
return false;
}
return true;
}
@Override
public Item clone () {
Item clone = new Item (id, volume, weight, rate1, rate2, rate3, rate4, rate5);
return clone;
}
/* (non-Javadoc)
* @see java. lang. Object#toString ()
*/
@Override
public String toString () {
return "Объект" +
"\nID: " + id + ",\nОбъём: " + volume + ",\nВес: " + weight
+ ",\nКр.1: " + rate1 + ",\nКр.2: " + rate2 + ",\nКр.3: " + rate3
+ ",\nКр.4: " + rate4 + ",\nКр.5" + rate5 + ",\nID парного объекта: " + pair. id;
}
}
Packer. java
package core;
import java. util. ArrayList;
import java. util. Collection;
import java. util. List;
import java. util. Random;
import java. util. Set;
import java. util. SortedMap;
/**
* Упаковщик.
* @author AtemB
*
*/
public class Packer {
/**
* Алгоритм упаковки.
* @author AtemB
*
*/
public enum ALGORYTHM {
/** В первый подходящий. */
FIRST,
// /** В первый подходящий с убыванием. */
// FIRST_DECREASE,
/** В лучший из подходящих. */
BEST,
// /** В лучший из подходящих с убыванием. */
// BEST_DECREASE
}
/**
* Тип сортировки.
* @author AtemB
*
*/
public enum SORT_TYPE {
/** По весу. */
WEIGHT,
/** По объёму. */
VOLUME,
/** По полезности. */
UTILITY,
/** По величине. */
SIZE
}
private Store store;
private Boss boss;
public Packer (Store store, Boss boss) {
this. store = store;
this. boss = boss;
}
public void breakPair (Item i1, Item i2) {
i1. setPair (null);
i2. setPair (null);
}
public void createPair (Item i1, Item i2) {
i1. setPair (i2);
i2. setPair (i1);
}
/**
* Обработать парные объекты.
* @param items Исходное множество объектов.
* @return Результирующее множество объектов.
*/
public List<Item> processPairs (List<Item> items) {
List<Item> listForRemove = new ArrayList<Item> ();
// Отображаем все пары в монолитные объекты.
for (int i = 0; i < items. size (); i++) {
Item current = items. get (i);
if (current. hasPair ()) {
// Помещаем парный текущему объект в список на удаление,
// т.к. теперь его параметры будут отражены в результирующем объекте.
listForRemove. add (current. getPair ());
Item resultItem = Boss. mapPair (current);
// Замещаем исходный объект по текущему индексу результирующим.
items. set (i, resultItem);
current. getPair (). setPair (null);
}
}
// Удаляем парные объекты из списка.
for (Item i: listForRemove) {
items. remove (i);
}
return items;
}
/**
* Создать слой Парето.
* @param boss ЛПР.
* @param items Исходное множество.
* @return Слой парето.
*/
public List<Item> extractParetoLayer (List<Item> items) {
BinaryRelation<Item> relation = boss. getBinaryRelation ();
if (items. isEmpty ()) {
return null;
} else {
// Сначала извлекаем первый попавшийся недоминируемый объект на исходном множестве.
List<Item> bestItems = new ArrayList<Item> ();
Item best = items. get (0);
for (Item i: items) {
// Сравниваем текущий элемент с каждым из элементов последовательности.
// Если новый элемент лучше текущего - инициализируем им ссылку на лучший объект.
if (relation.compare (best, i) == i) {
best = i;
}
}
// Удаляем недоминируемый объект из исходного множества.
items. remove (best);
// Добавляем его в слой Парето.
bestItems. add (best);
// Теперь нужно найти все несравнимые с ним элементы исходного множества.
List<Item> equalItems = new ArrayList<Item> ();
for (Item i: items) {
// Если очередной элемент несравним с ранее полученным лучшим,
// добавляем его в результирующее множество.
if (relation.compare (best, i) == null) {
equalItems. add (i);
}
}
// Удаляем из исходного множества все ссылки на недоминируемые объекты.
for (Item i: equalItems) {
items. remove (i);
}
// Добавляем недоминируемые объекты в слой Парето.
for (Item i: equalItems) {
bestItems. add (i);
}
return bestItems;
}
}
/**
* Получить множества (слои) Парето.
* @param boss ЛПР.
* @param items Исходное множество.
* @return Слои Парето.
*/
public List<List<Item>> createParetoSet (List<Item> items) {
List<List<Item>> layers = new ArrayList<List<Item>> ();
while (! (items. isEmpty ())) {
List<Item> paretoLayer = extractParetoLayer (items);
layers. add (paretoLayer);
}
return layers;
}
/**
* Упаковать очередной слой Парето. Инкапсулирует логику алгоритма упаковки.
* @param map Карта, содержащая информацию о контейнерах и об упакованных объектах.
* @param paretoLayer Слой Парето.
* @return Ту же карту с очередным добавленным слоем.
*/
public SortedMap<Container, List<Item>> pack (SortedMap<Container, List<Item>> map, List<Item> paretoLayer, ALGORYTHM algorythm) {
// Получаем массу и объём слоя Парето.
double layerWeight = 0.0;
double layerVolume = 0.0;
for (Item i: paretoLayer) {
layerWeight += i. weight;
layerVolume += i. volume;
}
// if (algorythm == ALGORYTHM. FIRST_DECREASE || algorythm == ALGORYTHM. BEST_DECREASE) {
// sort (paretoLayer, SORT_TYPE. SIZE);
// }
// Если он в полном составе не упаковывается, его нужно сортировать по эффективности.
if (layerWeight > getFreeCargo (map) ||
layerVolume > getFreeSpace (map)) {
sort (paretoLayer, Packer. SORT_TYPE. UTILITY);
}
List<Item> forRemove = new ArrayList<Item> ();
for (Item item: paretoLayer) {
if (! tryToPack (map, item, algorythm)) {
store. getRest (). add (item);
forRemove. add (item);
}
}
for (Item i: forRemove) {
paretoLayer. remove (i);
}
return map;
}
/**
* Попробовать паковать объект.
* @param map
* @param item Объект.
* @return Флаг удачного завершения операции.
*/
private boolean tryToPack (SortedMap<Container, List<Item>> map, Item item, ALGORYTHM algorythm) {
Set<Container> containers = map. keySet ();
if (algorythm == ALGORYTHM. BEST/* || algorythm == ALGORYTHM. BEST_DECREASE*/) {
Container bestContainer = getBest (containers, item, map);
if (bestContainer == null) {
return false;
} else {
map. get (bestContainer). add (item);
return true;
}
} else if (algorythm == ALGORYTHM. FIRST) {
for (Container container: containers) {
if (canPack (container, item, map)) {
map. get (container). add (item);
return true;
}
}
}
return false;
}
/**
* Получить свободное место в контейнерах.
* @param map Карта, содержащая информацию о контейнерах и об упакованных объектах.
* @return Свободное место.
*/
private double getFreeSpace (SortedMap<Container, List<Item>> map) {
double freeSpace = 0.0;
for (Container c: map. keySet ()) {
double itemsVolume = 0.0;
for (Item i: map. get (c)) {
itemsVolume += i. volume;
}
freeSpace += (c. getVolume () - itemsVolume);
}
return freeSpace;
}
/**
* Получить оставшуюся грузоподъёмность контейнеров.
* @param map Карта, содержащая информацию о контейнерах и об упакованных объектах.
* @return Оставшуюся грузоподъёмность контейнеров.
Подобные документы
Понятия, связанные с принятием решений в различных условиях. Примеры принятия решений в условиях определенности, риска и неопределенности. Модели и методы принятия решений. Страховой, валютный, кредитный риск. Интуитивное и рациональное решение.
реферат [90,4 K], добавлен 16.01.2011Назначение и краткая характеристика систем поддержки принятия решений. Концепции и принципы теории принятия решений. Получение информации, критерии принятия решений и их шкалы. Схема классификации возможных источников и способов получения информации.
курсовая работа [132,5 K], добавлен 14.02.2011Выбор планшетного ПК. Методы решения задач принятия решений в условиях неопределенности. Разработка математического обеспечения поддержки принятия решений на основе реализации стандартных и модифицированных алгоритмов теории исследования операций.
курсовая работа [5,9 M], добавлен 22.01.2016Оценка и выбор многокритериальных решений в условиях определенности и ранжирование исходного множества альтернатив (без учета выполнения ограничений). Принятие решений в условиях риска и неопределенности. Вычисление минимаксного критерия Севиджа.
курсовая работа [128,2 K], добавлен 22.01.2015Основные методы принятия решений. Применение активизирующих методов принятия решений в компании на примере "Менсей". Методы мозгового штурма, конференции идей, вопросов и ответов. Процесс разработки и принятия управленческих решений и их эффективность.
курсовая работа [2,0 M], добавлен 24.12.2014Понятие и сущность управленческих решений и их классификация. Основные понятия теории принятия решений. Применение методов принятия решений в условиях неопределенности. Выявление и диагностика проблем, возникающих в организации при изменении условий.
курсовая работа [105,4 K], добавлен 01.04.2014Подход к управлению как к науке и искусству. Общие сведения о теории принятия решений. Постулаты теории принятия оптимального решения. Классы утверждений психологической теории решений. Методы психологических исследований процессов принятия решений.
реферат [26,2 K], добавлен 07.12.2010Исследование роли управленческих решений, их классификация. Модели и этапы принятия управленческих решений. Особенности разделения труда в процессе принятия решений. Оценка среды принятия решений и рисков, методы прогнозирования для принятия решений.
курсовая работа [233,1 K], добавлен 15.05.2019Процесс подготовки и принятия управленческого решения. Методы принятия решений, направленных на достижение намеченных целей. Принятие управленческих решений в сложных кризисных условиях. Реализация альтернатив в условиях риска и неопределенности.
курсовая работа [123,6 K], добавлен 30.03.2015Анализ и принятие управленческих решений в условиях определенности, в условиях риска, в условиях неопределенности. Общие модели и методы принятия решений в условиях определенности, неопределенности и риска. Эффективность работы персонала.
реферат [34,0 K], добавлен 15.12.2006