示例#1
0
        //Функция получающая на ход набор вещей, возвращающая набор вещей максимальной стоимости для веса рюкзака
        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);
        }