141 lines
3.2 KiB
C++

#ifndef SIMULATED_ANNEALING_HEADER_12647_H
#define SIMULATED_ANNEALING_HEADER_12647_H
#include <algorithm>
#include <iostream>
#include <queue>
#include <random>
#include <vector>
#include <set>
namespace sa {
class solution {
std::vector<long long> items;
std::default_random_engine gen;
int capacity;
int fitness;
int iterations;
int iteration;
auto calculate_boxes()->int {
int count = 1;
long long now = 0;
for (auto i : items) {
if (now + i > capacity) {
count++;
now = i;
continue;
}
now += i;
}
return count;
}
static void print_box(int box, std::queue<long long> &stored) {
std::cout << "Caixa " << box << ":";
while (!stored.empty()) {
std::cout << ' ' << stored.front();
stored.pop();
}
std::cout << '\n';
}
public:
solution() = default;
solution(const solution &other, int itr): items(other.items), gen(other.gen),
capacity(other.capacity), fitness(other.fitness),
iteration(itr) {}
solution(const std::vector<long long> &items, int capacity): // Gera a solução inicial
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);
int first = dist(gen);
int second = 0;
while ((second = dist(gen)) == first) {}
std::swap(items[first], items[second]);
fitness = calculate_boxes();
}
void randomize() {
std::shuffle(items.begin(), items.end(), gen);
fitness = calculate_boxes();
}
void swap(solution &other) {
std::swap(fitness, other.fitness);
std::swap(items, other.items);
std::swap(capacity, other.capacity);
std::swap(gen, other.gen);
std::swap(iteration, other.iteration);
}
void print_sol() const {
std::cout << "Iteração da solução: " << iteration << '\n';
std::cout << "Número de iterações calculadas: " << iterations << '\n';
std::cout << "Número de caixas: " << fitness << '\n';
int box_now = 1;
long long now = 0;
std::queue<long long> items_stored;
for (auto i : items) {
if (now + i > capacity) {
print_box(box_now, items_stored);
box_now++;
now = i;
} else {
now += i;
}
items_stored.push(i);
}
print_box(box_now, items_stored);
std::cout << '\n';
}
void setiterations(int itr) {
iterations = itr;
}
static auto simulated_annealing(int capacity, const std::vector<long long> &items,
double alpha, double temp,
double temp_min)->solution;
};
} // namespace sa
#endif