From 0cecefcd9dba3194adf16bddcbf1ce4dfa3ac61d Mon Sep 17 00:00:00 2001 From: Mehmet Mert Yildiran Date: Tue, 29 Oct 2019 04:26:15 +0300 Subject: [PATCH] Replace the random sampling function with C++17 equivalent --- .ale_config | 1 + plexus/.ycm_extra_conf.py | 1 + plexus/network.hpp | 27 ++++++++++++++------------- plexus/plexus.cpp | 15 +++++++++------ setup.py | 2 +- 5 files changed, 26 insertions(+), 20 deletions(-) diff --git a/.ale_config b/.ale_config index 64b74fa..13b2bf0 100644 --- a/.ale_config +++ b/.ale_config @@ -13,3 +13,4 @@ -fPIC -I/usr/include/python3.6m -w +-std=c++17 diff --git a/plexus/.ycm_extra_conf.py b/plexus/.ycm_extra_conf.py index 1d1eb58..fac5cac 100644 --- a/plexus/.ycm_extra_conf.py +++ b/plexus/.ycm_extra_conf.py @@ -16,5 +16,6 @@ def Settings(**kwargs): '-fPIC', '-I/usr/include/python3.6m', '-w', + '-std=c++17', ], } diff --git a/plexus/network.hpp b/plexus/network.hpp index 8cfd0f6..7293917 100644 --- a/plexus/network.hpp +++ b/plexus/network.hpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include class Neuron; @@ -81,17 +83,16 @@ class Network void load(std::vector input_arr, std::vector output_arr); }; -// Function to get a random sampling from a vector -// using Fisher-Yates shuffle method -template -BidiIter random_unique(BidiIter begin, BidiIter end, size_t num_random) { - size_t left = std::distance(begin, end); - while (num_random--) { - BidiIter r = begin; - std::advance(r, rand()%left); - std::swap(*begin, *r); - ++begin; - --left; - } - return begin; + +// Requires -std=c++17 compilation flag +template +RandomSampling random_sample( + RandomSampling neurons, + unsigned int sample_length +) +{ + RandomSampling sample; + std::sample(neurons.begin(), neurons.end(), std::back_inserter(sample), + sample_length, std::mt19937{std::random_device{}()}); + return sample; } diff --git a/plexus/plexus.cpp b/plexus/plexus.cpp index 6daf7e1..07e73a9 100644 --- a/plexus/plexus.cpp +++ b/plexus/plexus.cpp @@ -23,7 +23,8 @@ Neuron::Neuron(Network& network) void Neuron::partially_subscribe() { if (this->subscriptions.size() == 0) { - unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); + unsigned seed = std::chrono::system_clock::now() + .time_since_epoch().count(); std::default_random_engine generator (seed); std::normal_distribution distribution( this->network->get_connectivity(), @@ -34,9 +35,12 @@ void Neuron::partially_subscribe() sample_length = this->network->nonmotor_neurons.size(); if (sample_length <= 0) sample_length = 0; + std::vector elected = random_sample( + this->network->nonmotor_neurons, + sample_length + ); this->subscriptions.reserve(sample_length); - for (unsigned int i = 0; i < sample_length; i++) { - Neuron* target_neuron = this->network->nonmotor_neurons[i]; + for (auto target_neuron: elected) { if (target_neuron != this) { this->subscriptions.insert( std::pair( @@ -203,9 +207,8 @@ void Network::_ignite(Network* network) std::vector ban_list; while (network->freezer == false) { if (network->randomly_fire) { - Neuron* neuron = random_unique( - network->nonsensory_neurons.begin(), - network->nonsensory_neurons.end(), + Neuron* neuron = random_sample( + network->nonsensory_neurons, 1 )[0]; if (neuron->type == MOTOR_NEURON) { diff --git a/setup.py b/setup.py index 46da1b7..c14f835 100644 --- a/setup.py +++ b/setup.py @@ -102,7 +102,7 @@ name='cplexus', sources=['plexus/plexus.cpp', 'plexus/wrapper.cpp'], language='c++', - extra_compile_args=['-w'], + extra_compile_args=['-w', '-std=c++17'], ) ] )