Compare commits

...

8 Commits

6263 changed files with 2997635 additions and 34 deletions

Binary file not shown.

32
getstats.py Normal file
View File

@ -0,0 +1,32 @@
arqname = input("Escreva o nome do arquivo de saída (Deve estar no formato de saída dos scripts, com arquivo de resposta ótima, e com os argumentos -i e -c)\n> ")
arq = open(arqname, "r", -1, "UTF-8")
caseqtd = 0
accuracy = 1.0
timetot = 0
largesterr = 0
while True:
arq.readline()
l2 = arq.readline().split(" ")
l3 = arq.readline().split(" ")
arq.readline()
l5 = arq.readline().split(" ")
if len(l5) < 5: break
progres = int(l2[len(l2)-1])
optires = int(l3[len(l3)-1])
extime = int(l5[len(l5)-2])
caseqtd += 1
timetot += extime
diff = progres-optires
if diff > largesterr: largesterr = diff
accuracy = (accuracy + 1 - (progres-optires)/optires)/2.0
print("----------Statistics----------")
print("Cases parsed...........: %d" %caseqtd)
print("Average execution time.: %f" %(timetot/caseqtd))
print("Average answer accuracy: %f%%" %(accuracy*100.0))
print("Largest error..........: %d" %largesterr)

View File

@ -12,7 +12,7 @@
#endif
#ifndef TEMP_MIN
#define TEMP_MIN 0.01
#define TEMP_MIN 10
#endif
int main(int argc, char *argv[])

4
random.cpp Normal file
View File

@ -0,0 +1,4 @@
#include "random.hpp"
std::random_device rdevice;
std::mt19937_64 rng::rng(rdevice());

24
random.hpp Normal file
View File

@ -0,0 +1,24 @@
#ifndef RANDOM_HPP_RANDOMNESS_WHATEVER_HEADER_238947837827_H
#define RANDOM_HPP_RANDOMNESS_WHATEVER_HEADER_238947837827_H
#include <random>
namespace rng {
extern std::mt19937_64 rng;
template<long long start, long long end>
auto random_int() -> int
{
static std::uniform_int_distribution<> rint(start, end);
return rint(rng);
}
template<int start, int end>
auto random_double() -> double
{
static std::uniform_real_distribution<> rdouble(start, end);
return rdouble(rng);
}
} // namespace rng
#endif

View File

