//Функция получающая на ход набор вещей, возвращающая набор вещей максимальной стоимости для веса рюкзака public Things PackOptimally(Things things, TreeView main, TextBox result) { //Счетчики текущих цены и веса в проуессе подсчета float currCost = 0; float currWeight = 0; //Список из инексов включенных в текущую выборку List <int> indexes = new List <int>(); //Список из индексов эл-тов, сумма которых максимальна List <int> final = new List <int>(); //Корень дерева для визуализации TreeNode root = null; //Внутренняя функция генерации следующего шага. Задача сводится к поиску оптимальной неупорядоченной //выборки без повторений, следовательно, оптимальный обход и подбор будет происходить по порядку //на вход подается позиция с которой нужно начать цикл void tryNextStep(int start) { //Если мы дошли до конца, то нужно просто проверить превосодить полученная сумма максимальную if (start == things.Count) { //Если да, то обновляем значения if (CurCost < currCost) { //Обновляем максимум CurCost = currCost; //Обновляем выборку, вместе с тем, отчет о промежуточном максимуме выводим на экран final.Clear(); for (int j = 0; j < indexes.Count; ++j) { final.Add(indexes.ElementAt(j)); result.Text += things[indexes.ElementAt(j)].thing.ToString() + Environment.NewLine; } result.Text += "Промежуточный вес : " + currWeight.ToString() + Environment.NewLine + "Промежуточная стоимость : " + CurCost.ToString() + Environment.NewLine + "----------------------------------------" + Environment.NewLine; } return; } //Иначе идем до конца списка for (int i = start; i < things.Count; ++i) { //Выбираем свободный элемент if (things[i].condition == Condition.Free) { //Если его включение приемлемо if (things[i].GetWeight() + currWeight <= Capacity) { //Добавляем в выборку indexes.Add(i); //Прибавляем к общему весу и общей стоимости currWeight += things[i].GetWeight(); currCost += things[i].GetCost(); //Генерируем узел дерева start -= 1; if (start == -1) { start = 0; } //Создаем строку узла W - текущий суммарный вес, C - текущая общая стоимость string s = things[i].thing.Name + ", W= " + currWeight.ToString() + ", C= " + currCost.ToString(); //Создаем узел дерева и добавляем его TreeNode one = new TreeNode(s); if (root == null) { main.Nodes.Add(one); } else { root.Nodes.Add(one); } root = one; //Меняем состояние на выбранное things[i].condition = Condition.Chosen; //Генерируем след. шаг tryNextStep(i + 1); //"Откатываем назад", стираем запись, уменьшаем вес и сумму currWeight -= things[i].GetWeight(); currCost -= things[i].GetCost(); root = root.Parent; things[i].condition = Condition.Free; indexes.Remove(i); } //Включение невозможно else //Проверяем, превосходит ли полученная выборка стоимость максимальной if (CurCost < currCost) { //Если да, обновляем данные CurCost = currCost; final.Clear(); for (int j = 0; j < indexes.Count; ++j) { final.Add(indexes.ElementAt(j)); result.Text += things[indexes.ElementAt(j)].thing.ToString() + Environment.NewLine; } result.Text += "Промежуточный вес : " + currWeight.ToString() + Environment.NewLine + "Промежуточная стоимость : " + CurCost.ToString() + Environment.NewLine + "----------------------------------------" + Environment.NewLine; } } } } //Запускаем генерацию сначала tryNextStep(0); //Формариуем результирующий список вещей Things res = new Things(); for (int i = 0; i < final.Count; ++i) { res.Add(things[final.ElementAt(i)].thing); } return(res); }