www.pudn.com > dgpc.rar > lang.c
/* pgpc -- Parallel Genetic Programming in C
written by David Andre
Copyright c 1995, Genetic Programming Institute?
Genetic Algorithms Technology Corporation
All rights reserved.
v1.1 May 9th, 1994
ep05.c */
/********************************************************************/
/* INCLUDE FILES -- SHOULD NOT CHANGE */
#include
#include
#include
#include
#ifdef _ICC
#include
#include
#include
#include
#endif
#include "gp.h"
#include "proto.h"
void gpi_SendError(char *str); /*funcdef*/
/********************************************************************/
/* NECESSARY GLOBAL VARIABLES -- SHOULD NOT CHANGE*/
Individual * CurrentDude;
FitCaseInfo fitness_cases[MAX_NUM_FIT_CASES];
GlobalFitCaseInfo global_fitness_case_info;
extern long int seed;
static char str[256];
int dind;
Population * ppop;
/********************************************************************/
/*this shouldn't change*/
/* INCLUDE THE FILE CONTAINING THE CreateFitnessCases function,
if we are under borland */
/*#ifdef __BORLANDC__*/
#include _PRB_CFC
/*#endif*/
/********************************************************************/
/* USER SPECIFIED VARIABLES -- CAN BE CHANGED */
/********************************************************************/
int next_node_num;
TableType table[MAX_NUM_ADFS];
int active_node;
int active_arc;
int ready;
int stack[STACK_SIZE];
int stack_index;
int jump_index;
TableType *active_table;
#define get_transition(tbl, old_state, input) (((tbl).state[old_state]).trans[input])
void PrintAutomata();
void split(Branch *br, int action);
void CreateTable(Branch* br);
void EvalTable(int *string, int length);
void Test();
/********************************************************************/
/*NECESSARY PROBLEM SPECIFIC FUNCTIONS -- USER CAN CHANGE*/
/*Function that returns the maximum size of the branch passed to it,
in terms of the number of nodes*/
int GetBranchSize(int brn)/*;*/ /*funcdef - problem - GetBranchSize*/
{
switch (brn) {
case 0: return(NODES_PER_RPB);
case 1:
case 2:
case 3: return(NODES_PER_ADF);
default:
#ifdef _ICC
__asm{seterr;};
#else
printf("Error in getbranchsize\n");
exit(1);
#endif
}
}
/*Function returns the weight of the given branch for weighted branch crossover*/
int GetBranchWeight(int brn)/*;*/ /*funcdef*/
{
switch(brn) {
case 0:
return(1);
case 1:
case 2:
case 3:
return(1);
default:
return(1);
}
}
/********************************************************************/
/* Can be used to print extra information about the best individual, by
using the extra_ints and extra_floats structures */
void PrintProblemSpecificInfo(FILE * fp, Population * pop) /*;*/ /*funcdef*/
{
#ifndef _ICC
fprintf(fp,"\n");
#endif
}
/********************************************************************/
/* Called at the nodes if any pointer re-initialization needs to be done */
void InitFitnessCases(Population * pop)
{
}
/********************************************************************/
/* Used to create any random constants -- must match name in .h */
/*
float make_RandomFloat()
{
return((float) ((float)0.001 + (float) RandomFloat((float) 2.0)));
}*/
int make_RandomInt()
{
return((int) ((int) RandomInt(20)));
}
/********************************************************************/
/* DEFINITIONS OF GP FUNCTIONS*/
/* Each must start with a _start_def_func, and end with a
_end_def_func, and can use the _eval_subtree macro, the
_skip_subtree macro, the _eval_args macro, etc */
/************************* Creation Functions ***************************/
void split(Branch *br, int action) {
int child;
int parent;
int i, j;
StateInfo *child_ptr, *parent_ptr, *sister_ptr;
#if (STRACE)
printf("SPLIT - new node = %d\n", next_node_num);
#endif
/* start cut here */
if (!ready) {
ready = 1;
active_node = 0;
for (j = 0; j < NUM_INPUTS; j++) {
(*active_table).state[0].trans[j] = 0;
}
(*active_table).state[0].action = action;
/*Eval Subtrees*/
active_arc = ARC_A;
_eval_subtree(br,ppop);
active_arc = ARC_B;
_eval_subtree(br,ppop);
return;
}
/* end cut here */
parent = active_node;
child = next_node_num;
next_node_num++;
active_node = child;
parent_ptr = &((*active_table).state[parent]);
child_ptr = &((*active_table).state[child]);
sister_ptr = &((*active_table). state[((*parent_ptr).trans[active_arc])]);
for (i = 0; i < NUM_INPUTS; i++) {
(*child_ptr).trans[i] =
(*sister_ptr).trans[i];
}
(*child_ptr).action = action;
for (j = active_arc; j < NUM_INPUTS; j++) {
(*parent_ptr).trans[j] = child;
}
/*Eval Subtrees*/
active_arc = ARC_A;
_eval_subtree(br,ppop);
active_arc = ARC_B;
_eval_subtree(br,ppop);
active_node = parent;
}
_start_def_func(splitA)
split(br, ACTION_ACCEPT);
return((GTYPE) 1);
_end_def_func(splitA)
_start_def_func(splitR)
split(br, ACTION_REJECT);
return((GTYPE) 1);
_end_def_func(splitR)
_start_def_func(retract)
if (ready)
(*active_table).state[active_node].trans[active_arc] = active_node;
_eval_subtree(br,ppop);
return((GTYPE) 1);
_end_def_func(retract)
_start_def_func(done)
return((GTYPE) 1);
_end_def_func(done)
_start_def_func(write_node)
if ((stack_index < STACK_SIZE - 1) && ready) {
stack[stack_index++] = active_node;
}
_eval_subtree(br,ppop);
return((GTYPE) 1);
_end_def_func(write_node)
_start_def_func(to_node)
if ((stack_index > 0) && ready) {
(*active_table).state[active_node].trans[active_arc] = stack[stack_index];
stack_index--;
}
_eval_subtree(br,ppop);
return((GTYPE) 1);
_end_def_func(to_node)
_start_def_func(pops)
if ((stack_index > 0) && ready) {
stack_index--;
}
_eval_subtree(br,ppop);
return((GTYPE) 1);
_end_def_func(pops)
_start_def_func(dec)
if ((jump_index > 0) && ready) {
jump_index--;
}
_eval_subtree(br,ppop);
return((GTYPE) 1);
_end_def_func(dec)
_start_def_func(reset)
jump_index = stack_index;
_eval_subtree(br,ppop);
return((GTYPE) 1);
_end_def_func(reset)
_start_def_func(jump)
if ((jump_index > 0) && ready) {
if (jump_index > stack_index)
(*active_table).state[active_node].trans[active_arc]
= stack[stack_index];
else
(*active_table).state[active_node].trans[active_arc]
= stack[jump_index];
}
_eval_subtree(br,ppop);
return((GTYPE) 1);
_end_def_func(jump)
/*********************** BOOLEAN FUNCTIONS **************************/
_start_def_func(jand)
if (_eval_subtree(br,ppop))
{
return(_eval_subtree(br,ppop));
}
else
{
_skip_subtree(br);
return((GTYPE) 0);
}
_end_def_func(jand)
_start_def_func(jor)
if (_eval_subtree(br,ppop))
{
_skip_subtree(br);
return((GTYPE) 1);
}
else
{
return(_eval_subtree(br,ppop));
}
_end_def_func(jor)
_start_def_func(jnot)
return(!(_eval_subtree(br,ppop)));
_end_def_func(jnot)
/********************************************************************/
/* MORE STABLE FUNCTIONS __ OFTEN WILL NOT BE CHANGED BY USER */
/*This function is called when a random constant is evaluated*/
GTYPE random_func(Branch * br)
{
br->ind->index_ptr++;
return((GTYPE) (*ppop).constants[(int) br->tree[br->ind->index_ptr].opcode]);
}
GTYPE adf(Branch * br)
{
int opcode;
opcode = br->tree[br->ind->index_ptr].opcode;
(br->ind->index_ptr)++;
return(table[opcode].result);
}
GTYPE adf_arg(Branch * br)
{
return( ((*ppop).pop_globals.g_arg)[( (br->tree[(br->ind->index_ptr++)].opcode) -
MAX_NUM_ADFS) ]);
}
/********************************************************************/
/*This function sets up the function sets and declares the
functions. The first 4 lines should always be there.*/
void MakeFunctionTable(Population * pop) /*;*//*funcdef*/
{
_init_make_function_table_vars;
_init_make_function_table;
/*DECLARATIONS OF ADFS -- (MUST COME FIRST, IF ANY) */
/*name*/ /*code*/ /*weight*/
/*------------------------------*/
_declare_adf(adf0, adf, 1 );
_declare_adf(adf1, adf, 1 );
_declare_adf(adf2, adf, 1 );
/*DECLARATIONS OF DUMMY ARGS -- (MUST COME SECOND, IF ANY) */
/*name*/ /*code*/ /*weight*/
/*-----------------------------------*/
/*DECLARATIONS OF REGULAR FUNCTIONS -- COMES AFTER ADFS AND DUMMY_ARGS*/
/*code arity macro? weight printname*/
/*----------------------------------------------*/
_declare_func(jand, 2, 1, 1, and);
_declare_func(jor, 2, 1, 1, or);
_declare_func(jnot, 1, 1, 1, not);
_declare_func(splitA, 2, 1, 1, splitA);
_declare_func(splitR, 2, 1, 1, splitR);
_declare_func(retract, 1, 1, 1, retract);
_declare_func(write_node, 1, 1, 1, write_node);
_declare_func(to_node, 1, 1, 1, to_node);
/* _declare_func(pops, 1, 1, 1, pops);
_declare_func(dec, 1, 1, 1, dec);
_declare_func(reset, 1, 1, 1, reset);
_declare_func(jump, 1, 1, 1, jump);
*/
_declare_func(done, 0, 0, 1, done);
/*DECLARATION OF THE RANDOM FUNCTION, MUST ALWAYS be included! _declare_random(weight)*/
_declare_random(1);
/*DEFINITION OF FUNCTION SETS FOR EACH BRANCH. */
/*The following now specifies the INITIAL function_vectors*/
/*THE RPBs come first, then the ADFs*/
branchnum =0;
_start_def_func_set_for_branch(branchnum);
_use_adf(branchnum, "adf0",0);
_use_adf(branchnum,"adf1",0);
_use_adf(branchnum,"adf2",0);
_use_func(branchnum,"and");
_use_func(branchnum,"or");
_use_func(branchnum,"not");
for (branchnum = 1; branchnum <= MAX_NUM_ADFS; branchnum++) {
_start_def_func_set_for_branch(branchnum);
_use_func(branchnum,"splitA");
_use_func(branchnum,"splitR");
_use_func(branchnum,"retract");
_use_func(branchnum,"write_node");
_use_func(branchnum,"to_node");
/* _use_func(branchnum,"pops");
_use_func(branchnum,"dec");
_use_func(branchnum,"reset");
_use_func(branchnum,"jump"); */
_use_func(branchnum,"done");
}
}
/********************************************************************/
/* Evaluation of Individual*/
void PrintAutomata() {
int i, j;
printf("TRANSITION TABLE\n");
printf("----------------\n");
printf("\ta\tb\n");
printf("\t-\t-\n");
for (i = 0; i < next_node_num; i++) {
printf("%d\t", i);
for ( j = 0; j < NUM_INPUTS; j++) {
printf("%d\t", (*active_table).state[i].trans[j]);
}
printf("\n");
}
printf("\n\nACCEPTING STATES: ");
for (i = 0; i < next_node_num; i++) {
if ((*active_table).state[i].action == ACTION_ACCEPT) {
printf("%d ", i);
}
}
printf("\n\n");
}
/* Faster EVAL */
int EvalFitnessOfDude(Individual * ind,Population *pop)
{
int sum;
Branch * brs;
FitCaseInfo *current_case;
FitCaseInfo *last_case = &(fitness_cases[MAX_NUM_FIT_CASES - 1]);
int result;
TableType *last_table = &table[MAX_NUM_ADFS - 1];
int table_num;
CurrentDude = ind;
sum = 0;
ppop = pop;
PrintIndividual(ind, stdout);
/* Test();*/
/* Create Transition Tables */
for (table_num = 0; table_num < MAX_NUM_ADFS; table_num++) {
active_table = &table[table_num];
CreateTable(&ind->adfs[table_num]);
PrintAutomata();
}
for (current_case = &(fitness_cases[0]); current_case <= last_case;
current_case++) {
for (active_table = &table[0]; active_table <= last_table; active_table++) {
EvalTable((*current_case).string, (*current_case).length);
}
result = EvalBranch(ind->rpbs,pop);
if ((*current_case).valid) {
if (result) sum++;
}
else {
if (!result) sum++;
}
}
ind->hits = sum;
ind->s_fitness = (float) (MAX_NUM_FIT_CASES - sum);
}
void CreateTable(Branch* br) {
stack_index = 0;
jump_index = 0;
ready = 0;
next_node_num = 1;
(br->ind->index_ptr) = 0;
_eval_subtree(br ,ppop);
}
void EvalTable(int *string, int length) {
int *last_input;
int *input;
int current_state = 0;
last_input = &(string[length - 1]);
for (input = &(string[0]); input <= last_input; input++) {
current_state = get_transition(*active_table, current_state, *input);
/*printf("current state = %d\n", current_state);*/
}
(*active_table).result = (*active_table).state[current_state].action;
}
void Test() {
int i, j;
for (i = 0; i < MAX_NUM_ADFS; i++) {
for (j = 0; j < MAX_NUM_STATES; j++) {
table[i].state[j].action = 1;
}
}
}