Skip to content

Feedback #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: feedback
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

## 1. Информация о студенте

**Номер группы**: 00-000
**Номер группы**: 11-101

**Фамилия и Имя**: Иванов Иван
**Фамилия и Имя**: Судаков Дмитрий

## 2. Описание задания

Expand Down
4 changes: 2 additions & 2 deletions src/bits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<int> mask2indices(const std::vector<int>& elems, int mask) {
Expand Down
16 changes: 10 additions & 6 deletions src/knapsack/backtracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,29 @@ 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<int>(profits.size())) {
return;
}

// Ограничение 1: превышение лимита емкости рюкзака
if (weight > capacity) {
return;
}

// ... если текущая "польза" максимальна, обновляем наилучшую "пользу"
if (profit > best_profit) {
// ...
best_profit = profit;
best_profit_mask = mask;
}

// рассматриваем следующий элемент
index += 1;

// Ограничение 0: выход за пределы
if (index == static_cast<int>(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
8 changes: 6 additions & 2 deletions src/knapsack/bit_masking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
25 changes: 14 additions & 11 deletions src/subset_sum/backtracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,36 +26,39 @@ namespace assignment {

assert(index >= -1 && mask >= 0 && sum >= 0 && residual >= 0 && target_sum > 0);

// Ограничение 0: вышли за пределы множества
if (index == static_cast<int>(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<int> 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<int>(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
15 changes: 15 additions & 0 deletions src/subset_sum/bit_masking.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "assignment/subset_sum/bit_masking.hpp"

#include <cassert> // assert
#include <numeric>

#include "assignment/bits.hpp" // is_bit_set, mask2indices

Expand All @@ -18,6 +19,20 @@ namespace assignment {
// 2. Внутренний цикл: проверка разрядов битовой маски и генерация подмножества, ассоциирующегося с этой маской
// 3. Подсчет суммы текущего подмножества, сохранение индексов подмножества с целевой суммой в результат
// Tips: можно пропустить итерацию, если сумма текущего подмножества стала больше целевой суммы
for(int mask = 0; mask < num_subsets; mask++) {
int sum = 0;
std::vector<int> 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;
}
Expand Down
15 changes: 8 additions & 7 deletions src/subsets/backtracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ namespace assignment {
const auto num_elems = static_cast<int>(set.size()); // N
const int num_subsets = 1 << num_elems; // 2^N

auto subsets = std::vector<std::vector<int>>();
subsets.reserve(num_subsets);
auto subsets = std::vector<std::vector<int>>(num_subsets);

// вызов вспомогательной функции: обратите внимание на начальное значение индекса и маски
generate(set, -1, 0, subsets);
Expand All @@ -27,16 +26,18 @@ namespace assignment {

// Ограничение: рассмотрены все элементы множества
if (index == static_cast<int>(set.size()) - 1) {

// ... сохранение полученного подмножества

std::vector<int> 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
8 changes: 8 additions & 0 deletions src/subsets/bit_masking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ namespace assignment {
// 2. Внутренний цикл: проверка разрядов битовой маски и генерация подмножества, ассоциирующегося с этой маской
// Tips: для проверки разряда бита на 1 (единицу) используйте функцию is_bit_set

for(int mask = 0; mask < num_subsets; mask++) {
std::vector<int> res;
for(int pos = 0; pos < set.size(); pos++) {
if(is_bit_set(mask, pos)) res.push_back(pos);
}
subsets[mask] = res;
}

return subsets;
}

Expand Down