Make everything use the same random pool

This commit is contained in:
Segcolt 2024-10-14 15:14:28 -03:00
parent 2f53e5de27
commit ad5aedd454
4 changed files with 38 additions and 21 deletions

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

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);
}

25
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 {
@ -94,7 +96,6 @@ class box {
class solution {
std::vector<box> boxes;
std::mt19937_64 gen;
long long fitness;
int capacity;
int iterations;
@ -104,7 +105,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 +122,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 +132,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 +174,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 +206,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';