From 42a1837ecfa46fb74c2b6aaf07b91686e2363a00 Mon Sep 17 00:00:00 2001 From: Moritz Sallermann Date: Thu, 21 Mar 2024 19:22:51 +0000 Subject: [PATCH] Deffuant: Implemented the update rule in the vector model Also hacked in the generation of the initial agents by hardcoding the dimensionality <--- TODO Co-authored-by: Amrita Goswami --- include/agents/discrete_vector_agent.hpp | 5 +-- src/models/DeffuantModelVector.cpp | 48 ++++++++++++++++++++---- test/test_util.cpp | 3 +- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/include/agents/discrete_vector_agent.hpp b/include/agents/discrete_vector_agent.hpp index 20f63be..01c72e0 100644 --- a/include/agents/discrete_vector_agent.hpp +++ b/include/agents/discrete_vector_agent.hpp @@ -42,9 +42,8 @@ inline DiscreteVectorAgent agent_from_string( const std::st { DiscreteVectorAgent res{}; - auto callback = [&]( int idx_list [[maybe_unused]], const auto & substring ) { - res.data.opinion.push_back( std::stoi( substring ) ); - }; + auto callback = [&]( int idx_list [[maybe_unused]], const auto & substring ) + { res.data.opinion.push_back( std::stoi( substring ) ); }; parse_comma_separated_list( str, callback ); return res; diff --git a/src/models/DeffuantModelVector.cpp b/src/models/DeffuantModelVector.cpp index 8c98334..3912632 100644 --- a/src/models/DeffuantModelVector.cpp +++ b/src/models/DeffuantModelVector.cpp @@ -1,7 +1,9 @@ +#include "agent.hpp" #include "agents/discrete_vector_agent.hpp" #include "models/DeffuantModel.hpp" -#include +#include "util/math.hpp" #include +#include #include namespace Seldon @@ -10,23 +12,53 @@ namespace Seldon template<> void DeffuantModelAbstract::initialize_agents() { + std::uniform_int_distribution dist( 0, 1 ); + int dim = 5; + for( size_t i = 0; i < network.agents.size(); i++ ) { - // network.agents[i].data.opinion = double( i ) / double( network.agents.size() ); + auto & opinion = network.agents[i].data.opinion; + opinion.resize( dim ); + for( auto & o : opinion ) + { + o = dist( gen ); + } } } template<> void DeffuantModelAbstract::update_rule( AgentT & agent1, AgentT & agent2 ) { + size_t dim = agent1.data.opinion.size(); + auto & opinion1 = agent1.data.opinion; + auto & opinion2 = agent2.data.opinion; + + auto distance = hamming_distance( std::span( opinion1 ), std::span( opinion2 ) ); + + std::uniform_int_distribution<> dist_pair( 0, 1 ); + std::uniform_real_distribution<> dist_convince( 0, 1 ); + // Update rule - // auto opinion_diff = agent1.data.opinion - agent2.data.opinion; // Only if less than homophily_threshold - // if( std::abs( opinion_diff ) < homophily_threshold ) - // { - // agent1.data.opinion -= mu * opinion_diff; - // agent2.data.opinion += mu * opinion_diff; - // } + if( distance < homophily_threshold ) + { + for( size_t idx_opinion = 0; idx_opinion < dim; idx_opinion++ ) + { + if( opinion1[idx_opinion] != opinion2[idx_opinion] ) + { + // randomly select one of the + auto idx_selected = dist_pair( gen ); + if( idx_selected == 0 && mu < dist_convince( gen ) ) + { + opinion1[idx_opinion] = opinion2[idx_opinion]; + } + else + { + opinion2[idx_opinion] = opinion1[idx_opinion]; + } + } + } + } } template class DeffuantModelAbstract; diff --git a/test/test_util.cpp b/test/test_util.cpp index a351fe2..c1ed1ac 100644 --- a/test/test_util.cpp +++ b/test/test_util.cpp @@ -16,7 +16,8 @@ TEST_CASE( "Test parse_comma_separated_list", "[util_parse_list]" ) std::vector dbl_vec_expected = { -2.0, 13.0 }; std::vector int_vec_expected = { 12, 10 }; - auto callback = [&]( int idx_list, std::string & substr ) { + auto callback = [&]( int idx_list, std::string & substr ) + { if( idx_list == 0 || idx_list == 3 ) { int_vec.push_back( std::stoi( substr ) );