Compare commits
9 Commits
64d4d6c71c
...
dd2aacb284
| Author | SHA1 | Date | |
|---|---|---|---|
| dd2aacb284 | |||
| 19ece6f700 | |||
| 7aad87810f | |||
| 65aed86783 | |||
| 01d9f25220 | |||
| 93d580a299 | |||
| 70f0125d13 | |||
| 859b34308c | |||
| d8086caa18 |
24
main.cpp
24
main.cpp
@ -8,11 +8,27 @@
|
||||
#endif
|
||||
|
||||
#ifndef ALPHA
|
||||
#define ALPHA 0.9999
|
||||
#define ALPHA 0.99
|
||||
#endif
|
||||
|
||||
int main()
|
||||
#ifndef TEMP_MIN
|
||||
#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 capacity = 0;
|
||||
std::cin >> number_of_items >> capacity;
|
||||
@ -23,7 +39,7 @@ int main()
|
||||
}
|
||||
|
||||
sa::solution act = sa::solution::simulated_annealing(capacity, items,
|
||||
TEMP, ALPHA);
|
||||
ALPHA, TEMP, TEMP_MIN);
|
||||
|
||||
act.print_sol();
|
||||
act.print_sol(flags);
|
||||
}
|
||||
|
||||
8
run.bat
8
run.bat
@ -1,4 +1,4 @@
|
||||
:: Uso: [set EXEC="caminho/do/executavel.exe"] && [set TEST_FOLDER="caminho/dos/casetests"] && run.bat
|
||||
:: Uso: [set EXEC="caminho/do/executavel.exe"] && [set TEST_FOLDER=caminho/dos/casetests] && [set ARGS=ic] && run.bat
|
||||
@ECHO off
|
||||
|
||||
if not defined EXEC (
|
||||
@ -11,5 +11,9 @@ if not defined TEST_FOLDER (
|
||||
|
||||
for %%g in (%TEST_FOLDER%/*) do (
|
||||
echo Arquivo de teste: %TEST_FOLDER%/%%g
|
||||
%EXEC% < %TEST_FOLDER%/%%g
|
||||
if defined ARGS (
|
||||
%EXEC% -%ARGS% < %TEST_FOLDER%/%%g
|
||||
) else (
|
||||
%EXEC% < %TEST_FOLDER%/%%g
|
||||
)
|
||||
)
|
||||
16
sa.cpp
16
sa.cpp
@ -2,22 +2,24 @@
|
||||
#include <cmath>
|
||||
|
||||
auto sa::solution::simulated_annealing(int capacity, const std::vector<long long> &items,
|
||||
const double alpha, double temp)->sa::solution
|
||||
const double alpha, double temp,
|
||||
const double temp_min)->sa::solution
|
||||
{
|
||||
sa::solution best(items, capacity);
|
||||
best.randomize();
|
||||
|
||||
sa::solution prev = best;
|
||||
std::random_device rdevice;
|
||||
std::default_random_engine eng(rdevice());
|
||||
std::uniform_real_distribution<> rand(0, 1);
|
||||
|
||||
const double temp_min = 0.30;
|
||||
while (temp < temp_min) {
|
||||
sa::solution neighbor(prev);
|
||||
int iteration = 0;
|
||||
|
||||
while (temp > temp_min) {
|
||||
iteration++;
|
||||
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);
|
||||
}
|
||||
@ -25,9 +27,11 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
best.setiterations(iteration);
|
||||
return best;
|
||||
}
|
||||
|
||||
84
sa.hpp
84
sa.hpp
@ -1,11 +1,14 @@
|
||||
#ifndef 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 <iostream>
|
||||
#include <queue>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
namespace sa {
|
||||
|
||||
@ -14,6 +17,8 @@ class solution {
|
||||
std::default_random_engine gen;
|
||||
int capacity;
|
||||
int fitness;
|
||||
int iterations;
|
||||
int iteration;
|
||||
|
||||
auto calculate_boxes()->int {
|
||||
int count = 1;
|
||||
@ -43,9 +48,40 @@ class solution {
|
||||
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
|
||||
items(items), gen(std::random_device()()), capacity(capacity),
|
||||
fitness(calculate_boxes()) {}
|
||||
gen(std::random_device()()), capacity(capacity),
|
||||
iteration(0) {
|
||||
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
|
||||
std::uniform_int_distribution<> dist(0, items.size() - 1);
|
||||
@ -68,32 +104,44 @@ class solution {
|
||||
std::swap(items, other.items);
|
||||
std::swap(capacity, other.capacity);
|
||||
std::swap(gen, other.gen);
|
||||
std::swap(iteration, other.iteration);
|
||||
}
|
||||
|
||||
void print_sol() const {
|
||||
void print_sol(char flags = 0) 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';
|
||||
|
||||
int box_now = 1;
|
||||
long long now = 0;
|
||||
std::queue<long long> items_stored;
|
||||
if(!(flags & SIMULATED_ANNEALING_DISABLE_SHOWCRATES)){
|
||||
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;
|
||||
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);
|
||||
}
|
||||
items_stored.push(i);
|
||||
}
|
||||
|
||||
print_box(box_now, items_stored);
|
||||
std::cout << '\n';
|
||||
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)->solution;
|
||||
double alpha, double temp,
|
||||
double temp_min)->solution;
|
||||
};
|
||||
|
||||
} // namespace sa
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user