Stride Reference Manual  1.0
Cluster.cpp
Go to the documentation of this file.
1 /*
2  * This is free software: you can redistribute it and/or modify it
3  * under the terms of the GNU General Public License as published by
4  * the Free Software Foundation, either version 3 of the License, or
5  * any later version.
6  * The software is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  * You should have received a copy of the GNU General Public License
11  * along with the software. If not, see <http://www.gnu.org/licenses/>.
12  *
13  * Copyright 2017, Willem L, Kuylen E, Stijven S & Broeckhove J
14  */
15 
21 #include "Cluster.h"
22 
23 #include "Infector.h"
24 #include "calendar/Calendar.h"
25 
26 #include <spdlog/spdlog.h>
27 
28 namespace stride {
29 
30 using namespace std;
31 
32 std::array<ContactProfile, numOfClusterTypes()> Cluster::g_profiles;
33 
34 Cluster::Cluster(std::size_t cluster_id, ClusterType cluster_type, GeoCoordinate coordinate)
35  : m_cluster_id(cluster_id), m_cluster_type(cluster_type),
36  m_index_immune(0), m_profile(g_profiles.at(toSizeType(m_cluster_type))),
37  m_coordinate(coordinate) {
38 }
39 
40 void Cluster::addContactProfile(ClusterType cluster_type, const ContactProfile& profile) {
41  g_profiles.at(toSizeType(cluster_type)) = profile;
42 }
43 
44 
46  m_members.emplace_back(std::make_pair(p, true));
48 }
49 
50 std::size_t Cluster::getInfectedCount() const {
51  size_t num_cases = 0;
52  for (auto& member : m_members) {
53  auto health = member.first->getHealth();
54  if (health.isInfected() || health.isRecovered())
55  ++num_cases;
56  }
57  return num_cases;
58 }
59 
60 void Cluster::removePerson(unsigned int id) {
61  for (unsigned int i_member = 0; i_member < m_members.size(); ++i_member) {
62  if (m_members.at(i_member).first->getId() == id) {
63  m_members.erase(m_members.begin() + i_member);
64  m_index_immune = m_members.size() > 0 ? m_members.size() - 1 : 0;
65  return;
66  }
67  }
68 }
69 
70 std::size_t Cluster::getActiveClusterMembers() const {
71  std::size_t total = 0;
72  for (const auto& person: m_members) {
73  if (!person.first->isOnVacation()) {
74  ++total;
75  }
76  }
77 
78  return total;
79 }
80 
81 tuple<bool, size_t> Cluster::sortMembers() {
82  bool infectious_cases = false;
83  size_t num_cases = 0;
84 
85  for (size_t i_member = 0; i_member < m_index_immune; i_member++) {
86  // if immune, move to back
87  if (m_members[i_member].first->getHealth().isImmune()) {
88  bool swapped = false;
89  size_t new_place = m_index_immune - 1;
90  m_index_immune--;
91  while (!swapped && new_place > i_member) {
92  if (m_members[new_place].first->getHealth().isImmune()) {
93  m_index_immune--;
94  new_place--;
95  } else {
96  swap(m_members[i_member], m_members[new_place]);
97  swapped = true;
98  }
99  }
100  }
101  // else, if not susceptible, move to front
102  else if (!m_members[i_member].first->getHealth().isSusceptible()) {
103  if (!infectious_cases && m_members[i_member].first->getHealth().isInfectious()) {
104  infectious_cases = true;
105  }
106  if (i_member > num_cases) {
107  swap(m_members[i_member], m_members[num_cases]);
108  }
109  num_cases++;
110  }
111  }
112  return make_tuple(infectious_cases, num_cases);
113 }
114 
116  for (auto& member: m_members) {
117  member.second = member.first->isInCluster(m_cluster_type);
118  }
119 }
120 
121 }
void updateMemberPresence()
Calculate which members are present in the cluster on the current day.
Definition: Cluster.cpp:115
Cluster(std::size_t cluster_id, ClusterType cluster_type, GeoCoordinate coordinate=GeoCoordinate(0, 0))
Constructor.
Definition: Cluster.cpp:34
std::size_t getActiveClusterMembers() const
Return number of persons in this cluster.
Definition: Cluster.cpp:70
static void addContactProfile(ClusterType cluster_type, const ContactProfile &profile)
Add contact profile.
Definition: Cluster.cpp:40
Header for the Infector class.
std::size_t getInfectedCount() const
Return the amount of infected people in this cluster.
Definition: Cluster.cpp:50
Header file for the Calendar class.
std::vector< std::pair< Simulator::PersonType *, bool > > m_members
Container with pointers to Cluster members.
Definition: Cluster.h:103
Time Dependent Person DataType.
Definition: NoBehaviour.h:17
std::size_t toSizeType(ClusterType c)
Cast for array access.
Definition: ClusterType.h:36
static std::array< ContactProfile, numOfClusterTypes()> g_profiles
Definition: Cluster.h:107
Forward declaration of class Person.
Definition: ThresholdData.h:15
std::tuple< bool, size_t > sortMembers()
Sort members w.r.t. health status (order: exposed/infected/recovered, susceptible, immune).
Definition: Cluster.cpp:81
STL namespace.
std::size_t m_index_immune
Index of the first immune member in the Cluster.
Definition: Cluster.h:102
void addPerson(Simulator::PersonType *p)
Add the given Person to the Cluster.
Definition: Cluster.cpp:45
ClusterType
Enumerates the cluster types.
Definition: ClusterType.h:28
Header for the core Cluster class.
void removePerson(unsigned int id)
Remove the given Person from the Cluster.
Definition: Cluster.cpp:60
ClusterType m_cluster_type
The type of the Cluster (for logging purposes).
Definition: Cluster.h:101