2 #define _POSIX_C_SOURCE 200112L
11 #include "sn_population.h"
12 #include "sn_network.h"
13 #include "sn_random.h"
15 struct sn_population_s
19 sn_network_t **networks;
21 uint32_t networks_num;
26 static int rate_network (const sn_network_t *n)
31 rate = SN_NETWORK_STAGE_NUM (n) * SN_NETWORK_INPUT_NUM (n);
32 for (i = 0; i < SN_NETWORK_STAGE_NUM (n); i++)
34 sn_stage_t *s = SN_NETWORK_STAGE_GET (n, i);
35 rate += SN_STAGE_COMP_NUM (s);
39 } /* int rate_network */
41 sn_population_t *sn_population_create (uint32_t size)
46 p = (sn_population_t *) malloc (sizeof (sn_population_t));
49 memset (p, 0, sizeof (sn_population_t));
52 p->networks = (sn_network_t **) calloc ((size_t) size,
53 sizeof (sn_network_t *));
54 if (p->networks == NULL)
60 p->ratings = (int *) calloc ((size_t) size, sizeof (int));
61 if (p->ratings == NULL)
68 status = pthread_mutex_init (&p->lock, /* attr = */ NULL);
71 fprintf (stderr, "sn_population_create: pthread_mutex_init failed: %i\n",
80 } /* sn_population_t *sn_population_create */
82 void sn_population_destroy (sn_population_t *p)
89 for (i = 0; i < p->size; i++)
90 if (p->networks[i] != NULL)
91 sn_network_destroy (p->networks[i]);
93 pthread_mutex_destroy (&p->lock);
98 } /* void sn_population_destroy */
100 int sn_population_push (sn_population_t *p, sn_network_t *n)
102 sn_network_t *n_copy;
105 n_copy = sn_network_clone (n);
108 fprintf (stderr, "sn_population_push: sn_network_clone failed.\n");
112 rating = rate_network (n_copy);
114 pthread_mutex_lock (&p->lock);
116 if (p->networks_num < p->size)
118 p->networks[p->networks_num] = n_copy;
119 p->ratings[p->networks_num] = rating;
125 sn_network_t *n_removed = n_copy;
128 for (i = 0; i < (1 + (p->networks_num / 16)); i++)
130 index = sn_bounded_random (0, p->networks_num - 1);
131 if (p->ratings[index] < rating)
134 n_removed = p->networks[index];
135 p->networks[index] = n_copy;
136 p->ratings[index] = rating;
140 sn_network_destroy (n_removed);
143 pthread_mutex_unlock (&p->lock);
146 } /* int sn_population_push */
148 sn_network_t *sn_population_pop (sn_population_t *p)
151 sn_network_t *n_copy;
153 pthread_mutex_lock (&p->lock);
155 if (p->networks_num <= 0)
157 pthread_mutex_unlock (&p->lock);
161 index = sn_bounded_random (0, p->networks_num - 1);
162 n_copy = sn_network_clone (p->networks[index]);
164 pthread_mutex_unlock (&p->lock);
167 } /* sn_population_t *sn_population_pop */
169 sn_network_t *sn_population_best (sn_population_t *p)
175 sn_network_t *n_copy;
180 pthread_mutex_lock (&p->lock);
182 if (p->networks_num <= 0)
184 pthread_mutex_unlock (&p->lock);
188 for (i = 0; i < p->networks_num; i++)
190 if ((p->ratings[i] < rating) || (rating < 0))
192 rating = p->ratings[i];
197 n_copy = sn_network_clone (p->networks[index]);
199 pthread_mutex_unlock (&p->lock);
202 } /* sn_network_t *sn_population_best */
204 /* vim: set shiftwidth=2 softtabstop=2 : */