From d3b3e682dbf60a428aa3c5c617b8feba2e24e67d Mon Sep 17 00:00:00 2001 From: Segcolt <9hmbzr275@mozmail.com> Date: Mon, 14 Oct 2024 00:03:11 -0300 Subject: [PATCH] Raise temperature and do some more changes --- main.cpp | 4 +- sa.hpp | 131 +++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 86 insertions(+), 49 deletions(-) diff --git a/main.cpp b/main.cpp index ec12c68..1989266 100644 --- a/main.cpp +++ b/main.cpp @@ -4,11 +4,11 @@ #include "sa.hpp" #ifndef TEMP -#define TEMP 1000000 +#define TEMP 1000 #endif #ifndef ALPHA -#define ALPHA 0.99 +#define ALPHA 0.999 #endif #ifndef TEMP_MIN diff --git a/sa.hpp b/sa.hpp index b9f20e7..bec18ac 100644 --- a/sa.hpp +++ b/sa.hpp @@ -8,12 +8,16 @@ #include #include #include +#include #include +#include namespace sa { +using content = std::priority_queue, std::greater<>>; + class box { - std::multiset items; + content items; long long fullness{}; friend void swap(box &one, box &two) { @@ -23,56 +27,62 @@ class box { swap(one.fullness, two.fullness); } + void pop() { + fullness -= items.top(); + items.pop(); + } + public: box() = default; - box(const std::multiset &multiset, long long fullness): - items(multiset), fullness(fullness) {} + box(const content &items, long long fullness): + items(items), fullness(fullness) {} void add_item(long long item) { fullness += item; - items.insert(item); + items.push(item); } void clear() { - items.clear(); + while (!items.empty()) { + items.pop(); + } fullness = 0; } - void pop() { - fullness -= *items.begin(); - items.erase(items.begin()); + auto swappable10(box &other, int capacity) -> bool { + return items.top() + other.fullness <= capacity; } - auto swap10(box &other, int capacity) -> bool { - if (*items.begin() + other.fullness > capacity) { - return false; - } - other.add_item(*items.begin()); - pop(); return true; } + void swap10(box &other) { + other.add_item(items.top()); + pop(); + } - auto swap11(box &other, int capacity) -> bool { - long long choice1 = *items.begin(); - long long choice2 = *other.items.begin(); + auto swappable11(box &other, int capacity) -> bool { + long long choice1 = items.top(); + long long choice2 = other.items.top(); + return choice1 + other.fullness - choice2 <= capacity && + choice2 + fullness - choice1 <= capacity; + } - if (choice1 + other.fullness - choice2 > capacity || - choice2 + fullness - choice1 > capacity) { - return false; - } + void swap11(box &other) { + long long choice1 = items.top(); + long long choice2 = other.items.top(); pop(); other.pop(); add_item(choice2); other.add_item(choice1); - - return true; } - void print(int ind) const { + void print(int ind) { std::cout << "Caixa " << ind << ":"; - for (auto item : items) { - std::cout << ' ' << item; + content tmp; + while (!items.empty()) { + std::cout << ' ' << items.top(); + items.pop(); } std::cout << '\n'; } @@ -101,6 +111,31 @@ class solution { swap(one.iteration, two.iteration); } + void random_swap(int choice, std::vector &sequence10, std::vector &sequence11) { + typedef void (box::*swap)(box&); + swap swaps[2] = { + &box::swap10, + &box::swap11 + }; + std::vector* sequences[2] = { + &sequence10, + &sequence11 + }; + + std::uniform_real_distribution<> rand(0, 1); + int now = rand(gen) > 0.3 ? 0 : 1; + + if (sequences[now]->empty()) { + now ^= 1; + if (sequences[now]->empty()) { + return; + } + } + + std::uniform_int_distribution<> dist(0, (int)sequences[now]->size() - 1); + (boxes[choice].*swaps[now])(boxes[(*sequences[now])[dist(gen)]]); + } + public: solution() = default; @@ -142,33 +177,35 @@ class solution { } void setneighbor() { // Gera um vizinho da solução - std::uniform_int_distribution<> dist(0, (int)boxes.size() - 1); + int choice = std::uniform_int_distribution<>(0, (int)boxes.size() - 1)(gen); + std::vector sequence10; + std::vector sequence11; + + sequence10.reserve(boxes.size()); + sequence11.reserve(boxes.size()); - int choice = dist(gen); - std::vector sequence(boxes.size() - 1); for (size_t i = 0; i < choice; i++) { - sequence[i] = i; + if (boxes[choice].swappable10(boxes[i], capacity)) { + sequence10.push_back((int)i); + } + if (boxes[choice].swappable11(boxes[i], capacity)) { + sequence11.push_back((int)i); + } } for (size_t i = choice + 1; i < boxes.size(); i++) { - sequence[i - 1] = i; - } - - shuffle(sequence.begin(), sequence.end(), gen); - - for (auto ind : sequence) { - if (boxes[choice].swap10(boxes[ind], capacity)) { - if (boxes[choice].empty()) { - boxes.erase(boxes.begin() + choice); - } - fitness = (int)boxes.size(); - return; + if (boxes[choice].swappable10(boxes[i], capacity)) { + sequence10.push_back((int)i); + } + if (boxes[choice].swappable11(boxes[i], capacity)) { + sequence11.push_back((int)i); } } - for (auto ind : sequence) { - if (boxes[choice].swap11(boxes[ind], capacity)) { - return; - } + random_swap(choice, sequence10, sequence11); + if (boxes[choice].empty()) { + swap(boxes[choice], boxes[boxes.size() - 1]); + boxes.pop_back(); + fitness = (int)boxes.size(); } } @@ -176,7 +213,7 @@ class solution { std::shuffle(boxes.begin(), boxes.end(), gen); } - void print_sol(char flags = 0) const { + void print_sol(char flags = 0) { if(!(flags & SIMULATED_ANNEALING_DISABLE_SHOWITRNUM)){ std::cout << "Iteração da solução: " << iteration << '\n'; std::cout << "Número de iterações calculadas: " << iterations << '\n';