From 07a6ddd44944543968e0fbd108e244e8c773fec7 Mon Sep 17 00:00:00 2001 From: "github-classroom[bot]" <66690702+github-classroom[bot]@users.noreply.github.com> Date: Sun, 5 Jun 2022 17:46:14 +0000 Subject: [PATCH 1/2] Setting up GitHub Classroom Feedback From 927c0c30e7e81cd9fe13f7b06aff1e3d8b72bca7 Mon Sep 17 00:00:00 2001 From: SRVergasov Date: Sun, 5 Jun 2022 20:53:44 +0300 Subject: [PATCH 2/2] completed --- README.md | 4 ++-- src/bits.cpp | 6 +++--- src/knapsack/backtracking.cpp | 8 ++++++-- src/knapsack/bit_masking.cpp | 9 ++++++++- src/subset_sum/backtracking.cpp | 8 ++++++-- src/subset_sum/bit_masking.cpp | 16 ++++++++++++++++ src/subsets/backtracking.cpp | 4 +++- src/subsets/bit_masking.cpp | 10 +++++++--- 8 files changed, 51 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index c82d0ec..fb62c9d 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..6712d98 100644 --- a/src/bits.cpp +++ b/src/bits.cpp @@ -5,13 +5,13 @@ namespace assignment { bool is_bit_set(int mask, int pos) { - assert(mask >= 0 && pos >= 0 && pos < 30); - return false; + assert(mask >= 0 && pos >= 0 && pos < 30); // pos < макс. кол-ва бит в маске + return ((mask & (1 << pos)) != 0); } 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..91e62ea 100644 --- a/src/knapsack/backtracking.cpp +++ b/src/knapsack/backtracking.cpp @@ -35,13 +35,17 @@ namespace assignment { // ... если текущая "польза" максимальна, обновляем наилучшую "пользу" if (profit > best_profit) { - // ... + best_profit_mask = mask; + best_profit = profit; } // рассматриваем следующий элемент index += 1; + solve(profits, weights, capacity, index, set_bit(mask, index), weight + weights[index], profit + profits[index], + best_profit, best_profit_mask); + solve(profits, weights, capacity, index, mask, weight, profit, best_profit, best_profit_mask); // ... рекурсивные вызовы со включением/исключением следующего элемента } -} // namespace assignment +} // namespace assignment \ No newline at end of file diff --git a/src/knapsack/bit_masking.cpp b/src/knapsack/bit_masking.cpp index 4160fef..c98f65a 100644 --- a/src/knapsack/bit_masking.cpp +++ b/src/knapsack/bit_masking.cpp @@ -34,6 +34,9 @@ namespace assignment { const int curr_weight = sum_helper(masked_weights); // ... обработка случая превышения емкости рюкзака + if (curr_weight > capacity) { + continue; + } // массив из "пользы" рассматриваемых элементов const auto masked_profits = mask2elems(profits, mask); @@ -42,11 +45,15 @@ 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..0c13bf7 100644 --- a/src/subset_sum/backtracking.cpp +++ b/src/subset_sum/backtracking.cpp @@ -32,13 +32,13 @@ namespace assignment { } // Ограничение 1: текущая сумма должна быть меньше целевой - if (true /* ... */) { + if (sum > target_sum) { // если превысили целевую сумму, то сделать ее меньше уже не получится (все элементы множества положительные) return; } // Ограничение 2: "остаточная сумма" + "текущая сумма" должны быть больше или равны "целевой сумме" - if (true /* ... */) { + if (sum + residual < target_sum) { // сумму невозможно будет набрать с оставшимися элементами множества return; } @@ -47,6 +47,8 @@ namespace assignment { if (sum == target_sum) { // ... сохранение в результат // ... нужно ли в этой ветке рекурсии рассматривать следующие элементы? + indices.push_back(mask2indices(set, mask)); + return; } // рассматриваем следующий элемент @@ -56,6 +58,8 @@ namespace assignment { residual -= set[index]; // рекурсивный вызов со включением/исключением элемента с текущим индексом ... + search(set, index, set_bit(mask, index), sum + set[index], residual, target_sum, indices); + search(set, index, mask, sum, 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..a280349 100644 --- a/src/subset_sum/bit_masking.cpp +++ b/src/subset_sum/bit_masking.cpp @@ -18,6 +18,22 @@ namespace assignment { // 2. Внутренний цикл: проверка разрядов битовой маски и генерация подмножества, ассоциирующегося с этой маской // 3. Подсчет суммы текущего подмножества, сохранение индексов подмножества с целевой суммой в результат // Tips: можно пропустить итерацию, если сумма текущего подмножества стала больше целевой суммы + int sum; + + for (int mask = 0; mask < num_subsets; mask++) { + sum = 0; + for (int pos = 0; pos < num_elems; pos++) { + if (is_bit_set(mask, pos)) { + sum += set[pos]; + if (sum > target_sum) { + break; + } + } + } + if (sum == target_sum) { + indices.push_back(mask2indices(set, mask)); + } + } return indices; } diff --git a/src/subsets/backtracking.cpp b/src/subsets/backtracking.cpp index 256dd5b..4c546cc 100644 --- a/src/subsets/backtracking.cpp +++ b/src/subsets/backtracking.cpp @@ -28,7 +28,7 @@ namespace assignment { // Ограничение: рассмотрены все элементы множества if (index == static_cast(set.size()) - 1) { - // ... сохранение полученного подмножества + subsets.push_back(mask2indices(set, mask)); return; // возвращаемся по дереву рекурсии } @@ -37,6 +37,8 @@ namespace assignment { // здесь должны быть рекурсивные вызовы ... // включаем или не включаем элемент с текущим индексом в подмножество (используя битовую маску) + generate(set, index, mask, subsets); + generate(set, index, set_bit(mask, 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..4b50747 100644 --- a/src/subsets/bit_masking.cpp +++ b/src/subsets/bit_masking.cpp @@ -15,9 +15,13 @@ namespace assignment { // выделяем память auto subsets = std::vector>(num_subsets); - // 1. Внешний цикл: пробегаемся по всем битовым маскам от 0..00 до 1..11 - // 2. Внутренний цикл: проверка разрядов битовой маски и генерация подмножества, ассоциирующегося с этой маской - // Tips: для проверки разряда бита на 1 (единицу) используйте функцию is_bit_set + for (int mask = 0; mask < num_subsets; mask++) { + for (int pos = 0; pos < num_elems; pos++) { + if (is_bit_set(mask, pos)) { + subsets[mask].push_back(pos); + } + } + } return subsets; }