From d459a017d2f73fc474693491315cd2295799ba64 Mon Sep 17 00:00:00 2001 From: "github-classroom[bot]" <66690702+github-classroom[bot]@users.noreply.github.com> Date: Wed, 1 Jun 2022 18:14:48 +0000 Subject: [PATCH 1/2] Setting up GitHub Classroom Feedback From 9fa0ac4b76f63d1a0bcf23af80e9f162039d2391 Mon Sep 17 00:00:00 2001 From: Dima Sudakov Date: Wed, 1 Jun 2022 22:55:13 +0300 Subject: [PATCH 2/2] dead --- README.md | 4 ++-- src/bits.cpp | 4 ++-- src/knapsack/backtracking.cpp | 16 ++++++++++------ src/knapsack/bit_masking.cpp | 8 ++++++-- src/subset_sum/backtracking.cpp | 25 ++++++++++++++----------- src/subset_sum/bit_masking.cpp | 15 +++++++++++++++ src/subsets/backtracking.cpp | 15 ++++++++------- src/subsets/bit_masking.cpp | 8 ++++++++ 8 files changed, 65 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index c82d0ec..49873b8 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ ## 1. Информация о студенте -**Номер группы**: 00-000 +**Номер группы**: 11-101 -**Фамилия и Имя**: Иванов Иван +**Фамилия и Имя**: Судаков Дмитрий ## 2. Описание задания diff --git a/src/bits.cpp b/src/bits.cpp index 37cf7a0..b1da664 100644 --- a/src/bits.cpp +++ b/src/bits.cpp @@ -6,12 +6,12 @@ namespace assignment { bool is_bit_set(int mask, int pos) { assert(mask >= 0 && pos >= 0 && pos < 30); - return false; + return (mask & (1 << pos)); } int set_bit(int mask, int pos) { assert(mask >= 0 && pos >= 0 && pos < 30); - return 0; + return (mask | (1 << pos)); } std::vector mask2indices(const std::vector& elems, int mask) { diff --git a/src/knapsack/backtracking.cpp b/src/knapsack/backtracking.cpp index d051dc2..7eef7c4 100644 --- a/src/knapsack/backtracking.cpp +++ b/src/knapsack/backtracking.cpp @@ -23,11 +23,6 @@ namespace assignment { void KnapsackBacktracking::solve(const Profits& profits, const Weights& weights, int capacity, int index, int mask, int weight, int profit, int& best_profit, int& best_profit_mask) const { - // Ограничение 0: выход за пределы - if (index == static_cast(profits.size())) { - return; - } - // Ограничение 1: превышение лимита емкости рюкзака if (weight > capacity) { return; @@ -35,13 +30,22 @@ namespace assignment { // ... если текущая "польза" максимальна, обновляем наилучшую "пользу" if (profit > best_profit) { - // ... + best_profit = profit; + best_profit_mask = mask; } // рассматриваем следующий элемент index += 1; + // Ограничение 0: выход за пределы + if (index == static_cast(profits.size())) { + return; + } + // ... рекурсивные вызовы со включением/исключением следующего элемента + solve(profits, weights, capacity, index, mask, weight, profit, best_profit, best_profit_mask); + solve(profits, weights, capacity, index, mask | (1 << index), weight + weights[index], profit + profits[index], + best_profit, best_profit_mask); } } // namespace assignment diff --git a/src/knapsack/bit_masking.cpp b/src/knapsack/bit_masking.cpp index 4160fef..719e106 100644 --- a/src/knapsack/bit_masking.cpp +++ b/src/knapsack/bit_masking.cpp @@ -34,6 +34,7 @@ namespace assignment { const int curr_weight = sum_helper(masked_weights); // ... обработка случая превышения емкости рюкзака + if(curr_weight > capacity) continue; // массив из "пользы" рассматриваемых элементов const auto masked_profits = mask2elems(profits, mask); @@ -42,11 +43,14 @@ namespace assignment { const int curr_profit = sum_helper(masked_profits); // ... обработка случая нахождения большего значения "пользы" + if(curr_profit > best_profit) { + best_profit = curr_profit; + best_profit_mask = mask; + } } // ... возвращение итогового результата: используйте mask2indices; - - return {}; + return mask2indices(profits, best_profit_mask); } } // namespace assignment \ No newline at end of file diff --git a/src/subset_sum/backtracking.cpp b/src/subset_sum/backtracking.cpp index c5c7469..729d4d0 100644 --- a/src/subset_sum/backtracking.cpp +++ b/src/subset_sum/backtracking.cpp @@ -26,36 +26,39 @@ namespace assignment { assert(index >= -1 && mask >= 0 && sum >= 0 && residual >= 0 && target_sum > 0); - // Ограничение 0: вышли за пределы множества - if (index == static_cast(set.size())) { - return; - } - // Ограничение 1: текущая сумма должна быть меньше целевой - if (true /* ... */) { - // если превысили целевую сумму, то сделать ее меньше уже не получится (все элементы множества положительные) + if (sum > target_sum) { return; } // Ограничение 2: "остаточная сумма" + "текущая сумма" должны быть больше или равны "целевой сумме" - if (true /* ... */) { - // сумму невозможно будет набрать с оставшимися элементами множества + if (sum + residual < target_sum) { return; } // если найдено подмножество с целевой суммой, то сохраняем в результат это подмножество if (sum == target_sum) { - // ... сохранение в результат - // ... нужно ли в этой ветке рекурсии рассматривать следующие элементы? + std::vector res; + for(int pos = 0; pos < set.size(); pos++) { + if(is_bit_set(mask, pos)) res.push_back(pos); + } + indices.push_back(res); } // рассматриваем следующий элемент index += 1; + // Ограничение 0: вышли за пределы множества + if (index == static_cast(set.size())) { + return; + } + // обновляется несмотря на включение/исключение элемента => почему? residual -= set[index]; // рекурсивный вызов со включением/исключением элемента с текущим индексом ... + search(set, index, mask, sum, residual, target_sum, indices); + search(set, index, mask | (1 << index), sum + set[index], residual, target_sum, indices); } } // namespace assignment \ No newline at end of file diff --git a/src/subset_sum/bit_masking.cpp b/src/subset_sum/bit_masking.cpp index 4deec18..8133a06 100644 --- a/src/subset_sum/bit_masking.cpp +++ b/src/subset_sum/bit_masking.cpp @@ -1,6 +1,7 @@ #include "assignment/subset_sum/bit_masking.hpp" #include // assert +#include #include "assignment/bits.hpp" // is_bit_set, mask2indices @@ -18,6 +19,20 @@ namespace assignment { // 2. Внутренний цикл: проверка разрядов битовой маски и генерация подмножества, ассоциирующегося с этой маской // 3. Подсчет суммы текущего подмножества, сохранение индексов подмножества с целевой суммой в результат // Tips: можно пропустить итерацию, если сумма текущего подмножества стала больше целевой суммы + for(int mask = 0; mask < num_subsets; mask++) { + int sum = 0; + std::vector res; + for(int pos = 0; pos < set.size(); pos++) { + if(is_bit_set(mask, pos)) { + sum += set[pos]; + res.push_back(pos); + } + if(sum > target_sum) break; + } + if(sum == target_sum) { + indices.push_back(res); + } + } return indices; } diff --git a/src/subsets/backtracking.cpp b/src/subsets/backtracking.cpp index 256dd5b..dad515a 100644 --- a/src/subsets/backtracking.cpp +++ b/src/subsets/backtracking.cpp @@ -12,8 +12,7 @@ namespace assignment { const auto num_elems = static_cast(set.size()); // N const int num_subsets = 1 << num_elems; // 2^N - auto subsets = std::vector>(); - subsets.reserve(num_subsets); + auto subsets = std::vector>(num_subsets); // вызов вспомогательной функции: обратите внимание на начальное значение индекса и маски generate(set, -1, 0, subsets); @@ -27,16 +26,18 @@ namespace assignment { // Ограничение: рассмотрены все элементы множества if (index == static_cast(set.size()) - 1) { - - // ... сохранение полученного подмножества - + std::vector res; + for(int pos = 0; pos < set.size(); pos++) { + if(is_bit_set(mask, pos)) res.push_back(pos); + } + subsets[mask] = res; return; // возвращаемся по дереву рекурсии } index += 1; // рассматриваем следующий элемент - // здесь должны быть рекурсивные вызовы ... - // включаем или не включаем элемент с текущим индексом в подмножество (используя битовую маску) + generate(set, index, mask, subsets); + generate(set, index, mask + (1 << index), subsets); } } // namespace assignment \ No newline at end of file diff --git a/src/subsets/bit_masking.cpp b/src/subsets/bit_masking.cpp index feadd7e..4c1bc6e 100644 --- a/src/subsets/bit_masking.cpp +++ b/src/subsets/bit_masking.cpp @@ -19,6 +19,14 @@ namespace assignment { // 2. Внутренний цикл: проверка разрядов битовой маски и генерация подмножества, ассоциирующегося с этой маской // Tips: для проверки разряда бита на 1 (единицу) используйте функцию is_bit_set + for(int mask = 0; mask < num_subsets; mask++) { + std::vector res; + for(int pos = 0; pos < set.size(); pos++) { + if(is_bit_set(mask, pos)) res.push_back(pos); + } + subsets[mask] = res; + } + return subsets; }