Somehow this works better than the metaheuristic?

This commit is contained in:
Segcolt 2024-10-12 21:18:15 -03:00
parent 70f0125d13
commit 01d9f25220
2 changed files with 29 additions and 4 deletions

4
sa.cpp
View File

@ -6,7 +6,6 @@ auto sa::solution::simulated_annealing(int capacity, const std::vector<long long
const double temp_min)->sa::solution
{
sa::solution best(items, capacity);
best.randomize();
sa::solution prev = best;
std::random_device rdevice;
@ -20,7 +19,7 @@ auto sa::solution::simulated_annealing(int capacity, const std::vector<long long
sa::solution neighbor(prev, iteration);
neighbor.setneighbor();
int diff = prev.fitness - neighbor.fitness;
int diff = neighbor.fitness - prev.fitness;
if (diff <= 0 || std::exp(-diff / temp) > rand(eng)) {
prev.swap(neighbor);
}
@ -28,6 +27,7 @@ auto sa::solution::simulated_annealing(int capacity, const std::vector<long long
temp *= alpha;
if (prev.fitness < best.fitness) {
std::cout << prev.fitness << ' ' << best.fitness << '\n';
best = prev;
}
}

29
sa.hpp
View File

@ -6,6 +6,7 @@
#include <queue>
#include <random>
#include <vector>
#include <set>
namespace sa {
@ -50,8 +51,32 @@ class solution {
iteration(itr) {}
solution(const std::vector<long long> &items, int capacity): // Gera a solução inicial
items(items), gen(std::random_device()()), capacity(capacity),
fitness(calculate_boxes()), iteration(0) {}
gen(std::random_device()()), capacity(capacity),
iteration(0) {
std::multiset<long long> its;
for (auto i : items) {
its.insert(i);
}
long long cap = capacity;
while (!its.empty()) {
auto itr = its.upper_bound(cap);
if (itr == its.begin()) {
cap = capacity;
cap -= *its.begin();
this->items.push_back(*its.begin());
its.erase(its.begin());
continue;
}
itr--;
cap -= *itr;
this->items.push_back(*itr);
its.erase(itr);
}
fitness = calculate_boxes();
}
void setneighbor() { // Gera um vizinho da solução
std::uniform_int_distribution<> dist(0, items.size() - 1);