/*!\todo No es necesario recalcular el fitness de un individuo si este no ha cambiado */ float individuo_fitness(individuo *ind) { int i,j,cont; polygon_holes temp; temp.p = &(ind->ambiente->plantilla); temp.h = (polygon*) malloc(sizeof(polygon)*(ind->ngenes+ind->ambiente->nhuecos)); temp.nholes = ind->ngenes+ind->ambiente->nhuecos; for (i=0,cont=0;i<ind->ambiente->nhuecos;i++) { temp.h[cont].nvertices = ind->ambiente->huecos[i].nvertices; temp.h[cont].v=(point*) malloc(sizeof(point)*temp.h[i].nvertices); for (j=0;j<temp.h[cont].nvertices;j++) { temp.h[cont].v[j].x=ind->ambiente->huecos[i].v[j].x; temp.h[cont].v[j].y=ind->ambiente->huecos[i].v[j].y; } cont++; } for (i=0;i<ind->ngenes;i++) { temp.h[cont].nvertices = ind->ambiente->patrones[ind->posgen[i].id].nvertices; temp.h[cont].v = (point*) malloc(sizeof(point)*temp.h[cont].nvertices); for (j=0;j<temp.h[cont].nvertices;j++) { temp.h[cont].v[j].x=ind->ambiente->patrones[ind->posgen[i].id].v[j].x; temp.h[cont].v[j].y=ind->ambiente->patrones[ind->posgen[i].id].v[j].y; } polygon_rotate(&(temp.h[cont]),ind->posgen[i].t); polygon_translate(&(temp.h[cont]),ind->posgen[i].x, ind->posgen[i].y); cont++; } ind->fitness = polygonholes_volumen(&temp)/(ind->ambiente->volumen); ind->areautil = polygonholes_area(&temp); for (i=0;i<temp.nholes;i++) { free(temp.h[i].v); } free (temp.h); return (ind->fitness); }
static gboolean process (GeglOperation *operation, GeglBuffer *input, GeglBuffer *output, const GeglRectangle *result, gint level) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation); GeglRectangle boundary = get_effective_area (operation); GeglRectangle extended; const Babl *format = babl_format ("RGBA float"); GRand *gr = g_rand_new_with_seed (o->seed); gfloat color[4]; gint cols, rows, num_tiles, count; gint *random_indices; gfloat *dst_buf; Polygon poly; gint i; extended.x = CLAMP (result->x - op_area->left, boundary.x, boundary.x + boundary.width); extended.width = CLAMP (result->width + op_area->left + op_area->right, 0, boundary.width); extended.y = CLAMP (result->y - op_area->top, boundary.y, boundary.y + boundary.width); extended.height = CLAMP (result->height + op_area->top + op_area->bottom, 0, boundary.height); dst_buf = g_new0 (gfloat, extended.width * extended.height * 4); cols = (result->width + o->tile_size - 1) / o->tile_size; rows = (result->height + o->tile_size - 1) / o->tile_size; num_tiles = (rows + 1) * (cols + 1); random_indices = g_new0 (gint, num_tiles); for (i = 0; i < num_tiles; i++) random_indices[i] = i; randomize_indices (num_tiles, random_indices, gr); for (count = 0; count < num_tiles; count++) { gint i, j, ix, iy; gdouble x, y, width, height, theta; i = random_indices[count] / (cols + 1); j = random_indices[count] % (cols + 1); x = j * o->tile_size + (o->tile_size / 4.0) - g_rand_double_range (gr, 0, (o->tile_size /2.0)) + result->x; y = i * o->tile_size + (o->tile_size / 4.0) - g_rand_double_range (gr, 0, (o->tile_size /2.0)) + result->y; width = (o->tile_size + g_rand_double_range (gr, -o->tile_size / 8.0, o->tile_size / 8.0)) * o->tile_saturation; height = (o->tile_size + g_rand_double_range (gr, -o->tile_size / 8.0, o->tile_size / 8.0)) * o->tile_saturation; theta = g_rand_double_range (gr, 0, 2 * G_PI); polygon_reset (&poly); polygon_add_point (&poly, -width / 2.0, -height / 2.0); polygon_add_point (&poly, width / 2.0, -height / 2.0); polygon_add_point (&poly, width / 2.0, height / 2.0); polygon_add_point (&poly, -width / 2.0, height / 2.0); polygon_rotate (&poly, theta); polygon_translate (&poly, x, y); ix = CLAMP (x, boundary.x, boundary.x + boundary.width - 1); iy = CLAMP (y, boundary.y, boundary.y + boundary.height - 1); gegl_buffer_sample (input, ix, iy, NULL, color, format, GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE); fill_poly_color (&poly, &extended, &boundary, dst_buf, color); } gegl_buffer_set (output, &extended, 0, format, dst_buf, GEGL_AUTO_ROWSTRIDE); g_free (dst_buf); g_free (random_indices); g_free (gr); return TRUE; }
/*!\fn bool individuo_validate(individuo *ind) Esta funcion identifica si un individuo es una solucion validad, esto es verdadero si se cumplen las siguientes condiciones: - No se repite ningun patron dentro de la solucion - Todos los patrones estan dentro de la plantilla - Ningun patron se solapa con la plantilla, huecos u otro patron En caso contrario el individuo no es valido. \param [in] ind Individuo a validar \return Verdadero si es un individuo valido, falso en caso contrario. */ bool individuo_validate(individuo *ind) { bool valido = true; int i,j; polygon_holes ph; polygon *pat; for (i=0;i<ind->ngenes-1 && valido;i++) { for (j=i+1;j<ind->ngenes && valido;j++) { if (ind->posgen[i].id == ind->posgen[j].id) valido = false; } } ph.p = &(ind->ambiente->plantilla); ph.nholes = ind->ambiente->nhuecos; ph.h = (polygon*) malloc(sizeof(polygon)*ph.nholes); for (i=0;i<ph.nholes;i++) { ph.h[i].nvertices = ind->ambiente->huecos[i].nvertices; ph.h[i].v=(point*) malloc(sizeof(point)*ph.h[i].nvertices); for (j=0;j<ph.h[i].nvertices;j++) { ph.h[i].v[j].x=ind->ambiente->huecos[i].v[j].x; ph.h[i].v[j].y=ind->ambiente->huecos[i].v[j].y; } } pat = (polygon*) malloc(sizeof(polygon)*ind->ngenes); for (i=0;i<ind->ngenes;i++) { pat[i].nvertices = ind->ambiente->patrones[ind->posgen[i].id].nvertices; pat[i].v = (point*) malloc(sizeof(point)*pat[i].nvertices); for (j=0;j<pat[i].nvertices;j++) { pat[i].v[j].x=ind->ambiente->patrones[ind->posgen[i].id].v[j].x; pat[i].v[j].y=ind->ambiente->patrones[ind->posgen[i].id].v[j].y; } polygon_rotate(&(pat[i]),ind->posgen[i].t); polygon_translate(&(pat[i]),ind->posgen[i].x, ind->posgen[i].y); } for (i=0;i<ind->ngenes && valido;i++) { if(!polygonholes_polygonin(&ph, &(pat[i]))) { valido=false; } } for (i=0;i<ind->ngenes-1 && valido;i++) { for (j=i+1;j<ind->ngenes && valido;j++) { if (polygon_overlapping(&(pat[i]),&(pat[j]))) { valido=false; } } } for (i=0;i<ind->ngenes;i++) { free(pat[i].v); } free(pat); for (i=0;i<ph.nholes;i++) { free(ph.h[i].v); } free(ph.h); return valido; }