Compare commits

..

No commits in common. "dd2aacb284a4c381d6bcc0423dd6d710b1971cdc" and "64d4d6c71c38d2c541ee0574258427bb6f2cc24b" have entirely different histories.

4 changed files with 29 additions and 101 deletions

View File

@ -8,27 +8,11 @@
#endif #endif
#ifndef ALPHA #ifndef ALPHA
#define ALPHA 0.99 #define ALPHA 0.9999
#endif #endif
#ifndef TEMP_MIN int main()
#define TEMP_MIN 0.01
#endif
int main(int argc, char *argv[])
{ {
char flags = 0;
for(int i = 1; i < argc; i++){
if(argv[i][0] == '-'){
int j = 1;
while(argv[i][j] != '\0'){
if(argv[i][j] == 'i') flags |= SIMULATED_ANNEALING_DISABLE_SHOWITRNUM;
else if(argv[i][j] == 'c') flags |= SIMULATED_ANNEALING_DISABLE_SHOWCRATES;
j++;
}
}
}
int number_of_items = 0; int number_of_items = 0;
int capacity = 0; int capacity = 0;
std::cin >> number_of_items >> capacity; std::cin >> number_of_items >> capacity;
@ -39,7 +23,7 @@ int main(int argc, char *argv[])
} }
sa::solution act = sa::solution::simulated_annealing(capacity, items, sa::solution act = sa::solution::simulated_annealing(capacity, items,
ALPHA, TEMP, TEMP_MIN); TEMP, ALPHA);
act.print_sol(flags); act.print_sol();
} }

View File

