2 * collectd - src/sn_population.c
3 * Copyright (C) 2008 Florian octo Forster
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; only version 2 of the License is applicable.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 * Florian octo Forster <octo at verplant.org>
22 #ifndef _ISOC99_SOURCE
23 # define _ISOC99_SOURCE
25 #ifndef _POSIX_C_SOURCE
26 # define _POSIX_C_SOURCE 200112L
36 #include "sn_population.h"
37 #include "sn_network.h"
38 #include "sn_random.h"
40 struct sn_population_s
44 sn_network_t **networks;
46 uint32_t networks_num;
51 static int rate_network (const sn_network_t *n)
56 rate = SN_NETWORK_STAGE_NUM (n) * SN_NETWORK_INPUT_NUM (n);
57 for (i = 0; i < SN_NETWORK_STAGE_NUM (n); i++)
59 sn_stage_t *s = SN_NETWORK_STAGE_GET (n, i);
60 rate += SN_STAGE_COMP_NUM (s);
64 } /* int rate_network */
66 sn_population_t *sn_population_create (uint32_t size)
71 p = (sn_population_t *) malloc (sizeof (sn_population_t));
74 memset (p, 0, sizeof (sn_population_t));
77 p->networks = (sn_network_t **) calloc ((size_t) size,
78 sizeof (sn_network_t *));
79 if (p->networks == NULL)
85 p->ratings = (int *) calloc ((size_t) size, sizeof (int));
86 if (p->ratings == NULL)
93 status = pthread_mutex_init (&p->lock, /* attr = */ NULL);
96 fprintf (stderr, "sn_population_create: pthread_mutex_init failed: %i\n",
105 } /* sn_population_t *sn_population_create */
107 void sn_population_destroy (sn_population_t *p)
114 for (i = 0; i < p->size; i++)
115 if (p->networks[i] != NULL)
116 sn_network_destroy (p->networks[i]);
118 pthread_mutex_destroy (&p->lock);
123 } /* void sn_population_destroy */
125 int sn_population_push (sn_population_t *p, sn_network_t *n)
127 sn_network_t *n_copy;
130 n_copy = sn_network_clone (n);
133 fprintf (stderr, "sn_population_push: sn_network_clone failed.\n");
137 rating = rate_network (n_copy);
139 pthread_mutex_lock (&p->lock);
141 if (p->networks_num < p->size)
143 p->networks[p->networks_num] = n_copy;
144 p->ratings[p->networks_num] = rating;
150 sn_network_t *n_removed = n_copy;
153 for (i = 0; i < (1 + (p->networks_num / 16)); i++)
155 index = sn_bounded_random (0, p->networks_num - 1);
156 if (p->ratings[index] < rating)
159 n_removed = p->networks[index];
160 p->networks[index] = n_copy;
161 p->ratings[index] = rating;
165 sn_network_destroy (n_removed);
168 pthread_mutex_unlock (&p->lock);
171 } /* int sn_population_push */
173 sn_network_t *sn_population_pop (sn_population_t *p)
176 sn_network_t *n_copy;
178 pthread_mutex_lock (&p->lock);
180 if (p->networks_num <= 0)
182 pthread_mutex_unlock (&p->lock);
186 index = sn_bounded_random (0, p->networks_num - 1);
187 n_copy = sn_network_clone (p->networks[index]);
189 pthread_mutex_unlock (&p->lock);
192 } /* sn_population_t *sn_population_pop */
194 sn_network_t *sn_population_best (sn_population_t *p)
200 sn_network_t *n_copy;
205 pthread_mutex_lock (&p->lock);
207 if (p->networks_num <= 0)
209 pthread_mutex_unlock (&p->lock);
213 for (i = 0; i < p->networks_num; i++)
215 if ((p->ratings[i] < rating) || (rating < 0))
217 rating = p->ratings[i];
222 n_copy = sn_network_clone (p->networks[index]);
224 pthread_mutex_unlock (&p->lock);
227 } /* sn_network_t *sn_population_best */
229 int sn_population_best_rating (sn_population_t *p)
234 pthread_mutex_lock (&p->lock);
236 if (p->networks_num <= 0)
238 pthread_mutex_unlock (&p->lock);
242 for (i = 0; i < p->networks_num; i++)
243 if ((p->ratings[i] < rating) || (rating < 0))
244 rating = p->ratings[i];
246 pthread_mutex_unlock (&p->lock);
249 } /* int sn_population_best_rating */
251 /* vim: set shiftwidth=2 softtabstop=2 : */