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 #define _ISOC99_SOURCE
23 #define _POSIX_C_SOURCE 200112L
32 #include "sn_population.h"
33 #include "sn_network.h"
34 #include "sn_random.h"
36 struct sn_population_s
40 sn_network_t **networks;
42 uint32_t networks_num;
47 static int rate_network (const sn_network_t *n)
52 rate = SN_NETWORK_STAGE_NUM (n) * SN_NETWORK_INPUT_NUM (n);
53 for (i = 0; i < SN_NETWORK_STAGE_NUM (n); i++)
55 sn_stage_t *s = SN_NETWORK_STAGE_GET (n, i);
56 rate += SN_STAGE_COMP_NUM (s);
60 } /* int rate_network */
62 sn_population_t *sn_population_create (uint32_t size)
67 p = (sn_population_t *) malloc (sizeof (sn_population_t));
70 memset (p, 0, sizeof (sn_population_t));
73 p->networks = (sn_network_t **) calloc ((size_t) size,
74 sizeof (sn_network_t *));
75 if (p->networks == NULL)
81 p->ratings = (int *) calloc ((size_t) size, sizeof (int));
82 if (p->ratings == NULL)
89 status = pthread_mutex_init (&p->lock, /* attr = */ NULL);
92 fprintf (stderr, "sn_population_create: pthread_mutex_init failed: %i\n",
101 } /* sn_population_t *sn_population_create */
103 void sn_population_destroy (sn_population_t *p)
110 for (i = 0; i < p->size; i++)
111 if (p->networks[i] != NULL)
112 sn_network_destroy (p->networks[i]);
114 pthread_mutex_destroy (&p->lock);
119 } /* void sn_population_destroy */
121 int sn_population_push (sn_population_t *p, sn_network_t *n)
123 sn_network_t *n_copy;
126 n_copy = sn_network_clone (n);
129 fprintf (stderr, "sn_population_push: sn_network_clone failed.\n");
133 rating = rate_network (n_copy);
135 pthread_mutex_lock (&p->lock);
137 if (p->networks_num < p->size)
139 p->networks[p->networks_num] = n_copy;
140 p->ratings[p->networks_num] = rating;
146 sn_network_t *n_removed = n_copy;
149 for (i = 0; i < (1 + (p->networks_num / 16)); i++)
151 index = sn_bounded_random (0, p->networks_num - 1);
152 if (p->ratings[index] < rating)
155 n_removed = p->networks[index];
156 p->networks[index] = n_copy;
157 p->ratings[index] = rating;
161 sn_network_destroy (n_removed);
164 pthread_mutex_unlock (&p->lock);
167 } /* int sn_population_push */
169 sn_network_t *sn_population_pop (sn_population_t *p)
172 sn_network_t *n_copy;
174 pthread_mutex_lock (&p->lock);
176 if (p->networks_num <= 0)
178 pthread_mutex_unlock (&p->lock);
182 index = sn_bounded_random (0, p->networks_num - 1);
183 n_copy = sn_network_clone (p->networks[index]);
185 pthread_mutex_unlock (&p->lock);
188 } /* sn_population_t *sn_population_pop */
190 sn_network_t *sn_population_best (sn_population_t *p)
196 sn_network_t *n_copy;
201 pthread_mutex_lock (&p->lock);
203 if (p->networks_num <= 0)
205 pthread_mutex_unlock (&p->lock);
209 for (i = 0; i < p->networks_num; i++)
211 if ((p->ratings[i] < rating) || (rating < 0))
213 rating = p->ratings[i];
218 n_copy = sn_network_clone (p->networks[index]);
220 pthread_mutex_unlock (&p->lock);
223 } /* sn_network_t *sn_population_best */
225 int sn_population_best_rating (sn_population_t *p)
230 pthread_mutex_lock (&p->lock);
232 if (p->networks_num <= 0)
234 pthread_mutex_unlock (&p->lock);
238 for (i = 0; i < p->networks_num; i++)
239 if ((p->ratings[i] < rating) || (rating < 0))
240 rating = p->ratings[i];
242 pthread_mutex_unlock (&p->lock);
245 } /* int sn_population_best_rating */
247 /* vim: set shiftwidth=2 softtabstop=2 : */