@ -1,4 +1,4 @@
:: Uso: [set EXEC="caminho/do/executavel.exe"] && [set TEST_FOLDER=caminho/dos/casetests] && [set ARGS=ic] && run.bat :: Uso: [set EXEC="caminho/do/executavel.exe"] && [set TEST_FOLDER="caminho/dos/casetests"] && run.bat
@ECHO off @ECHO off
if not defined EXEC ( if not defined EXEC (
@ -11,9 +11,5 @@ if not defined TEST_FOLDER (
for %%g in (%TEST_FOLDER%/*) do ( for %%g in (%TEST_FOLDER%/*) do (
echo Arquivo de teste: %TEST_FOLDER%/%%g echo Arquivo de teste: %TEST_FOLDER%/%%g
if defined ARGS ( %EXEC% < %TEST_FOLDER%/%%g
%EXEC% -%ARGS% < %TEST_FOLDER%/%%g
) else (
%EXEC% < %TEST_FOLDER%/%%g
)
) )

16
sa.cpp
View File

@ -2,24 +2,22 @@
#include <cmath> #include <cmath>
auto sa::solution::simulated_annealing(int capacity, const std::vector<long long> &items, auto sa::solution::simulated_annealing(int capacity, const std::vector<long long> &items,
const double alpha, double temp, const double alpha, double temp)->sa::solution
const double temp_min)->sa::solution
{ {
sa::solution best(items, capacity); sa::solution best(items, capacity);
best.randomize();
sa::solution prev = best; sa::solution prev = best;
std::random_device rdevice; std::random_device rdevice;
std::default_random_engine eng(rdevice()); std::default_random_engine eng(rdevice());
std::uniform_real_distribution<> rand(0, 1); std::uniform_real_distribution<> rand(0, 1);
int iteration = 0; const double temp_min = 0.30;
while (temp < temp_min) {
while (temp > temp_min) { sa::solution neighbor(prev);
iteration++;
sa::solution neighbor(prev, iteration);
neighbor.setneighbor(); neighbor.setneighbor();
int diff = neighbor.fitness - prev.fitness; int diff = prev.fitness - neighbor.fitness;
if (diff <= 0 || std::exp(-diff / temp) > rand(eng)) { if (diff <= 0 || std::exp(-diff / temp) > rand(eng)) {
prev.swap(neighbor); prev.swap(neighbor);
} }
@ -27,11 +25,9 @@ auto sa::solution::simulated_annealing(int capacity, const std::vector<long long
temp *= alpha; temp *= alpha;
if (prev.fitness < best.fitness) { if (prev.fitness < best.fitness) {
std::cout << prev.fitness << ' ' << best.fitness << '\n';
best = prev; best = prev;
} }
} }
best.setiterations(iteration);
return best; return best;
} }

82
sa.hpp
View File

@ -1,14 +1,11 @@
#ifndef SIMULATED_ANNEALING_HEADER_12647_H #ifndef SIMULATED_ANNEALING_HEADER_12647_H
#define SIMULATED_ANNEALING_HEADER_12647_H #define SIMULATED_ANNEALING_HEADER_12647_H
#define SIMULATED_ANNEALING_DISABLE_SHOWCRATES 1
#define SIMULATED_ANNEALING_DISABLE_SHOWITRNUM 2
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <queue> #include <queue>
#include <random> #include <random>
#include <vector> #include <vector>
#include <set>
namespace sa { namespace sa {
@ -17,8 +14,6 @@ class solution {
std::default_random_engine gen; std::default_random_engine gen;
int capacity; int capacity;
int fitness; int fitness;
int iterations;
int iteration;
auto calculate_boxes()->int { auto calculate_boxes()->int {
int count = 1; int count = 1;
@ -48,40 +43,9 @@ class solution {
public: public:
solution() = default; 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 solution(const std::vector<long long> &items, int capacity): // Gera a solução inicial
gen(std::random_device()()), capacity(capacity), items(items), gen(std::random_device()()), capacity(capacity),
iteration(0) { fitness(calculate_boxes()) {}
std::multiset<long long> its;
for (auto i : items) {
its.insert(i);
}
this->items.resize(items.size());
size_t i = 0;
long long cap = capacity;
while (!its.empty()) {
auto itr = its.upper_bound(cap);
if (itr == its.begin()) {
cap = capacity;
cap -= *its.begin();
itr = its.begin();
} else {
itr--;
cap -= *itr;
}
this->items[i] = *itr;
its.erase(itr);
i++;
}
fitness = calculate_boxes();
}
void setneighbor() { // Gera um vizinho da solução void setneighbor() { // Gera um vizinho da solução
std::uniform_int_distribution<> dist(0, items.size() - 1); std::uniform_int_distribution<> dist(0, items.size() - 1);
@ -104,44 +68,32 @@ class solution {
std::swap(items, other.items); std::swap(items, other.items);
std::swap(capacity, other.capacity); std::swap(capacity, other.capacity);
std::swap(gen, other.gen); std::swap(gen, other.gen);
std::swap(iteration, other.iteration);
} }
void print_sol(char flags = 0) const { void print_sol() const {
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';
}
std::cout << "Número de caixas: " << fitness << '\n'; std::cout << "Número de caixas: " << fitness << '\n';
if(!(flags & SIMULATED_ANNEALING_DISABLE_SHOWCRATES)){ int box_now = 1;
int box_now = 1; long long now = 0;
long long now = 0; std::queue<long long> items_stored;
std::queue<long long> items_stored;
for (auto i : items) { for (auto i : items) {
if (now + i > capacity) { if (now + i > capacity) {
print_box(box_now, items_stored); print_box(box_now, items_stored);
box_now++; box_now++;
now = i; now = i;
} else { } else {
now += i; now += i;
}
items_stored.push(i);
} }
items_stored.push(i);
print_box(box_now, items_stored);
std::cout << '\n';
} }
}
void setiterations(int itr) { print_box(box_now, items_stored);
iterations = itr; std::cout << '\n';
} }
static auto simulated_annealing(int capacity, const std::vector<long long> &items, static auto simulated_annealing(int capacity, const std::vector<long long> &items,
double alpha, double temp, double alpha, double temp)->solution;
double temp_min)->solution;
}; };
} // namespace sa } // namespace sa