/* lil-gp Genetic Programming System, version 1.0, 11 July 1995
* Copyright (C) 1995 Michigan State University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Douglas Zongker (zongker@isl.cps.msu.edu)
* Dr. Bill Punch (punch@isl.cps.msu.edu)
*
* Computer Science Department
* A-714 Wells Hall
* Michigan State University
* East Lansing, Michigan 48824
* USA
*
* This parallel version based on PVM is an extension of version 1.1
* of Lil-gp.
*
* Johan Parent (johan@info.vub.ac.be)
*
* Faculty of Applied Sciences (Engineering Faculty)
* Building K, Computer Science Department
* Vrije Universiteit Brussel
* Pleinlaan 2, 1050 Etterbeek
* Belgium
*
*/
#include <lilgp.h>
#ifdef _PARALLEL_H
event individual_send_event;
event individual_receive_event;
#endif
/* print_individual_stdout()
*
* prints the given individual to stdout. used with the "call" command
* in gdb (stdout is a #defined symbol and so is not available to the
* debugger, at least under Solaris...)
*/
void print_individual_stdout ( individual *ind )
{
print_individual ( ind, stdout );
}
/* print_individual()
*
* prints the given individual to the given FILE *.
*/
void print_individual ( individual *ind, FILE *f )
{
int j;
for ( j = 0; j < tree_count; ++j )
{
fprintf ( f, " %s: ", tree_map[j].name );
print_tree ( ind->tr[j].data, f );
}
}
/* pretty_print_individual()
*
* pretty-prints the individual to the given FILE *. shows expression
* structure via indentation.
*/
void pretty_print_individual ( individual *ind, FILE *f )
{
int j;
#ifdef _PARALLEL_H
if (f == NULL)
return;
#endif
for ( j = 0; j < tree_count; ++j )
{
fprintf ( f, "%s:", tree_map[j].name );
pretty_print_tree ( ind->tr[j].data, f );
}
}
/* individual_size()
*
* returns the total number of nodes in an individual.
*/
int individual_size ( individual *ind )
{
int j, k = 0;
for ( j = 0; j < tree_count; ++j )
k += ind->tr[j].nodes;
return k;
}
/* individual_depth()
*
* returns the depth of an individual (maximum of the depths
* of its trees).
*/
int individual_depth ( individual *ind )
{
int i, j, k = 0;
for ( j = 0; j < tree_count; ++j )
{
if ( ( i = tree_depth ( ind->tr[j].data ) ) > k )
k = i;
}
return k;
}
/* duplicate_individual()
*
* duplicates an individual.
*/
void duplicate_individual ( individual *to, individual *from )
{
int j;
for ( j = 0; j < tree_count; ++j )
copy_tree ( to->tr+j, from->tr+j );
to->r_fitness = from->r_fitness;
to->s_fitness = from->s_fitness;
to->a_fitness = from->a_fitness;
to->hits = from->hits;
to->evald = from->evald;
to->flags = from->flags;
}
#ifdef _PARALLEL_H
/* pack_individual()
*
* pack an individual in order to send it
*/
void pack_individual( individual *ind_ptr)
{
int i;
/* First pack the individual's information */
if (pvm_pkdouble(&(ind_ptr->r_fitness), 1, 1))
pvm_perror ("pack_individual() error packing \"r_fitness\"");
if (pvm_pkdouble(&(ind_ptr->s_fitness), 1, 1))
pvm_perror ("pack_individual() error packing \"s_fitness\"");
if (pvm_pkdouble(&(ind_ptr->a_fitness), 1, 1))
pvm_perror ("pack_individual() error packing \"a_fitness\"");
if (pvm_pkint(&(ind_ptr->hits), 1, 1))
pvm_perror ("pack_individual() error packing \"hits\"");
if (pvm_pkint(&(ind_ptr->evald), 1, 1))
pvm_perror ("pack_individual() error packing \"evald\"");
if (pvm_pkint(&(ind_ptr->flags), 1, 1))
pvm_perror ("pack_individual() error packing \"flags\"");
if (pvm_pkint(&(ind_ptr->current_exch), 1, 1))
pvm_perror ("pack_individual() error packing \"current_exch\"");
if (pvm_pkint(&(ind_ptr->new_trees), 1, 1))
pvm_perror ("pack_individual() error packing \"new_trees\"");
/* 2nd pack its trees */
for (i=0; i<tree_count; i++)
pack_tree(&(ind_ptr->tr[i]));
return;
}
/* unpack_individual()
*
* unpack an individual and allocates the memory for it ...
*/
void unpack_individual ( individual **ind_ptr )
{
int i;
individual *tmp_ind;
tmp_ind = (individual *) MALLOC (sizeof(individual));
tmp_ind->tr = (tree *) MALLOC (sizeof(tree)*tree_count);
/* First unpack the individual's information */
if (pvm_upkdouble(&(tmp_ind->r_fitness), 1, 1))
pvm_perror ("unpack_individual() error unpacking \"r_fitness\"")
;
if (pvm_upkdouble(&(tmp_ind->s_fitness), 1, 1))
pvm_perror ("unpack_individual() error unpacking \"s_fitness\"");
if (pvm_upkdouble(&(tmp_ind->a_fitness), 1, 1))
pvm_perror ("unpack_individual() error unpacking \"a_fitness\"");
if (pvm_upkint(&(tmp_ind->hits), 1, 1))
pvm_perror ("unpack_individual() error unpacking \"hits\"");
if (pvm_upkint(&(tmp_ind->evald), 1, 1))
pvm_perror ("unpack_individual() error unpacking \"evald\"");
if (pvm_upkint(&(tmp_ind->flags), 1, 1))
pvm_perror ("unpack_individual() error unpacking \"flags\"");
if (pvm_upkint(&(tmp_ind->current_exch), 1, 1))
pvm_perror ("unpack_individual() error unpacking \"current_exch\"");
if (pvm_upkint(&(tmp_ind->new_trees), 1, 1))
pvm_perror ("unpack_individual() error unpacking \"new_trees\"");
/* 2nd unpack it trees */
for (i=0; i<tree_count; i++)
unpack_tree(&tmp_ind->tr[i]);
/* 3d put into the pointer */
*ind_ptr = tmp_ind;
return;
}
/* send_individual()
*
* send an entire individual
*/
void send_individual ( int destination_node, int exch_id, int exch, individual *ind_ptr, int gen )
{
event start, stop;
#ifdef PDEBUG_INDIVIDUAL
printf("send_individiual() to %x\n", destination_node);
#endif
event_mark(&start);
pvm_initsend(ENCODING);
/* 1) pack the exchange identification */
if (pvm_pkint(&exch_id, 1, 1))
pvm_perror ("send_individual() error packing \"exch_id\"");
if (pvm_pkint(&exch, 1, 1))
pvm_perror ("send_individual() error packing \"exch\"");
if (pvm_pkint(&gen, 1, 1))
pvm_perror ("send_individual() error packing \"gen\"");
pack_individual(ind_ptr);
/* Send */
if (pvm_send (destination_node, IND_TAG))
pvm_perror ("send_individual() error sending");
event_mark(&stop);
event_accumdiff(&individual_send_event, &start, &stop);
#ifdef PDEBUG_INDIVIDUAL
printf("finished send_individual()\n");
#endif
}
/* receive_individual()
*
* receives an individual.
*/
void receive_individual ( int *exch_id, int *exch, individual **ind_ptr, int *gen )
{
event start, stop;
#ifdef PDEBUG_INDIVIDUAL
printf("receive_individiual()\n");
#endif
event_mark(&start);
/* 1) unpack the exchange identification */
if (pvm_upkint(exch_id, 1, 1))
pvm_perror ("send_individual() error unpacking \"exch_id\"");
if (pvm_upkint(exch, 1, 1))
pvm_perror ("send_individual() error unpacking \"exch\"");
if (pvm_upkint(gen, 1, 1))
pvm_perror ("send_individual() error unpacking \"gen\"");
/* First unpack the individual's information */
unpack_individual(ind_ptr);
event_mark(&stop);
event_accumdiff(&individual_receive_event, &start, &stop);
#ifdef PDEBUG_INDIVIDUAL
printf("finished receive_individual()\n");
#endif
}
/* get_individual_sent_event()
*
* returns the address of individual_send_event.
*/
event *get_individual_send_event ( void )
{
return &individual_send_event;
}
/* get_individual_receive_event()
*
* returns the address of individual_receive_event.
*/
event *get_individual_receive_event ( void )
{
return &individual_receive_event;
}
#endif