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 3 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-109

**Фамилия и Имя**: Иванов Иван
**Фамилия и Имя**: Краденова Дарья

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

Expand Down
15 changes: 8 additions & 7 deletions src/bits.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
#include "assignment/bits.hpp"

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

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 All @@ -34,14 +35,14 @@ namespace assignment {

std::vector<int> masked_elems;

for (int pos = 0; pos < static_cast<int>(elems.size()); pos++) {
for (int idx = 0; idx < static_cast<int>(elems.size()); idx++) {

if (is_bit_set(mask, pos)) {
masked_elems.push_back(elems[pos]);
if (is_bit_set(mask, idx)) {
masked_elems.push_back(elems[idx]);
}
}

return masked_elems;
}

} // namespace assignment
}
26 changes: 10 additions & 16 deletions src/knapsack/backtracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,9 @@ namespace assignment {
std::vector<int> KnapsackBacktracking::solve(const Profits& profits, const Weights& weights, int capacity) const {
assert(profits.size() == weights.size() && capacity > 0);

// результат: наибольшая "польза"
int best_profit = 0;
int best_profit_mask = 0;

// вызов вспомогательного метода: обратите внимание на входные аргументы
// и на то, как они передаются (по значению или ссылке, почему так?)
solve(profits, weights, capacity, -1, 0, 0, 0, best_profit, best_profit_mask);

return mask2indices(profits, best_profit_mask);
Expand All @@ -23,25 +20,22 @@ 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;
}
if (index == static_cast<int>(profits.size())) {return;}

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

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



}

// рассматриваем следующий элемент
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
29 changes: 16 additions & 13 deletions src/knapsack/bit_masking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,53 @@
#include <cassert> // assert
#include <numeric> // accumulate

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

namespace assignment {

// вспомогательная функция подсчета суммы элементов массива
static int sum_helper(const std::vector<int>& arr) {
return std::accumulate(arr.begin(), arr.end(), 0);
}

std::vector<int> KnapsackBitMasking::solve(const Profits& profits, const Weights& weights, int capacity) const {
assert(profits.size() == weights.size() && capacity > 0);

const auto num_elems = static_cast<int>(profits.size()); // N
const int num_subsets = 1 << num_elems; // 2^N
const auto num_elems = static_cast<int>(profits.size());
const int num_subsets = 1 << num_elems;

// результат: лучшая найденная "польза" (+ маска для получения элементов)
int best_profit = 0;
int best_profit_mask = 0;

// Tip: What if the weight is equal to the max weight? Can we stop the process?

// 0..00, 0..01, 0..10, 0..11, ..., 1..11
if(capacity == sum_helper(weights)){
return mask2indices(profits,num_subsets - 1);
}
for (int mask = 0; mask < num_subsets; mask++) { // 2^N

// массив из весов рассматриваемых элементов
const auto masked_weights = mask2elems(weights, mask);

// вычисление общего веса рассматриваемых элементов
const int curr_weight = sum_helper(masked_weights);

// ... обработка случая превышения емкости рюкзака
if(curr_weight > capacity) {
continue;
}

// массив из "пользы" рассматриваемых элементов
const auto masked_profits = mask2elems(profits, mask);

// вычисление общей "пользы" рассматриваемых элементов
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
8 changes: 6 additions & 2 deletions src/subset_sum/backtracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ namespace assignment {
}

// Ограничение 1: текущая сумма должна быть меньше целевой
if (true /* ... */) {
if (sum > target_sum) {
// если превысили целевую сумму, то сделать ее меньше уже не получится (все элементы множества положительные)
return;
}

// Ограничение 2: "остаточная сумма" + "текущая сумма" должны быть больше или равны "целевой сумме"
if (true /* ... */) {
if ((residual + sum) < target_sum) {
// сумму невозможно будет набрать с оставшимися элементами множества
return;
}
Expand All @@ -47,6 +47,8 @@ namespace assignment {
if (sum == target_sum) {
// ... сохранение в результат
// ... нужно ли в этой ветке рекурсии рассматривать следующие элементы?
indices.push_back(mask2indices(set,mask));
return;
}

// рассматриваем следующий элемент
Expand All @@ -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
13 changes: 13 additions & 0 deletions src/subset_sum/bit_masking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@ namespace assignment {
// 3. Подсчет суммы текущего подмножества, сохранение индексов подмножества с целевой суммой в результат
// Tips: можно пропустить итерацию, если сумма текущего подмножества стала больше целевой суммы

for(int mask = 0; mask < num_subsets; mask++) {
std::vector<int> subset = mask2indices(set, mask);
int curr_sum = 0;
for (int idx = 0; idx < subset.size(); idx++) {
curr_sum += set[static_cast<unsigned long>(subset[idx])];
if (curr_sum > target_sum) {
break;
}
}
if (curr_sum == target_sum) {
indices.push_back(subset);
}
}
return indices;
}

Expand Down
20 changes: 10 additions & 10 deletions src/subsets/backtracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@

#include <cassert> // assert

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

namespace assignment {

std::vector<std::vector<int>> SubsetsBacktracking::generate(const std::vector<int>& set) const {
assert(set.size() <= 16);

const auto num_elems = static_cast<int>(set.size()); // N
const int num_subsets = 1 << num_elems; // 2^N
const auto num_elems = static_cast<int>(set.size());
const int num_subsets = 1 << num_elems;

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

// вызов вспомогательной функции: обратите внимание на начальное значение индекса и маски
generate(set, -1, 0, subsets);

return subsets;
Expand All @@ -25,18 +24,19 @@ namespace assignment {
std::vector<std::vector<int>>& subsets) const {
assert(mask >= 0 && index >= -1);

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

// ... сохранение полученного подмножества
subsets.push_back(mask2indices(set,mask));

return; // возвращаемся по дереву рекурсии
return;
}

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

// здесь должны быть рекурсивные вызовы ...
// включаем или не включаем элемент с текущим индексом в подмножество (используя битовую маску)

generate(set,index,mask,subsets);

generate(set,index, set_bit(mask,index),subsets);
}

} // namespace assignment
18 changes: 11 additions & 7 deletions src/subsets/bit_masking.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "assignment/subsets/bit_masking.hpp"

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

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

namespace assignment {

Expand All @@ -12,14 +12,18 @@ 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>>(num_subsets);

// 1. Внешний цикл: пробегаемся по всем битовым маскам от 0..00 до 1..11
// 2. Внутренний цикл: проверка разрядов битовой маски и генерация подмножества, ассоциирующегося с этой маской
// Tips: для проверки разряда бита на 1 (единицу) используйте функцию is_bit_set
for(int mask = 0; mask < num_subsets; mask++) {
std::vector<int> curr_subset;
for (int position = 0; position < num_elems; position++) {
if (is_bit_set(mask, position)) {
subsets[mask].push_back(position);
}

}
}
return subsets;
}

} // namespace assignment
}