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
|
#endif
|
||||||
|
|
||||||
#ifndef ALPHA
|
#ifndef ALPHA
|
||||||
#define ALPHA 0.9999
|
#define ALPHA 0.99
|
||||||
#endif
|
#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 number_of_items = 0;
|
||||||
int capacity = 0;
|
int capacity = 0;
|
||||||
std::cin >> number_of_items >> capacity;
|
std::cin >> number_of_items >> capacity;
|
||||||
@ -23,7 +39,7 @@ int main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
sa::solution act = sa::solution::simulated_annealing(capacity, items,
|
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
|
@ECHO off
|
||||||
|
|
||||||
if not defined EXEC (
|
if not defined EXEC (
|
||||||
@ -11,5 +11,9 @@ 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
|
||||||
%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>
|
#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)->sa::solution
|
const double alpha, double temp,
|
||||||
|
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);
|
||||||
|
|
||||||
const double temp_min = 0.30;
|
int iteration = 0;
|
||||||
while (temp < temp_min) {
|
|
||||||
sa::solution neighbor(prev);
|
while (temp > temp_min) {
|
||||||
|
iteration++;
|
||||||
|
sa::solution neighbor(prev, iteration);
|
||||||
neighbor.setneighbor();
|
neighbor.setneighbor();
|
||||||
|
|
||||||
int diff = prev.fitness - neighbor.fitness;
|
int diff = neighbor.fitness - prev.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);
|
||||||
}
|
}
|
||||||
@ -25,9 +27,11 @@ 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;
|
||||||
}
|
}
|
||||||
|
|||||||
84
sa.hpp
84
sa.hpp
@ -1,11 +1,14 @@
|
|||||||
#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 {
|
||||||
|
|
||||||
@ -14,6 +17,8 @@ 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;
|
||||||
@ -43,9 +48,40 @@ 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
|
||||||
items(items), gen(std::random_device()()), capacity(capacity),
|
gen(std::random_device()()), capacity(capacity),
|
||||||
fitness(calculate_boxes()) {}
|
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
|
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);
|
||||||
@ -68,32 +104,44 @@ 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() 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';
|
std::cout << "Número de caixas: " << fitness << '\n';
|
||||||
|
|
||||||
int box_now = 1;
|
if(!(flags & SIMULATED_ANNEALING_DISABLE_SHOWCRATES)){
|
||||||
long long now = 0;
|
int box_now = 1;
|
||||||
std::queue<long long> items_stored;
|
long long now = 0;
|
||||||
|
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);
|
print_box(box_now, items_stored);
|
||||||
std::cout << '\n';
|
std::cout << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setiterations(int itr) {
|
||||||
|
iterations = itr;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)->solution;
|
double alpha, double temp,
|
||||||
|
double temp_min)->solution;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sa
|
} // namespace sa
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user