home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1991
/
04
/
morrow
/
gene.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-09-03
|
3KB
|
172 lines
/***
* GASystem
* Mike Morrow
* September 1989
***/
#include "ga.h"
#include "param.h"
#include "util.h"
extern void *calloc();
/**
* These variables hold parameters that the user may set by interacting with the
* symbol table. The default values are hardwired here.
**/
static int param_gene_len = 10;
static int param_gene_lowa = 'A';
static int param_gene_hia = 'Z';
static CONST PARAMSPEC geneparams[] =
{
{"LEN", (void *) ¶m_gene_len, MODEINT, FLAG_INIT},
{"LOWA", (void *) ¶m_gene_lowa, MODEINT, FLAG_INIT},
{"HIA", (void *) ¶m_gene_hia, MODEINT, FLAG_INIT},
{(char *) 0, (void *) 0, (MODE) 0, 0}
};
/**
* This routine inserts information about the parameter vars
* into the symbol table.
**/
genepinit()
{
CONST PARAMSPEC *p;
for(p = geneparams; p->param_name; p++)
paramins(p, SYMVAR);
}
/**
* Generate a new gene.
**/
GENE *genenew()
{
GENE *new;
unsigned int i;
SEQ_COMPONENT range;
new = calloc(1, sizeof(GENE));
if(! new)
return new;
new->gene_seq = calloc(param_gene_len, sizeof(SEQ_COMPONENT));
if(! new->gene_seq)
{
free(new);
return (GENE *) 0;
}
new->gene_fit = (FIT_TYPE) 0;
/**
* Generate a random SEQ pattern
**/
range = param_gene_hia - param_gene_lowa + 1;
for(i = 0; i < param_gene_len; i++)
new->gene_seq[i] = param_gene_lowa +
(SEQ_COMPONENT) randnum((int) range);
return new;
}
/**
* Perform 2-point crossover on g1 and g2.
**/
void genecross(g1, g2)
GENE *g1, *g2;
{
int xpnt1, xpnt2;
register SEQ_COMPONENT *g1ptr, *g1end, *g2ptr;
xpnt1 = randnum(param_gene_len);
xpnt2 = xpnt1 + randnum(param_gene_len - xpnt1);
/**
* Everything between xpnt1 and xpnt2 will be swapped.
**/
g1ptr = &(g1->gene_seq[xpnt1]);
g1end = &(g1->gene_seq[xpnt2]);
g2ptr = &(g2->gene_seq[xpnt1]);
while(g1ptr <= g1end)
{
register SEQ_COMPONENT tmp;
tmp = *g2ptr;
*g2ptr++ = *g1ptr;
*g1ptr++ = tmp;
}
}
/**
* Mutate a random allele in the gene g.
**/
void genemutate(g)
GENE *g;
{
SEQ_COMPONENT range, new;
int where;
where = randnum(param_gene_len);
range = param_gene_hia - param_gene_lowa + 1;
new = param_gene_lowa + (SEQ_COMPONENT) randnum((int) range);
g->gene_seq[where] = new;
}
/**
* Duplicate the SEQ of g2 into g1. Also the fitness rating is transferred.
**/
void genedupl(g1, g2)
GENE *g1, *g2;
{
memcpy(g1->gene_seq, g2->gene_seq, param_gene_len * sizeof(SEQ_COMPONENT));
g1->gene_fit = g2->gene_fit;
}
/**
* Apply the objective function to GENE g.
**/
FIT_TYPE genefitness(g)
GENE *g;
{
return g->gene_fit = objective(g->gene_seq, param_gene_len);
}
void geneshow(g)
GENE *g;
{
objshow(g->gene_seq, param_gene_len, g->gene_fit);
}
/**
* Compare the fitness of two genes. Return convention is like strcmp().
**/
int genecomp(g1, g2)
GENE **g1, **g2;
{
return (*g2)->gene_fit - (*g1)->gene_fit;
}