@ -1,13 +1,13 @@
:: Uso: [set EXEC="caminho\do\executavel.exe"]&&[set TEST_FOLDER=caminho\dos\casetests]&&[set ARGS=ic]&&[set SOLUTIONS_FILE=arquivo\de\solucoes.txt]&&run.bat
:: Uso: [set EXEC="caminho\do\executavel.exe"]&&[set TEST_FOLDER=caminho\dos\casetests]&&[set ARGS=ic]&&[set SOLUTIONS_FILE=arquivo\de\solucoes.txt]&&run.bat [> arq\de\saida.txt]
@ECHO off
setlocal enabledelayedexpansion
if not defined EXEC (
set EXEC="build\solucao.exe"
set EXEC="build\main.exe"
)
if not defined TEST_FOLDER (
set TEST_FOLDER=Teste\Casos
set TEST_FOLDER=test\reduced
)
if defined ARGS (

20
run.sh
View File

@ -15,19 +15,23 @@ if [[ -z $SOLUTIONS_FILE ]]; then
fi
declare -A solutions
while read line; do
solutions[$(awk '{print $1}' <<< "$line")]=$(awk '{print $2}' <<< "$line")
done < "$SOLUTIONS_FILE"
if [[ -f "$SOLUTIONS_FILE" ]]; then
while read line; do
solutions[$(awk '{print $1}' <<< "$line")]=$(awk '{print $2}' <<< "$line")
done < "$SOLUTIONS_FILE"
fi
for file in $(find "$TEST_FOLDER" -type f); do
echo "Arquivo de teste: $file"
res=$("$EXEC" -i -c < "$file" | awk '{print $4}')
optimal=${solutions[$(basename "$file")]}
echo "Resultado do programa: ${res}"
echo "Resultado ótimo: ${optimal}"
if [[ $res = $optimal ]]; then
echo "Resultado ótimo!"
else
echo "Diferença de $(bc <<< "${res} - ${optimal}")"
if [[ ! -z $optimal ]]; then
echo "Resultado ótimo: ${optimal}"
if [[ $res = $optimal ]]; then
echo "Resultado ótimo!"
else
echo "Diferença de $(bc <<< "${res} - ${optimal}")"
fi
fi
done

6
sa.cpp
View File

@ -6,11 +6,7 @@ auto sa::solution::simulated_annealing(int capacity, const std::vector<long long
const double temp_min)->sa::solution
{
sa::solution best(items, capacity);
sa::solution prev = best;
std::random_device rdevice;
std::default_random_engine eng(rdevice());
std::uniform_real_distribution<> rand(0, 1);
int iteration = 0;
@ -20,7 +16,7 @@ auto sa::solution::simulated_annealing(int capacity, const std::vector<long long
neighbor.setneighbor();
long long diff = neighbor.fitness - prev.fitness;
if (diff < 0 || rand(eng) / temp < 0.8) {
if (diff < 0 || rng::random_double<0, 1>() / temp < 0.8) {
swap(prev, neighbor);
}

28
sa.hpp
View File

@ -6,11 +6,13 @@
#include <algorithm>
#include <iostream>
#include <queue>
#include <random>
#include <set>
#include <utility>
#include <vector>
#include <queue>
#include "random.hpp"
namespace sa {
@ -63,7 +65,8 @@ class box {
auto swappable11(box &other, int capacity) -> bool {
long long choice1 = items.top();
long long choice2 = other.items.top();
return choice1 + other.fullness - choice2 <= capacity &&
return choice1 != choice2 &&
choice1 + other.fullness - choice2 <= capacity &&
choice2 + fullness - choice1 <= capacity;
}
@ -94,7 +97,6 @@ class box {
class solution {
std::vector<box> boxes;
std::mt19937_64 gen;
long long fitness;
int capacity;
int iterations;
@ -104,7 +106,6 @@ class solution {
using std::swap;
swap(one.boxes, two.boxes);
swap(one.gen, two.gen);
swap(one.capacity, two.capacity);
swap(one.fitness, two.fitness);
swap(one.iterations, two.iterations);
@ -122,8 +123,7 @@ class solution {
&sequence11
};
std::uniform_real_distribution<> rand(0, 1);
int now = rand(gen) > 0.3 ? 0 : 1;
int now = rng::random_double<0, 1>() > 0.3 ? 0 : 1;
if (sequences[now]->empty()) {
now ^= 1;
@ -133,19 +133,17 @@ class solution {
}
std::uniform_int_distribution<> dist(0, (int)sequences[now]->size() - 1);
(boxes[choice].*swaps[now])(boxes[(*sequences[now])[dist(gen)]]);
(boxes[choice].*swaps[now])(boxes[(*sequences[now])[dist(rng::rng)]]);
}
public:
solution() = default;
solution(const solution &other, int itr): boxes(other.boxes), gen(other.gen),
fitness(other.fitness), capacity(other.capacity),
iteration(itr) {}
solution(const solution &other, int itr): boxes(other.boxes), fitness(other.fitness),
capacity(other.capacity), iteration(itr) {}
solution(const std::vector<long long> &items, int capacity): // Gera a solução inicial
gen(std::random_device()()), capacity(capacity),
iteration(0) {
capacity(capacity), iteration(0) {
std::multiset<long long> its;
for (auto i : items) {
its.insert(i);
@ -177,7 +175,7 @@ class solution {
}
void setneighbor() { // Gera um vizinho da solução
int choice = std::uniform_int_distribution<>(0, (int)boxes.size() - 1)(gen);
int choice = std::uniform_int_distribution<>(0, (int)boxes.size() - 1)(rng::rng);
std::vector<int> sequence10;
std::vector<int> sequence11;
@ -209,10 +207,6 @@ class solution {
}
}
void randomize() {
std::shuffle(boxes.begin(), boxes.end(), gen);
}
void print_sol(char flags = 0) {
if(!(flags & SIMULATED_ANNEALING_DISABLE_SHOWITRNUM)){
std::cout << "Iteração da solução: " << iteration << '\n';

45
src/main.cpp Normal file
View File

@ -0,0 +1,45 @@
#include <iostream>
#include <vector>
#include "sa.hpp"
#ifndef TEMP
#define TEMP 1000
#endif
#ifndef ALPHA
#define ALPHA 0.999
#endif
#ifndef TEMP_MIN
#define TEMP_MIN 10
#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;
std::vector<long long> items(number_of_items);
for (auto &i : items) {
std::cin >> i;
}
sa::solution act = sa::solution::simulated_annealing(capacity, items,
ALPHA, TEMP, TEMP_MIN);
act.print_sol(flags);
}

4
src/random.cpp Normal file
View File

@ -0,0 +1,4 @@
#include "random.hpp"
std::random_device rdevice;
std::mt19937_64 rng::rng(rdevice());

24
src/random.hpp Normal file
View File

@ -0,0 +1,24 @@
#ifndef RANDOM_HPP_RANDOMNESS_WHATEVER_HEADER_238947837827_H
#define RANDOM_HPP_RANDOMNESS_WHATEVER_HEADER_238947837827_H
#include <random>
namespace rng {
extern std::mt19937_64 rng;
template<long long start, long long end>
auto random_int() -> int
{
static std::uniform_int_distribution<> rint(start, end);
return rint(rng);
}
template<int start, int end>
auto random_double() -> double
{
static std::uniform_real_distribution<> rdouble(start, end);
return rdouble(rng);
}
} // namespace rng
#endif

32
src/sa.cpp Normal file
View File

@ -0,0 +1,32 @@
#include "sa.hpp"
#include <cmath>
auto sa::solution::simulated_annealing(int capacity, const std::vector<long long> &items,
const double alpha, double temp,
const double temp_min)->sa::solution
{
sa::solution best(items, capacity);
sa::solution prev = best;
int iteration = 0;
while (temp > temp_min) {
iteration++;
sa::solution neighbor(prev, iteration);
neighbor.setneighbor();
long long diff = neighbor.fitness - prev.fitness;
if (diff < 0 || rng::random_double<0, 1>() / temp < 0.8) {
swap(prev, neighbor);
}
temp *= alpha;
if (prev.fitness < best.fitness) {
best = prev;
}
}
best.setiterations(iteration);
return best;
}

235
src/sa.hpp Normal file
View File

@ -0,0 +1,235 @@
#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 <set>
#include <utility>
#include <vector>
#include "random.hpp"
namespace sa {
using content = std::priority_queue<long long, std::vector<long long>, std::greater<>>;
class box {
content items;
long long fullness{};
friend void swap(box &one, box &two) {
using std::swap;
swap(one.items, two.items);
swap(one.fullness, two.fullness);
}
void pop() {
fullness -= items.top();
items.pop();
}
public:
box() = default;
box(const content &items, long long fullness):
items(items), fullness(fullness) {}
void add_item(long long item) {
fullness += item;
items.push(item);
}
void clear() {
while (!items.empty()) {
items.pop();
}
fullness = 0;
}
auto swappable10(box &other, int capacity) -> bool {
return items.top() + other.fullness <= capacity;
}
void swap10(box &other) {
other.add_item(items.top());
pop();
}
auto swappable11(box &other, int capacity) -> bool {
long long choice1 = items.top();
long long choice2 = other.items.top();
return choice1 != choice2 &&
choice1 + other.fullness - choice2 <= capacity &&
choice2 + fullness - choice1 <= capacity;
}
void swap11(box &other) {
long long choice1 = items.top();
long long choice2 = other.items.top();
pop();
other.pop();
add_item(choice2);
other.add_item(choice1);
}
void print(int ind) {
std::cout << "Caixa " << ind << ":";
content tmp;
while (!items.empty()) {
std::cout << ' ' << items.top();
items.pop();
}
std::cout << '\n';
}
[[nodiscard]] auto empty() const -> bool {
return fullness == 0;
}
};
class solution {
std::vector<box> boxes;
long long fitness;
int capacity;
int iterations;
int iteration;
friend void swap(solution &one, solution &two) {
using std::swap;
swap(one.boxes, two.boxes);
swap(one.capacity, two.capacity);
swap(one.fitness, two.fitness);
swap(one.iterations, two.iterations);
swap(one.iteration, two.iteration);
}
void random_swap(int choice, std::vector<int> &sequence10, std::vector<int> &sequence11) {
typedef void (box::*swap)(box&);
swap swaps[2] = {
&box::swap10,
&box::swap11
};
std::vector<int>* sequences[2] = {
&sequence10,
&sequence11
};
int now = rng::random_double<0, 1>() > 0.3 ? 0 : 1;
if (sequences[now]->empty()) {
now ^= 1;
if (sequences[now]->empty()) {
return;
}
}
std::uniform_int_distribution<> dist(0, (int)sequences[now]->size() - 1);
(boxes[choice].*swaps[now])(boxes[(*sequences[now])[dist(rng::rng)]]);
}
public:
solution() = default;
solution(const solution &other, int itr): boxes(other.boxes), fitness(other.fitness),
capacity(other.capacity), iteration(itr) {}
solution(const std::vector<long long> &items, int capacity): // Gera a solução inicial
capacity(capacity), iteration(0) {
std::multiset<long long> its;
for (auto i : items) {
its.insert(i);
}
long long cap = capacity;
box tmp;
while (!its.empty()) {
auto itr = its.upper_bound(cap);
if (itr == its.begin()) {
cap = capacity;
cap -= *its.begin();
itr = its.begin();
this->boxes.emplace_back(tmp);
tmp.clear();
} else {
itr--;
cap -= *itr;
}
tmp.add_item(*itr);
its.erase(itr);
}
if (!tmp.empty()) {
this->boxes.emplace_back(tmp);
}
fitness = (int)this->boxes.size();
}
void setneighbor() { // Gera um vizinho da solução
int choice = std::uniform_int_distribution<>(0, (int)boxes.size() - 1)(rng::rng);
std::vector<int> sequence10;
std::vector<int> sequence11;
sequence10.reserve(boxes.size());
sequence11.reserve(boxes.size());
for (size_t i = 0; i < choice; i++) {
if (boxes[choice].swappable10(boxes[i], capacity)) {
sequence10.push_back((int)i);
}
if (boxes[choice].swappable11(boxes[i], capacity)) {
sequence11.push_back((int)i);
}
}
for (size_t i = choice + 1; i < boxes.size(); i++) {
if (boxes[choice].swappable10(boxes[i], capacity)) {
sequence10.push_back((int)i);
}
if (boxes[choice].swappable11(boxes[i], capacity)) {
sequence11.push_back((int)i);
}
}
random_swap(choice, sequence10, sequence11);
if (boxes[choice].empty()) {
swap(boxes[choice], boxes[boxes.size() - 1]);
boxes.pop_back();
fitness = (int)boxes.size();
}
}
void print_sol(char flags = 0) {
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';
if(!(flags & SIMULATED_ANNEALING_DISABLE_SHOWCRATES)){
for (size_t i = 0; i < boxes.size(); i++) {
boxes[i].print((int)i + 1);
}
}
}
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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More