- •Санкт-петербургский государственный политехнический университет
- •Введение Основные понятия теории принятия решений
- •Формализация задач принятия решений
- •Методы оценки многокритериальных альтернатив
- •Прямые методы
- •Аксиоматические методы
- •Методы компенсации
- •Точки и кривые безразличия
- •Методы сравнения разностей оценок альтернатив
- •Методы порогов несравнимости
- •Человеко-машинные процедуры принятия решений
- •Постановка задачи об упаковке.
- •Функция полезности.
- •Слои Парето.
- •Программа.
- •Структура.
- •Пример решения задачи.
- •Заключение
- •Список использованных источников
- •Приложение 1
- •Классы предметной области.
- •Полный исходный код программы.
Полный исходный код программы.
Исходный код программы на 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 Оставшуюся грузоподъёмность контейнеров.
*/
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;
}
}
Store.java
package core;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import util.ContainerTemplate;
import util.ItemTemplate;
/**
* Склад.
* @author AtemB
*
*/
public class Store {
/**
* Сортировщик по ключам карты упаковки.
* @author AtemB
*
*/
class MapKeysComparator implements Comparator<Container> {
private List<Integer> template;
public MapKeysComparator(int index) {
this.template = templates.get(index);
}
@Override
public int compare(Container c1, Container c2) {
return template.indexOf(c1.getId()) - template.indexOf(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;
private int[] containersSequence;
private List<List<Integer>> templates;
public Store() {
containers = new ArrayList<Container>();
items = new ArrayList<Item>();
rest = new ArrayList<Item>();
}
/**
* Создать контейнеры.
* @param containersNum Число контейнеров.
* @param ct Шаблон контейнера.
* @param maxVolume Ограничение по объёму.
* @param maxCargo Ограничение по грузоподъёмности.
*/
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 + 1,
r.nextInt(volumeDiapasonLength + 1) + ct.getVolume().getBegin(),
r.nextInt(cargoDiapasonLength + 1) + ct.getCargo().getBegin()));
}
this.containersSequence = new int[containersNum];
for (int i = 0; i < containersNum; i++) {
containersSequence[i] = containers.get(i).getId();
}
templates = new LinkedList<List<Integer>>();
permutations(templates, containersSequence, containersNum);
map = new TreeMap<Container, List<Item>>(new MapKeysComparator(0));
for (Container c: containers) {
map.put(c, new LinkedList<Item>());
}
}
/**
* Создать упаковываемые объекты.
* @param itemsNum Число объектов.
* @param it Шабло объекта.
* @param maxVolume Ограничение по объёму.
* @param maxWeight Ограничение по массе.
*/
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 + 1) + "", 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(int index) {
SortedMap<Container, List<Item>> clone = new TreeMap<Container, List<Item>>(new MapKeysComparator(index));
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;
}
private void swap(int[] array, int index1, int index2) {
int temp=array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
private void addSequence(List<List<Integer>> sequence, int[] array) {
List<Integer> subSequence = new ArrayList<Integer>();
for(int i = 0; i < array.length; i++) {
subSequence.add(new Integer(array[i]));
}
sequence.add(subSequence);
}
/**
*
* @param array - массив
* @param n - число переставляемых элементов
*/
private void permutations(List<List<Integer>> sequence, int[] array,int n) {
// Если нечего переставлять
if(n==1) {
addSequence(sequence, array);
} else {
for(int i=0;i<n;i++) {
swap(array, i,n-1); //меняем последний элемент с каждым,
//в том числе и с самим собой.
permutations(sequence, array,n-1); //запускаем функцию, для n-1 элементов
swap(array, i,n-1); //поигрались - и хватит. Надо вернуть массив в прежнее
//состояние для следующего обмена элементов
}
}
}
/**
* @return the templates
*/
public List<List<Integer>> getTemplates() {
return templates;
}
}
Пакет util.
ContainerTemplate.java
package util;
public class ContainerTemplate {
private IntegerDiapason volume;
private IntegerDiapason cargo;
public ContainerTemplate(IntegerDiapason volume, IntegerDiapason cargo) {
super();
this.volume = volume;
this.cargo = cargo;
}
/**
* @return the volume
*/
public IntegerDiapason getVolume() {
return volume;
}
/**
* @return the cargo
*/
public IntegerDiapason getCargo() {
return cargo;
}
}
IntegerDiapason.java
package util;
public class IntegerDiapason {
private int begin;
private int end;
public IntegerDiapason(int begin, int end) {
super();
this.begin = begin;
this.end = end;
}
/**
* @return the begin
*/
public int getBegin() {
return begin;
}
/**
* @return the end
*/
public int getEnd() {
return end;
}
}
ItemTemplate.java
package util;
public class ItemTemplate {
private IntegerDiapason weight;
private IntegerDiapason volume;
private IntegerDiapason rate1;
private IntegerDiapason rate2;
private IntegerDiapason rate3;
private IntegerDiapason rate4;
private IntegerDiapason rate5;
public ItemTemplate(IntegerDiapason weight, IntegerDiapason volume,
IntegerDiapason rate1, IntegerDiapason rate2,
IntegerDiapason rate3, IntegerDiapason rate4, IntegerDiapason rate5) {
super();
this.weight = weight;
this.volume = volume;
this.rate1 = rate1;
this.rate2 = rate2;
this.rate3 = rate3;
this.rate4 = rate4;
this.rate5 = rate5;
}
/**
* @return the weight
*/
public IntegerDiapason getWeight() {
return weight;
}
/**
* @return the volume
*/
public IntegerDiapason getVolume() {
return volume;
}
/**
* @return the rate1
*/
public IntegerDiapason getRate1() {
return rate1;
}
/**
* @return the rate2
*/
public IntegerDiapason getRate2() {
return rate2;
}
/**
* @return the rate3
*/
public IntegerDiapason getRate3() {
return rate3;
}
/**
* @return the rate4
*/
public IntegerDiapason getRate4() {
return rate4;
}
/**
* @return the rate5
*/
public IntegerDiapason getRate5() {
return rate5;
}
}
Пакет gui.
GUI.java
package gui;
import javax.swing.JFrame;
import javax.swing.JTabbedPane;
import util.ContainerTemplate;
import util.ItemTemplate;
import core.Boss;
import core.Packer;
import core.Store;
/**
* Графический интерфейс.
* @author AtemB
*
*/
public class GUI {
private JFrame mainFrame;
private ObjectCreatorViewer oViewer;
private ParetoLayersViewer pViewer;
private ItemsViewer iViewer;
private ResultViewer rViewer;
private Store store;
public GUI(Store store, Packer packer, Boss boss, ContainerTemplate ct, ItemTemplate it) {
this.store = store;
JTabbedPane tabbedPane = new JTabbedPane();
oViewer = new ObjectCreatorViewer(this, this.store, ct, it, 40, 8);
iViewer = new ItemsViewer(store.getContainers(), store.getItemsInstance(), packer, boss);
pViewer = new ParetoLayersViewer(this, store, packer);
rViewer = new ResultViewer(this, store, packer, boss);
this.mainFrame = new JFrame("Упаковка объектов");
tabbedPane.addTab("Задание исходных данных", oViewer.getViewer());
tabbedPane.addTab("Объекты и контейнеры", iViewer.getViewer());
tabbedPane.addTab("Слои Парето", pViewer.getViewer());
tabbedPane.addTab("Результаты упаковки", rViewer.getViewer());
this.mainFrame.setSize(1000, 550);
this.mainFrame.add(tabbedPane);
this.mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.mainFrame.setVisible(true);
}
public void refreshItemsViewer() {
iViewer.refreshTables(store.getContainers(), store.getItemsInstance());
}
}
ObjectCreatorViewer.java
package gui;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.HashMap;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import util.ContainerTemplate;
import util.ItemTemplate;
import core.Store;
class ObjectCreatorViewer {
private JPanel viewer;
private JPanel containersPanel;
private JSpinner containersNum;
private JSpinner cVolume;
private JSpinner cargo;
private JPanel itemsPanel;
private JSpinner itemsNum;
private JSpinner iVolume;
private JSpinner weight;
private JButton createButton;
private Store store;
private ContainerTemplate ct;
private ItemTemplate it;
private int topItemsNum;
private int topContainersNum;
private GUI gui;
private Map<JSpinner, Integer[]> spinnersTopValues;
public ObjectCreatorViewer(GUI gui, Store store,
ContainerTemplate ct,
ItemTemplate it,
final int topItemsNum,
final int topContainersNum) {
this.gui = gui;
this.ct = ct;
this.it = it;
this.topItemsNum = topItemsNum;
this.topContainersNum = topContainersNum;
this.store = store;
this.spinnersTopValues = new HashMap<JSpinner, Integer[]>();
JPanel containersNumPanel = new JPanel();
containersNum = new JSpinner(new SpinnerNumberModel(1, 1, topContainersNum, 1));
addStandardWheelListener(containersNum);
spinnersTopValues.put(containersNum, new Integer[]{1, topContainersNum});
containersNumPanel.add(new JLabel("Количесвто контейнеров (1 - " + topContainersNum + "): "));
containersNumPanel.add(containersNum);
JPanel cVolumePanel = new JPanel();
int bottomContainerVolume = ct.getVolume().getBegin();
int topContainerVolume = ct.getVolume().getEnd();
cVolume = new JSpinner(new SpinnerNumberModel(bottomContainerVolume, bottomContainerVolume, topContainerVolume, 1));
addStandardWheelListener(cVolume);
spinnersTopValues.put(cVolume, new Integer[]{bottomContainerVolume, topContainerVolume});
cVolumePanel.add(new JLabel("Объём одного контейнера, max (" + bottomContainerVolume + " - " + topContainerVolume +"): "));
cVolumePanel.add(cVolume);
JPanel cargoPanel = new JPanel();
int bottomCargo = ct.getCargo().getBegin();
int topCargo = ct.getCargo().getEnd();
cargo = new JSpinner(new SpinnerNumberModel(bottomCargo, bottomCargo, topCargo, 1));
addStandardWheelListener(cargo);
spinnersTopValues.put(cargo, new Integer[]{bottomCargo, topCargo});
cargoPanel.add(new JLabel("Грузоподъёмность одного контейнера, max (" + bottomCargo + " - " + topCargo + "): "));
cargoPanel.add(cargo);
containersPanel = new JPanel(new GridBagLayout());
containersPanel.add(containersNumPanel, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST,
GridBagConstraints.BASELINE, new Insets(5, 5, 5, 5), 0, 0));
containersPanel.add(cVolumePanel, new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.NORTHWEST,
GridBagConstraints.BASELINE, new Insets(5, 5, 5, 5), 0, 0));
containersPanel.add(cargoPanel, new GridBagConstraints(0, 2, 1, 2, 0, 0, GridBagConstraints.NORTHWEST,
GridBagConstraints.BASELINE, new Insets(5, 5, 5, 5), 0, 0));
containersPanel.setBorder(BorderFactory.createTitledBorder("Создание контейнеров"));
JPanel itemsNumPanel = new JPanel();
itemsNum = new JSpinner(new SpinnerNumberModel(1, 1, topItemsNum, 1));
addStandardWheelListener(itemsNum);
spinnersTopValues.put(itemsNum, new Integer[]{1, topItemsNum});
itemsNumPanel.add(new JLabel("Количесвто объектов (1 - " + topItemsNum + "): "));
itemsNumPanel.add(itemsNum);
JPanel iVolumePanel = new JPanel();
int singleItemBottomVolume = it.getVolume().getBegin();
int singleItemTopVolume = it.getVolume().getEnd();
iVolume = new JSpinner(new SpinnerNumberModel(singleItemBottomVolume, singleItemBottomVolume, singleItemTopVolume, 1));
addStandardWheelListener(iVolume);
spinnersTopValues.put(iVolume, new Integer[]{singleItemBottomVolume, singleItemTopVolume});
iVolumePanel.add(new JLabel("Объём одного объекта, max (" + singleItemBottomVolume + " - " + singleItemTopVolume + "): "));
iVolumePanel.add(iVolume);
JPanel weightPanel = new JPanel();
int singleItemBottomWeight = it.getVolume().getBegin();
int singleItemTopWeight = it.getVolume().getEnd();
weight = new JSpinner(new SpinnerNumberModel(singleItemBottomWeight, singleItemBottomWeight, singleItemTopWeight, 1));
addStandardWheelListener(weight);
spinnersTopValues.put(weight, new Integer[]{singleItemBottomWeight, singleItemTopWeight});
weightPanel.add(new JLabel("Вес одного объекта, max (" + singleItemBottomWeight + " - " + singleItemTopWeight + "): "));
weightPanel.add(weight);
itemsPanel = new JPanel(new GridBagLayout());
itemsPanel.add(itemsNumPanel, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST,
GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
itemsPanel.add(iVolumePanel, new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.NORTHWEST,
GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
itemsPanel.add(weightPanel, new GridBagConstraints(0, 2, 1, 1, 0, 0, GridBagConstraints.NORTHWEST,
GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
itemsPanel.setBorder(BorderFactory.createTitledBorder("Создание объектов"));
createButton = new JButton("Создать");
createButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
Store s = ObjectCreatorViewer.this.store;
s.setEmpty();
s.createContainers(getSpinnerValue(containersNum), ObjectCreatorViewer.this.ct, getSpinnerValue(cVolume), getSpinnerValue(cargo));
// LayouterLauncher.printContainersSumParameters(s.getContainers());
s.createItems(getSpinnerValue(itemsNum), ObjectCreatorViewer.this.it, getSpinnerValue(iVolume), getSpinnerValue(weight));
// LayouterLauncher.printItemsSumParameters(s.getItems());
ObjectCreatorViewer.this.gui.refreshItemsViewer();
}
});
viewer = new JPanel(new GridBagLayout());
viewer.add(containersPanel, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0));
viewer.add(itemsPanel, new GridBagConstraints(1, 0, 1, 1, 1, 1, GridBagConstraints.NORTHEAST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0));
viewer.add(createButton, new GridBagConstraints(1, 1, 1, 1, 0, 0, GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
}
/**
* @return the viewer
*/
public JPanel getViewer() {
return viewer;
}
private int getSpinnerValue(JSpinner s) {
return ((SpinnerNumberModel) s.getModel()).getNumber().intValue();
}
int getContainersNum() {
return getSpinnerValue(containersNum);
}
int getMaxContainerVolume() {
return getSpinnerValue(cVolume);
}
int getMaxCargo() {
return getSpinnerValue(cargo);
}
int getItemsNum() {
return getSpinnerValue(itemsNum);
}
int getMaxItemVolume() {
return getSpinnerValue(iVolume);
}
int getMaxWeight() {
return getSpinnerValue(weight);
}
/**
* @return the topItemsNum
*/
public int getTopItemsNum() {
return topItemsNum;
}
/**
* @return the topContainersNum
*/
public int getTopContainersNum() {
return topContainersNum;
}
private void addStandardWheelListener(final JSpinner spinner) {
spinner.addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
int value = getSpinnerValue(spinner) + ((Integer) e.getWheelRotation() * -1);
Integer[] values = spinnersTopValues.get(spinner);
int bottom = values[0];
int top = values[1];
if (bottom <= value && value <= top) {
((JSpinner) e.getComponent()).setValue(value);
}
}
});
}
}
ItemsViewer.java
package gui;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import core.Boss;
import core.Container;
import core.Item;
import core.Packer;
class ItemsViewer {
class ContainerTableModel implements TableModel {
private List<Container> containers;
private Set<TableModelListener> listeners = new HashSet<TableModelListener>();
public ContainerTableModel(List<Container> containers) {
this.containers = containers;
}
@Override
public void addTableModelListener(TableModelListener columnIndex) {
listeners.add(columnIndex);
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return Integer.class;
}
@Override
public int getColumnCount() {
return 3;
}
@Override
public String getColumnName(int columnIndex) {
switch (columnIndex) {
case 0:
return "ID";
case 1:
return "Объём";
case 2:
return "Грузоподъёмность";
}
return "column index error:\ngetted index = " + columnIndex + ",\nmost admissible index = " + (getColumnCount() - 1);
}
@Override
public int getRowCount() {
return containers.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Container c = containers.get(rowIndex);
switch (columnIndex) {
case 0:
return c.getId();
case 1:
return c.getVolume();
case 2:
return c.getCargo();
}
return null;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return false;
case 1:
case 2:
return true;
}
return false;
}
@Override
public void removeTableModelListener(TableModelListener l) {
listeners.remove(l);
}
@Override
public void setValueAt(Object arg0, int rowIndex, int columnIndex) {
Container c = containers.get(rowIndex);
switch (columnIndex) {
case 1:
c.setVolume((int) arg0);
break;
case 2:
c.setCargo((int) arg0);
break;
}
}
}
class ItemTableModel implements TableModel {
private List<Item> items;
private Set<TableModelListener> listeners = new HashSet<TableModelListener>();
public ItemTableModel(List<Item> items) {
this.items = items;
}
@Override
public void addTableModelListener(TableModelListener l) {
listeners.add(l);
}
@Override
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0:
return Integer.class;
case 1:
return Integer.class;
case 2:
return Integer.class;
case 3:
return Integer.class;
case 4:
return Integer.class;
case 5:
return Integer.class;
case 6:
return Integer.class;
case 7:
return Integer.class;
case 8:
return Double.class;
case 9:
return String.class;
}
return null;
}
@Override
public int getColumnCount() {
return 10;
}
@Override
public String getColumnName(int columnIndex) {
switch (columnIndex) {
case 0:
return "ID";
case 1:
return "Объём";
case 2:
return "Вес";
case 3:
return "Кр. 1";
case 4:
return "Кр. 2";
case 5:
return "Кр. 3";
case 6:
return "Кр. 4";
case 7:
return "Кр. 5";
case 8:
return "Полезность";
case 9:
return "Пара";
}
return "item index error:\ngetted index = " + columnIndex + ",\nmost admissible index = " + (getColumnCount() - 1);
}
@Override
public int getRowCount() {
return items.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return Integer.parseInt(items.get(rowIndex).getId());
case 1:
return items.get(rowIndex).getVolume();
case 2:
return items.get(rowIndex).getWeight();
case 3:
return items.get(rowIndex).getRate1();
case 4:
return items.get(rowIndex).getRate2();
case 5:
return items.get(rowIndex).getRate3();
case 6:
return items.get(rowIndex).getRate4();
case 7:
return items.get(rowIndex).getRate5();
case 8:
return boss.getUtility(items.get(rowIndex));
case 9:
if (items.get(rowIndex).getPair() != null) {
return items.get(rowIndex).getPair().getId();
} else {
return null;
}
}
return null;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
if (columnIndex != 0 && columnIndex != 8 && columnIndex != 9) {
return true;
}
return false;
}
@Override
public void removeTableModelListener(TableModelListener l) {
listeners.remove(l);
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
Item i = items.get(rowIndex);
switch (columnIndex) {
case 1:
i.setVolume((Integer) aValue);
break;
case 2:
i.setWeight((Integer) aValue);
break;
case 3:
i.setRate1((Integer) aValue);
break;
case 4:
i.setRate2((Integer) aValue);
break;
case 5:
i.setRate3((Integer) aValue);
break;
case 6:
i.setRate4((Integer) aValue);
break;
case 7:
i.setRate5((Integer) aValue);
break;
}
}
public void recountUtilities() {
for (int i = 0; i < items.size(); i++) {
setValueAt(ItemsViewer.this.boss.getUtility(items.get(i)), i, 8);
}
}
Item getElement(int index) {
return items.get(index);
}
List<Item> getElements() {
return items;
}
}
private JPanel viewer;
private JTable itemTable;
private JTable containersTable;
private JButton createPairButton;
private JButton breakPairButton;
private JLabel pairsNum;
private JLabel pairsCount;
private Packer packer;
private Boss boss;
public ItemsViewer(List<Container> containers, List<Item> items, Packer packer, Boss boss) {
this.boss = boss;
this.packer = packer;
viewer = new JPanel(new GridBagLayout());
ItemTableModel itm = new ItemTableModel(items);
itm.addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
((ItemTableModel) e.getSource()).recountUtilities();
}
});
itemTable = new JTable(itm);
TableRowSorter<ItemTableModel> sorter = new TableRowSorter<ItemTableModel>((ItemTableModel) itemTable.getModel());
sorter.setSortable(9, false);
itemTable.setRowSorter(sorter);
itemTable.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent arg0) {
int[] selectedRowIndices = ((JTable) arg0.getComponent()).getSelectedRows();
if (selectedRowIndices.length == 2) {
breakPairButton.setEnabled(false);
boolean single = true;
for (int index: selectedRowIndices) {
single = ((JTable) arg0.getComponent()).getModel().getValueAt(index, 9) == null;
if (!single) {
createPairButton.setEnabled(false);
break;
}
}
if (single) {
createPairButton.setEnabled(true);
}
} else if (selectedRowIndices.length == 1) {
createPairButton.setEnabled(false);
if (((ItemTableModel) itemTable.getModel()).getElement(selectedRowIndices[0]).hasPair()) {
breakPairButton.setEnabled(true);
} else {
breakPairButton.setEnabled(false);
}
} else {
createPairButton.setEnabled(false);
breakPairButton.setEnabled(false);
}
}
});
containersTable = new JTable(new ContainerTableModel(containers));
containersTable.setRowSorter(new TableRowSorter<ContainerTableModel>((ContainerTableModel) containersTable.getModel()));
createPairButton = new JButton("Создать пару");
createPairButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int[] selectedRowIndices = itemTable.getSelectedRows();
Item i1 = ((ItemTableModel) itemTable.getModel()).getElement(selectedRowIndices[0]);
Item i2 = ((ItemTableModel) itemTable.getModel()).getElement(selectedRowIndices[1]);
ItemsViewer.this.packer.createPair(i1, i2);
pairsCount.setText(ItemsViewer.this.packer.countPairs(((ItemTableModel) itemTable.getModel()).getElements()) + "");
itemTable.repaint();
((JButton) e.getSource()).setEnabled(false);
}
});
createPairButton.setEnabled(false);
breakPairButton = new JButton("Разбить пару");
breakPairButton.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
Item i1 = ((ItemTableModel) itemTable.getModel()).getElement(itemTable.getSelectedRows()[0]);
Item i2 = i1.getPair();
ItemsViewer.this.packer.breakPair(i1, i2);
itemTable.repaint();
((JButton) e.getSource()).setEnabled(false);
pairsCount.setText(ItemsViewer.this.packer.countPairs(((ItemTableModel) itemTable.getModel()).getElements()) + "");
}
});
breakPairButton.setEnabled(false);
pairsNum = new JLabel("Количество пар: ");
pairsCount = new JLabel(packer.countPairs(((ItemTableModel) itemTable.getModel()).getElements()) + "");
JPanel buttons = new JPanel();
buttons.add(createPairButton);
buttons.add(breakPairButton);
JPanel labels = new JPanel();
labels.add(pairsNum);
labels.add(pairsCount);
viewer.add(new JScrollPane(itemTable), new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0));
viewer.add(new JScrollPane(containersTable), new GridBagConstraints(1, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 5, 5, 5), 0, 0));
viewer.add(buttons, new GridBagConstraints(0, 2, 1, 1, 1, 0, GridBagConstraints.SOUTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
viewer.add(labels, new GridBagConstraints(1, 2, 1, 1, 1, 0, GridBagConstraints.SOUTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
}
public void refreshTables(List<Container> containers, List<Item> items) {
itemTable.setModel(new ItemTableModel(items));
containersTable.setModel(new ContainerTableModel(containers));
}
/**
* @return the viewer
*/
public JPanel getViewer() {
return viewer;
}
}
ParetoLayersViewer.java
package gui;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import core.Item;
import core.Packer;
import core.Store;
class ParetoLayersViewer {
class ParetoLayersTableModel implements TableModel {
private List<List<Item>> paretoLayers;
private Set<TableModelListener> listeners = new HashSet<TableModelListener>();
public ParetoLayersTableModel(List<List<Item>> paretoLayers) {
super();
this.paretoLayers = paretoLayers;
}
@Override
public void addTableModelListener(TableModelListener l) {
listeners.add(l);
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return String.class;
}
@Override
public int getColumnCount() {
int maxLayerSize = 0;
for (List<Item> l: paretoLayers) {
int currentLayerSize = l.size();
if (maxLayerSize < currentLayerSize) {
maxLayerSize = currentLayerSize;
}
}
return maxLayerSize;
}
@Override
public String getColumnName(int columnIndex) {
return (columnIndex + 1) + "";
}
@Override
public int getRowCount() {
return paretoLayers.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
List<Item> paretoLayer = paretoLayers.get(rowIndex);
if (paretoLayer.size() > columnIndex) {
return paretoLayer.get(columnIndex).getId();
}
return null;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
@Override
public void removeTableModelListener(TableModelListener l) {
listeners.remove(l);
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
}
}
private JPanel viewer;
private JTable paretoLayersTable;
private JCheckBox byUtilityBox;
private JCheckBox byVolumeBox;
private JCheckBox byWeightBox;
private JCheckBox processPairsBox;
private JButton recountButton;
private Store store;
private Packer packer;
public ParetoLayersViewer(GUI gui, Store store, Packer packer) {
this.store = store;
this.packer = packer;
this.viewer = new JPanel(new GridBagLayout());
this.byUtilityBox = new JCheckBox("По полезности", false);
byUtilityBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
refreshBoxes();
}
});
this.byVolumeBox = new JCheckBox("По объёму", false);
this.byWeightBox = new JCheckBox("По весу", false);
this.recountButton = new JButton("Пересчитать");
recountButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
recountLayers(ParetoLayersViewer.this.store.getItemsClones());
}
});
processPairsBox = new JCheckBox("Обрабатывать парные объекты", true);
JPanel checkBoxesPanel = new JPanel();
checkBoxesPanel.add(byVolumeBox);
checkBoxesPanel.add(byWeightBox);
checkBoxesPanel.add(byUtilityBox);
checkBoxesPanel.add(processPairsBox);
checkBoxesPanel.add(recountButton);
paretoLayersTable = new JTable();
viewer.add(new JScrollPane(paretoLayersTable), new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(5, 5, 0, 0), 0, 0));
viewer.add(checkBoxesPanel, new GridBagConstraints(0, 1, 1, 1, 1, 1, GridBagConstraints.SOUTHWEST, GridBagConstraints.NONE, new Insets(5, 0, 5, 0), 0, 0));
refreshBoxes();
}
public void recountLayers(List<Item> sourceSet) {
if (processPairsBox.isSelected()) {
sourceSet = packer.processPairs(sourceSet);
}
List<List<Item>> paretoSet = packer.createParetoSet(sourceSet);
if (byUtilityBox.isSelected()) {
for (List<Item> paretoLayer: paretoSet) {
packer.sort(paretoLayer, Packer.SORT_TYPE.UTILITY);
}
} else {
if (byVolumeBox.isSelected() && byWeightBox.isSelected()) {
for (List<Item> paretoLayer: paretoSet) {
packer.sort(paretoLayer, Packer.SORT_TYPE.VOLUME, Packer.SORT_TYPE.WEIGHT);
}
} else {
if (byVolumeBox.isSelected()) {
for (List<Item> paretoLayer: paretoSet) {
packer.sort(paretoLayer, Packer.SORT_TYPE.VOLUME);
}
} else if (byWeightBox.isSelected()) {
for (List<Item> paretoLayer: paretoSet) {
packer.sort(paretoLayer, Packer.SORT_TYPE.WEIGHT);
}
}
}
}
store.setParetoSet(paretoSet);
paretoLayersTable.setModel(new ParetoLayersTableModel(paretoSet));
for (int i = 0; i < paretoLayersTable.getColumnCount(); i++) {
TableColumn column = paretoLayersTable.getColumn((i + 1) + "");
column.setMinWidth(35);
}
}
/**
* @return the paretoLayersPanel
*/
public JPanel getViewer() {
return viewer;
}
private void refreshBoxes() {
boolean state = !byUtilityBox.isSelected();
byVolumeBox.setEnabled(state);
byWeightBox.setEnabled(state);
}
}
ResultViewer.java
package gui;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;
import java.util.SortedMap;
import javax.swing.ComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextPane;
import javax.swing.JTree;
import javax.swing.event.ListDataListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
import core.Boss;
import core.Container;
import core.Item;
import core.Packer;
import core.Store;
import core.Packer.ALGORYTHM;
class ResultViewer {
private class Resume {
private String algNameReport;
private String effectivityReport;
private String restReport;
private String packedReport;
private DecimalFormat format;
public Resume() {
DecimalFormatSymbols f = new DecimalFormatSymbols();
f.setDecimalSeparator('.');
format = new DecimalFormat("#,##0.00", f);
}
/**
* @param algNameReport the algNameReport to set
*/
public void setAlgNameReport(String algNameReport) {
this.algNameReport = "<h2><font color='RED'>Алгоритм: " + algNameReport + "</text></h2><p>";
}
/**
* @param effectivityReport the effectivityReport to set
*/
public void setEffectivityReport(SortedMap<Container, List<Item>> map) {
String header = "<h3><font color='RED'>Эффективность алгоритма</font></h3>";
double occupiedSpacePercent = 0;
double loadPercent = 0;
double volumeAccumulator = 0;
double weightAccumulator = 0;
double iVolumeAccumulator = 0;
double cargoAccumulator = 0;
for (Container c: map.keySet()) {
for (Item i: map.get(c)) {
iVolumeAccumulator += i.getVolume();
weightAccumulator += i.getWeight();
}
volumeAccumulator += c.getVolume();
cargoAccumulator += c.getCargo();
}
occupiedSpacePercent = (iVolumeAccumulator / volumeAccumulator) * 100;
loadPercent = (weightAccumulator / cargoAccumulator) * 100;
String occupiedSpacePercentString = getFormattedPair("Процент заполнения пространства контейнеров", occupiedSpacePercent);
String loadPercentString = getFormattedPair("Процент загрузки контейнеров", loadPercent);
String loadedItemsMass = getFormattedPair("Общая масса упакованных объектов", weightAccumulator);
String loadedItemsVolume = getFormattedPair("Общий объём упакованных объектов", iVolumeAccumulator);
String effectivityReport = occupiedSpacePercentString + loadPercentString + loadedItemsVolume + loadedItemsMass;
this.effectivityReport = header + effectivityReport;
}
/**
* @param restReport the restReport to set
*/
public void setRestReport(Store store) {
String header = "<h3><font color='RED'>Остаток на складе</font></h3>";
double volumeAccumulator = 0;
double weightAccumulator = 0;
for (Item i : store.getRest()) {
volumeAccumulator += i.getVolume();
weightAccumulator += i.getWeight();
}
String restVolume = getFormattedPair("Общий объём оставшихся объектов", volumeAccumulator);
String restWeight = getFormattedPair("Общий вес оставшихся объектов", weightAccumulator);
this.restReport = header + restVolume + restWeight;
}
/**
* @param packedReport the packedReport to set
*/
public void setPackedReport(SortedMap<Container, List<Item>> map) {
String packedReport = "<h3><font color='RED'>Упакованные объекты</font></h3>";
for (Container c: map.keySet()) {
String containerID = "Контейнер ";
String itemsID = "Объекты:";
String freeSpace = "Свободное место в контейнере: ";
String freeCargo = "Неиспользованная грузоподъёмность: ";
double iVolumeAccumulator = 0;
double iWeightAccumulator = 0;
containerID += c.getId() + "<br>";
for (Item i: map.get(c)) {
itemsID += " " + i.getId();
iVolumeAccumulator += i.getVolume();
iWeightAccumulator += i.getWeight();
}
itemsID += "<br>";
freeSpace += (c.getVolume() - iVolumeAccumulator) + "<br>";
freeCargo += (c.getCargo() - iWeightAccumulator) + "<br>";
packedReport += containerID + itemsID + freeSpace + freeCargo + "<br>";
}
this.packedReport = packedReport;
}
/**
* @return the algNameReport
*/
public String getAlgNameReport() {
return algNameReport;
}
/**
* @return the effectivityReport
*/
public String getEffectivityReport() {
return effectivityReport;
}
/**
* @return the restReport
*/
public String getRestReport() {
return restReport;
}
/**
* @return the packedReport
*/
public String getPackedReport() {
return packedReport;
}
private String getFormattedPair(String string, double value) {
return "<font color='BLUE'>" + string + ": " +
"<font color='GREEN'><b>" + format.format(value) + "</b></font></font><br>";
}
}
private class ConsoleLogTextPane extends JTextPane {
/**
*
*/
private static final long serialVersionUID = -5691372469851601341L;
private String TEMPLATE = "<html><title></title><body></body></html>";
private String buffer;
private int breakIndex;
public ConsoleLogTextPane() {
setText(TEMPLATE);
setContentType("text/html");
breakIndex = 0;
}
public void addString(String str){
buffer = this.getText();
breakIndex = buffer.lastIndexOf("</body>");
buffer = buffer.substring(0, breakIndex) + str + buffer.substring(breakIndex);
this.setText(buffer);
}
public void clearConsole() {
this.setText(TEMPLATE);
}
}
class AlgorythmsComboBoxModel implements ComboBoxModel<String> {
private Set<ListDataListener> listeners;
private List<String> elements;
private String selected;
public AlgorythmsComboBoxModel(String... strings) {
listeners = new HashSet<ListDataListener>();
elements = new ArrayList<String>();
selected = "";
for (String s: strings) {
elements.add(s);
}
}
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
}
@Override
public String getElementAt(int index) {
return elements.get(index);
}
@Override
public int getSize() {
return elements.size();
}
@Override
public void removeListDataListener(ListDataListener l) {
listeners.remove(l);
}
@Override
public Object getSelectedItem() {
return selected;
}
@Override
public void setSelectedItem(Object anItem) {
selected = (String) anItem;
}
}
class ResultTreeCellRenderer implements TreeCellRenderer {
private JLabel label = new JLabel();
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row,
boolean hasFocus) {
if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
ImageIcon icon = null;
DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
Object userObject = node.getUserObject();
if (userObject instanceof Container) {
icon = new ImageIcon(ResultViewer.class.getResource("images/Container.png"));
label.setText("Контейнер, ID: " + ((Container) userObject).getId());
} else if (userObject instanceof Item) {
icon = new ImageIcon(ResultViewer.class.getResource("images/Item.png"));
label.setText("Объект, ID: " + ((Item) userObject).getId());
} else if (userObject instanceof String) {
if (node.getParent() == null ||
node.getParent() == value) {
icon = new ImageIcon(ResultViewer.class.getResource("images/Containers.png"));
} else {
icon = new ImageIcon(ResultViewer.class.getResource("images/Field.png"));
}
label.setText((String) node.getUserObject());
}
label.setOpaque(true);
if (selected) {
label.setBackground(new DefaultTreeCellRenderer().getBackgroundSelectionColor());
} else {
label.setBackground(new DefaultTreeCellRenderer().getBackgroundNonSelectionColor());
}
label.setIcon(icon);
}
return label;
}
}
private JPanel viewer;
private JTree tree;
private JPanel treePanel;
private JPanel cBoxPanel;
private JButton packButton;
private JButton clearConsoleButton;
private ConsoleLogTextPane resumeLoggerPane;
private JSplitPane splitPane;
private JComboBox<String> algorythmsBox;
private Hashtable<String, Packer.ALGORYTHM> table;
private final String NO_ALGORYTHM_CHOSEN = "Выберите алгоритм";
private final String FIRST = "В первый подходящий";
private final String BEST = "В лучший из подходящих";
private Resume resume;
public ResultViewer(final GUI gui, final Store store, final Packer packer, final Boss boss) {
resumeLoggerPane = new ConsoleLogTextPane();
resumeLoggerPane.setEditable(false);
resume = new Resume();
DefaultMutableTreeNode top = new DefaultMutableTreeNode("[пусто]");
table = new Hashtable<String, Packer.ALGORYTHM>();
table.put(FIRST, ALGORYTHM.FIRST);
table.put(BEST, ALGORYTHM.BEST);
algorythmsBox = new JComboBox<String>(new AlgorythmsComboBoxModel(NO_ALGORYTHM_CHOSEN, FIRST, BEST));
algorythmsBox.setSelectedIndex(0);
algorythmsBox.addItemListener(new ItemListener() {
@SuppressWarnings("unchecked")
@Override
public void itemStateChanged(ItemEvent arg0) {
packButton.setEnabled(((JComboBox<String>) arg0.getSource()).getModel().getSelectedItem() != NO_ALGORYTHM_CHOSEN &&
store.getParetoSetInstance() != null &&
!store.getParetoSetInstance().isEmpty());
}
});
packButton = new JButton("Упаковать");
packButton.setEnabled(false);
packButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
if (store != null) {
store.getRest().clear();
if (store.getParetoSetInstance() != null) {
List<List<Integer>> templates = store.getTemplates();
double maxUtilityRate = 0;
int maxUtilityIndex = 0;
SortedMap<Container, List<Item>> map = null;
for (int i = 0; i < templates.size(); i++) {
map = store.getMapClone(i);
for (List<Item> paretoLayer: store.getParetoSetClone()) {
packer.pack(map, paretoLayer, table.get(algorythmsBox.getSelectedItem()));
}
double utilityRate = boss.getPackUtility(map);
if (maxUtilityRate < utilityRate) {
maxUtilityRate = utilityRate;
maxUtilityIndex = i;
}
store.getRest().clear();
}
map = store.getMapClone(maxUtilityIndex);
for (List<Item> paretoLayer: store.getParetoSetClone()) {
packer.pack(map, paretoLayer, table.get(algorythmsBox.getSelectedItem()));
}
refreshTree(map); resume.setAlgNameReport((String) ResultViewer.this.algorythmsBox.getSelectedItem());
resume.setEffectivityReport(map);
resume.setRestReport(store);
resume.setPackedReport(map);
resumeLoggerPane.addString(resume.getAlgNameReport());
resumeLoggerPane.addString(resume.getEffectivityReport());
resumeLoggerPane.addString(resume.getRestReport());
resumeLoggerPane.addString(resume.getPackedReport());
}
}
}
});
clearConsoleButton = new JButton("Очистить");
clearConsoleButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
ResultViewer.this.resumeLoggerPane.clearConsole();
}
});
viewer = new JPanel(new GridBagLayout());
tree = new JTree(top);
tree.setCellRenderer(new ResultTreeCellRenderer());
treePanel = new JPanel(new GridBagLayout());
treePanel.add(new JScrollPane(tree), new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
cBoxPanel = new JPanel(new GridBagLayout());
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, treePanel, cBoxPanel);
splitPane.setOneTouchExpandable(true);
splitPane.setDividerLocation(350);
cBoxPanel.add(new JScrollPane(resumeLoggerPane), new GridBagConstraints(0, 0, 2, 1, 1, 1, GridBagConstraints.NORTHEAST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
cBoxPanel.add(algorythmsBox, new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
cBoxPanel.add(packButton, new GridBagConstraints(1, 1, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
cBoxPanel.add(clearConsoleButton, new GridBagConstraints(1, 1, 1, 1, 0, 0, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
viewer.add(splitPane, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
}
public void refreshTree(SortedMap<Container, List<Item>> map) {
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Упакованные объекты", true);
createTree(root, map);
}
private void createTree(DefaultMutableTreeNode root, SortedMap<Container, List<Item>> map) {
((DefaultMutableTreeNode) ((DefaultTreeModel) tree.getModel()).getRoot()).removeAllChildren();
((DefaultTreeModel) tree.getModel()).setRoot(root);
DefaultMutableTreeNode container = null;
DefaultMutableTreeNode item = null;
DefaultMutableTreeNode containerField = null;
DefaultMutableTreeNode itemField = null;
Set<Container> containers = map.keySet();
for (Container c: containers) {
container = new DefaultMutableTreeNode(c, true);
List<Item> items = map.get(c);
containerField = new DefaultMutableTreeNode("ID: " + c.getId(), false);
container.add(containerField);
containerField = new DefaultMutableTreeNode("Объём: " + c.getVolume(), false);
container.add(containerField);
containerField = new DefaultMutableTreeNode("Грузоподъёмность: " + c.getCargo(), false);
container.add(containerField);
for (Item i: items) {
item = new DefaultMutableTreeNode(i, true);
itemField = new DefaultMutableTreeNode("ID: " + i.getId(), false);
item.add(itemField);
itemField = new DefaultMutableTreeNode("Объём: " + i.getVolume(), false);
item.add(itemField);
itemField = new DefaultMutableTreeNode("Вес: " + i.getWeight(), false);
item.add(itemField);
itemField = new DefaultMutableTreeNode("Кр. 1: " + i.getRate1(), false);
item.add(itemField);
itemField = new DefaultMutableTreeNode("Кр. 2: " + i.getRate2(), false);
item.add(itemField);
itemField = new DefaultMutableTreeNode("Кр. 3: " + i.getRate3(), false);
item.add(itemField);
itemField = new DefaultMutableTreeNode("Кр. 4: " + i.getRate4(), false);
item.add(itemField);
itemField = new DefaultMutableTreeNode("Кр. 5: " + i.getRate5(), false);
item.add(itemField);
if (i.hasPair()) {
itemField = new DefaultMutableTreeNode("ID парного объекта: " + i.getPair().getId());
item.add(itemField);
}
container.add(item);
}
root.add(container);
}
tree.expandPath(new TreePath(((DefaultMutableTreeNode) ((DefaultMutableTreeNode) root.getChildAt(0)).getChildAt(3)).getPath()));
}
/**
* @return the viewer
*/
public JPanel getViewer() {
return viewer;
}
}
Пакет launcher.
LayouterLauncher.java
package launcher;
import gui.GUI;
import util.ContainerTemplate;
import util.IntegerDiapason;
import util.ItemTemplate;
import core.Boss;
import core.Packer;
import core.Store;
public class LayouterLauncher {
/**
* @param args
*/
public static void main(String[] args) {
// Задаём ограничения на предельные значения параметров объектов и контейнеров.
ContainerTemplate ct = new ContainerTemplate(new IntegerDiapason(25, 40), new IntegerDiapason(25, 40));
ItemTemplate it = new ItemTemplate(new IntegerDiapason(1, 20),
new IntegerDiapason(1, 20),
new IntegerDiapason(1, 5),
new IntegerDiapason(1, 5),
new IntegerDiapason(1, 5),
new IntegerDiapason(1, 5),
new IntegerDiapason(1, 5)
);
// Создаём склад.
Store store = new Store();
// Создаём ЛПР
Boss boss = new Boss();
// Создаём упаковщика.
Packer packer = new Packer(store, boss);
new GUI(store, packer, boss, ct, it);
}
}
