1997-02-19 13:59:07 +01:00
|
|
|
/*------------------------------------------------------------------------
|
|
|
|
*
|
1999-02-14 00:22:53 +01:00
|
|
|
* geqo_recombination.c
|
1997-09-07 07:04:48 +02:00
|
|
|
* misc recombination procedures
|
1997-02-19 13:59:07 +01:00
|
|
|
*
|
2004-08-29 07:07:03 +02:00
|
|
|
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_recombination.c,v 1.14 2004/08/29 05:06:43 momjian Exp $
|
1997-02-19 13:59:07 +01:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* contributed by:
|
|
|
|
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
|
1997-09-07 07:04:48 +02:00
|
|
|
* Martin Utesch * Institute of Automatic Control *
|
|
|
|
= = University of Mining and Technology =
|
|
|
|
* utesch@aut.tu-freiberg.de * Freiberg, Germany *
|
1997-02-19 13:59:07 +01:00
|
|
|
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* -- parts of this are adapted from D. Whitley's Genitor algorithm -- */
|
|
|
|
|
|
|
|
#include "postgres.h"
|
2004-01-24 00:54:21 +01:00
|
|
|
|
1997-02-19 13:59:07 +01:00
|
|
|
#include "optimizer/geqo_random.h"
|
1999-07-16 07:00:38 +02:00
|
|
|
#include "optimizer/geqo_recombination.h"
|
1997-02-19 13:59:07 +01:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
1999-02-14 00:22:53 +01:00
|
|
|
* init_tour
|
1997-02-19 13:59:07 +01:00
|
|
|
*
|
1997-09-07 07:04:48 +02:00
|
|
|
* Randomly generates a legal "traveling salesman" tour
|
|
|
|
* (i.e. where each point is visited only once.)
|
|
|
|
* Essentially, this routine fills an array with all possible
|
|
|
|
* points on the tour and randomly chooses the 'next' city from
|
|
|
|
* this array. When a city is chosen, the array is shortened
|
|
|
|
* and the procedure repeated.
|
1997-02-19 13:59:07 +01:00
|
|
|
*/
|
|
|
|
void
|
1997-09-08 23:56:23 +02:00
|
|
|
init_tour(Gene *tour, int num_gene)
|
1997-02-19 13:59:07 +01:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
Gene *tmp;
|
|
|
|
int remainder;
|
|
|
|
int next,
|
|
|
|
i;
|
1997-02-19 13:59:07 +01:00
|
|
|
|
2004-01-24 00:54:21 +01:00
|
|
|
/* Fill a temp array with the IDs of all not-yet-visited cities */
|
1997-09-07 07:04:48 +02:00
|
|
|
tmp = (Gene *) palloc(num_gene * sizeof(Gene));
|
1997-02-19 13:59:07 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
for (i = 0; i < num_gene; i++)
|
2004-01-24 00:54:21 +01:00
|
|
|
tmp[i] = (Gene) (i + 1);
|
1997-02-19 13:59:07 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
remainder = num_gene - 1;
|
1997-02-19 13:59:07 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
for (i = 0; i < num_gene; i++)
|
|
|
|
{
|
2004-01-24 00:54:21 +01:00
|
|
|
/* choose value between 0 and remainder inclusive */
|
|
|
|
next = (int) geqo_randint(remainder, 0);
|
|
|
|
/* output that element of the tmp array */
|
1997-09-07 07:04:48 +02:00
|
|
|
tour[i] = tmp[next];
|
2004-01-24 00:54:21 +01:00
|
|
|
/* and delete it */
|
1997-09-07 07:04:48 +02:00
|
|
|
tmp[next] = tmp[remainder];
|
|
|
|
remainder--;
|
|
|
|
}
|
|
|
|
|
2004-01-24 00:54:21 +01:00
|
|
|
/*
|
2004-08-29 07:07:03 +02:00
|
|
|
* Since geqo_eval() will reject tours where tour[0] > tour[1], we may
|
|
|
|
* as well switch the two to make it a valid tour.
|
2004-01-24 00:54:21 +01:00
|
|
|
*/
|
|
|
|
if (num_gene >= 2 && tour[0] > tour[1])
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
Gene gtmp = tour[0];
|
2004-01-24 00:54:21 +01:00
|
|
|
|
|
|
|
tour[0] = tour[1];
|
|
|
|
tour[1] = gtmp;
|
|
|
|
}
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
pfree(tmp);
|
|
|
|
}
|
1997-02-19 13:59:07 +01:00
|
|
|
|
1999-02-14 00:22:53 +01:00
|
|
|
/* alloc_city_table
|
1997-02-19 13:59:07 +01:00
|
|
|
*
|
1997-09-07 07:04:48 +02:00
|
|
|
* allocate memory for city table
|
1997-02-19 13:59:07 +01:00
|
|
|
*/
|
1998-02-26 05:46:47 +01:00
|
|
|
City *
|
1997-02-19 13:59:07 +01:00
|
|
|
alloc_city_table(int num_gene)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
City *city_table;
|
1997-02-19 13:59:07 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
|
|
|
* palloc one extra location so that nodes numbered 1..n can be
|
|
|
|
* indexed directly; 0 will not be used
|
|
|
|
*/
|
|
|
|
city_table = (City *) palloc((num_gene + 1) * sizeof(City));
|
1997-02-19 13:59:07 +01:00
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return city_table;
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
1997-02-19 13:59:07 +01:00
|
|
|
|
1999-02-14 00:22:53 +01:00
|
|
|
/* free_city_table
|
1997-02-19 13:59:07 +01:00
|
|
|
*
|
1997-09-07 07:04:48 +02:00
|
|
|
* deallocate memory of city table
|
1997-02-19 13:59:07 +01:00
|
|
|
*/
|
1997-09-07 07:04:48 +02:00
|
|
|
void
|
1997-09-08 23:56:23 +02:00
|
|
|
free_city_table(City *city_table)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
|
|
|
pfree(city_table);
|
|
|
|
}
|