Compare commits
5 Commits
52327fd62e
...
f536ca37fe
| Author | SHA1 | Date | |
|---|---|---|---|
| f536ca37fe | |||
| e6d4434e69 | |||
| f538278232 | |||
| b791a80128 | |||
| ea8be549a2 |
29
main.cpp
Normal file
29
main.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "sa.hpp"
|
||||||
|
|
||||||
|
#ifndef TEMP
|
||||||
|
#define TEMP 1000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ALPHA
|
||||||
|
#define ALPHA 0.99
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int number_of_items = 0;
|
||||||
|
int capacity = 0;
|
||||||
|
std::cin >> number_of_items >> capacity;
|
||||||
|
|
||||||
|
std::vector<long long> items(number_of_items);
|
||||||
|
for (auto &i : items) {
|
||||||
|
std::cin >> i;
|
||||||
|
}
|
||||||
|
|
||||||
|
sa::solution act = sa::solution::simulated_annealing(capacity, items,
|
||||||
|
TEMP, ALPHA);
|
||||||
|
|
||||||
|
act.print_sol();
|
||||||
|
}
|
||||||
7
run.sh
Executable file
7
run.sh
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
IFS=$'\n'
|
||||||
|
|
||||||
|
for file in $(find test -type f); do
|
||||||
|
build/main.out < $file
|
||||||
|
done
|
||||||
33
sa.cpp
Normal file
33
sa.cpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#include "sa.hpp"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
auto sa::solution::simulated_annealing(int capacity, const std::vector<long long> &items,
|
||||||
|
const double alpha, double temp)->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);
|
||||||
|
neighbor.setneighbor();
|
||||||
|
|
||||||
|
int diff = prev.fitness - neighbor.fitness;
|
||||||
|
if (diff <= 0 || std::exp(-diff / temp) > rand(eng)) {
|
||||||
|
prev.swap(neighbor);
|
||||||
|
}
|
||||||
|
|
||||||
|
temp *= alpha;
|
||||||
|
|
||||||
|
if (prev.fitness < best.fitness) {
|
||||||
|
best = prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return best;
|
||||||
|
}
|
||||||
52
sa.hpp
52
sa.hpp
@ -1,9 +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
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <queue>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace sa {
|
namespace sa {
|
||||||
|
|
||||||
@ -14,7 +16,7 @@ class solution {
|
|||||||
int fitness;
|
int fitness;
|
||||||
|
|
||||||
auto calculate_boxes()->int {
|
auto calculate_boxes()->int {
|
||||||
int count = 0;
|
int count = 1;
|
||||||
long long now = 0;
|
long long now = 0;
|
||||||
|
|
||||||
for (auto i : items) {
|
for (auto i : items) {
|
||||||
@ -29,16 +31,23 @@ class solution {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
static void print_box(int box, std::queue<long long> &stored) {
|
||||||
solution(const std::vector<long long> &items, int capacity): // Gera a solução inicial
|
std::cout << "Caixa " << box << ":";
|
||||||
items(items), capacity(capacity), fitness(calculate_boxes()) {
|
while (!stored.empty()) {
|
||||||
std::random_device rdevice;
|
std::cout << ' ' << stored.front();
|
||||||
gen.seed(rdevice());
|
stored.pop();
|
||||||
}
|
}
|
||||||
|
std::cout << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
solution(const solution &sol):
|
public:
|
||||||
items(sol.items), gen(sol.gen), capacity(sol.capacity) { // Gera um vizinho da solução
|
solution() = default;
|
||||||
|
|
||||||
|
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()) {}
|
||||||
|
|
||||||
|
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);
|
||||||
int first = dist(gen);
|
int first = dist(gen);
|
||||||
int second = 0;
|
int second = 0;
|
||||||
@ -60,6 +69,31 @@ class solution {
|
|||||||
std::swap(capacity, other.capacity);
|
std::swap(capacity, other.capacity);
|
||||||
std::swap(gen, other.gen);
|
std::swap(gen, other.gen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_sol() const {
|
||||||
|
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';
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto simulated_annealing(int capacity, const std::vector<long long> &items,
|
||||||
|
double alpha, double temp)->solution;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sa
|
} // namespace sa
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user