[comp.sources.misc] v07i079: Whales and Plankton, part 06/13

allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (07/19/89)

Posting-number: Volume 7, Issue 79
Submitted-by: loy@gtx.UUCP (Bob Loy)
Archive-name: whpl/part06

# whpl06of13.shar
#---cut here---cut here---cut here---cut here---cut here---
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files.
# This archive created: Sat Jan 14 04:04:34 MST 1989
export PATH; PATH=/bin:$PATH
echo shar: extracting "'whpl.c'" '(5128 characters)'
if test -f 'whpl.c'
then
	echo shar: will not over-write existing file "'whpl.c'"
else
sed 's/^X//' << \SHAR_EOF > 'whpl.c'
X
X/*---------------------------------------------------------------------------*
X *
X *   Copyright (c) 1987, 1988   Bob Loy
X *
X *   Please don't try to make money from whpl.c or associated files whpl.h,
X *       whx.c, genes.c, whio.c, or rando.c.  Also, don't be changing my
X *       name in this notice.
X *   Permission is otherwise granted to the user to freely delete or modify
X *       or add to any of the code in the above-named source files.
X *
X *   In other words, Experiment!
X *
X *---------------------------------------------------------------------------*/
X   char glsccsid[] = "  whpl.c     1.10  ";
X#ifndef lint
X   static char dateid[] = "    88/12/16  ";
X#endif
X/*@#==========================================================================*
X@@#
X@@@#   whpl.c
X@#
X@#  Purpose:
X@@#          A study of genetic algorithms in a model of a small ecology.
X@#
X@#  Options:
X@#     See comments in whio.c for command line options.
X@#
X@#  Example:
X@#     See comments in whio.c for command line examples.
X@#
X@#  Compiling:
X@#     cc -O whpl.c -c
X@#
X@#  Dependencies:
X@#     whpl.h, whx.c, genes.c, whio.c, rando.c
X@#
X@#  Subordinate To:
X@#     whx.c
X@#
X@#  Functions:
X@#     int     qhilo();
X@#     int     qlohi();
X@#     int     testloc();
X@#     void    quiklist();
X@#     Ushort  geneval();
X@#     int     boundstest();
X@#     void    clearlocarr();
X@#     void    loadsecarr();
X@#     int     countplank();
X@#     void    plankplace();
X@#     void    plankgrow2();
X@#     void    plankgrow1();
X@#     void    plankgrow();
X@#     void    countwhales();
X@#     int     whaleplace();
X@#     void    whaleload();
X@#     int     allsort();
X@#     void    whaledie();
X@#     void    enersave();
X@#     int     femsort();
X@#     int     collision();
X@#     int     attract();
X@#     void    hgjoin2();
X@#     void    hgjoin1();
X@#     void    fgjoin2();
X@#     void    fgjoin1();
X@#     void    mate();
X@#
X@#  General Comments:
X@#     See comments in whpl.h for how to extract a general overview of "Whales
X@#        & Plankton" from the source code; see comments in whx.c for how to
X@#        compile & run the program; see comments in whio.c for command line
X@#        examples and comments about file I/O; see comments in genes.c for
X@#        explanations of breeds and genes; and see individual functions for
X@#        more specific comments.
X@#     Notes on the state of the code:
X@#        Programming style
X@#           One of the intents for "Whales & Plankton" is as a platform for
X@#           experimentation.  To this end, I have attempted to use a fairly
X@#           simple style of C programming, one easy to modify.  I have rarely
X@#           put more than one statement per line, for example.  Also, for
X@#           readability, I have used array notation rather than pointer
X@#           notation, even for pointers not initially declared as arrays.
X@#           Although I think "whpl" may be a bit much for C-beginners to
X@#           modify, it is not, all in all, a deeply complex program.  For
X@#           flexibility in experimentation, a great deal can still be done
X@#           at simpler levels of modification:
X@#              1) command line options,
X@#              2) modification of constants in whpl.h, and
X@#              3) minor changes & additions to the switch-statement in the
X@#                 do-loop at the bottom of main() in whx.c.
X@#           One other thing:  There are no tabs in this code.  I hate tabs.
X@#        Portability considerations:
X@#           This may be another matter.  Writing whpl was a big enough task
X@#           that I took advantage of whatever library functions were available
X@#           under Sun Unix, such as qsort() & getopt(), which may not be in
X@#           everybody's package.  I also use the math library, but only (I
X@#           believe) for one call to log() in lastuff(), which may be hacked
X@#           out, as it is only used for computing a 'rating' of doubtful
X@#           accuracy.  Other simple supports of portability have also been
X@#           ignored (sorry) such as judicious replacement of ints with shorts
X@#           or longs.  Video incompatibilities, at least, should be avoidable
X@#           by turning off the SUN compile flag.
X@#        State of the code  (version 1.10):
X@#           This is "mature code", which can be both good and bad.  It has
X@#           been tested since version 1.08 through almost 300 hours worth
X@#           of runs, all of which have exercised movewhale() and mate(), the
X@#           most complex functions.  On the other hand, There may be a few
X@#           too many lazy globals around by now, some of the functions have
X@#           started getting conditioning parameters passed to them, and others
X@#           are getting pretty big.  More data-hiding handler functions for
X@#           some of the structures and file I/O may also be in order.  In
X@#           short, it may not yet be due for a rewrite, but the first signs
X@#           of creeping spaghettiness have started showing up.
X@#
X@#---------------------------------------------------------------------------*/
SHAR_EOF
if test 5128 -ne "`wc -c < 'whpl.c'`"
then
	echo shar: error transmitting "'whpl.c'" '(should have been 5128 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'whx.c'" '(19370 characters)'
if test -f 'whx.c'
then
	echo shar: will not over-write existing file "'whx.c'"
else
sed 's/^X//' << \SHAR_EOF > 'whx.c'
X
X/*---------------------------------------------------------------------------*
X *
X *   Copyright (c) 1987, 1988   Bob Loy
X *
X *   Please don't try to make money from whpl.c or associated files whpl.h,
X *       whx.c, genes.c, whio.c, or rando.c.  Also, don't be changing my
X *       name in this notice.
X *   Permission is otherwise granted to the user to freely delete or modify
X *       or add to any of the code in the above-named source files.
X *
X *   In other words, Experiment!
X *
X *---------------------------------------------------------------------------*/
X#ifndef lint
X   static char sccsid[] = "  whx.c     1.14  ";
X   static char dateid[] = "    88/12/18  ";
X#endif
X/*@#==========================================================================*
X@@#{
X@@@#   whx.c
X@#@^
X@#  Purpose:
X@@#          Execute routines for whpl.c and assoc. files.  Contains main().
X@#
X@#  Options:
X@#     See comments at top of whio.c for command line options.  See also
X@#        ophandle() in that file for flag names, settings, etc.
X@#
X@#  Examples:
X@#     See comments in whio.c for command line examples.
X@#
X@#  Compiling:
X@#     cc -O whx.c whpl.o genes.o whio.o rando.o -o whx -lm
X@#        or:
X@#     cc -O -DSUN whx.c whpl.o genes.o whio.o rando.o -o whx -lm -lpixrect
X@#        (for display on Sun workstations like the 3/50)
X@#
X@#  Dependencies:
X@#     whpl.h, whpl.c, genes.c, whio.c, rando.c
X@#
X@#  Functions:
X@#     void    finish();
X@#     void    interim();
X@#     void    plankcall();
X@#     void    movewhale();
X@#     void    main();
X@#
X@#  General Comments:
X@#     See comments in whpl.h for how to extract a general overview of "Whales
X@#        & Plankton" from the source code; see comments in whio.c for more
X@#        command line examples and more comments about file I/O; and see
X@#        comments in genes.c for explanations of breeds and genes.
X@#     Running this program:
X@#        The simplest thing to type would be the name of the program by
X@#        itself: "whx".  This would create a run based on constants in the
X@#        header file whpl.h.  A Two-dimensional array covering the "planet"
X@#        Wa-Tor would be created of size AREA and heigth VBIAS.  This would
X@#        then be randomly filled with plankton for the whales to feed on.
X@#        Then a count of NUMWH whales would be created with random genesets
X@#        (even-numbered whales (including #0) would be female; odd, male)
X@#        and they would start 'swimming' around the array hunting for, and
X@#        feeding off of the plankton, which would periodically regrow when
X@#        they were too completely diminished.  If running on a Sun, and
X@#        compiled with the proper flags & library, this plankton diminish/
X@#        regrow cycle would be periodically displayed.
X@#     Based on a do-loop in the main() function, sometimes the weaker whales
X@#        (the ones not eating very much plankton) would be eliminated.  Other
X@#        times in that loop, the mate() function would be called to create
X@#        new offspring containing a mixture of genes from their parents.
X@#        After a period of time governed by MONTHS, the program would finish,
X@#        and four files would be written out.  The three important ones:
X@#           whs120000 - a statistics file rating the whales from best to least
X@#           whc120000 - a file of all the details of all the whales
X@#           wha1200   - an archive file with ID's of the whales of this run
X@#     While all this is going on, there'll also be text output on the screen:
X@#
X@#             RUN  2088120000
X@#
X@#           Number of whales to be newly created: 25  [equals constant NUMWH]
X@#
X@#             Seeded plankton          =    3871
X@#             Final initial plankton   =   82829
X@#
X@#           Conditioning world for six months
X@#                1
X@#                2                                           [counts by ones]
X@#                :
X@#           whaledie():  enerquar =  981734    [lowest quartile energy level]
X@#           mate():  year is 1    [presently set at 6 months between matings]
X@#           whaledie():  enerquar =  989386
X@#           mate():  year is 2
X@#                 :                            [and so on up to program exit]
X@#                 :
X@#           Final whale moves for twelve months
X@#                2
X@#                4                                           [counts by twos]
X@#                :
X@#           whaledie():  enerquar =  984164
X@#
X@#           DONE
X@#
X@#        Note:  Whales below the enerquar level are killed off.
X@#     With NUMWH set to 25 and MONTHS set to 30 (both in whpl.h), a run
X@#        should take about two hours on a Sun 3/50.
X@#     Obviously, changes in the values of the defined constants in whpl.h,
X@#        and/or changes to the do-loop in main(), will change the parameters
X@#        of the run.  But there is also a third way, using command line
X@#        modifiers (options).  These are covered in detail in whio.c, but
X@#        let's look at the main ones here.  For example, to continue from the
X@#        above run, this command line might be used:
X@#@^         whx -i whc120000 -r 2 -k -d 2
X@#@^      The -i opt specifies a file of whales to be read into the program,
X@#@^      instead of having whales created from scratch.  The new run would
X@#@^      take place with the previous whales, and the output files would be
X@#@^         whs120002 - the stat file
X@#@^         whc120002 - the whale file
X@#@^         wha1200   - the previous archive file with ID's of the whales of
X@#@^                        this latest run appended to the end of it
X@#@^      note the "2" argument to the -r opt created a new filename, keeping
X@#@^      the previous run's files from being overwritten.  The -k opt kills
X@#@^      the screen display, and makes the program run faster.  The -d2 opt
X@#@^      stops all terminal output except for error messages on stderr.
X@#@^   The numeric parts of the above files are based on the constant DATRUN,
X@#@^      defined in whpl.h, and the command line input from the  -r option.
X@#@^      I usually define DATRUN with part of a date (eg, 2088120000 for
X@#@^      "December 1988"), recompile, and then modify the filenames for
X@#@^      the rest of the month from the command line (eg, -r2501 , the first
X@#@^      run of December 25).  The archive file wha1200 then lasts for the
X@#@^      whole month.
X@#@^   Note: This  DATRUN plus -r opt  value is also used as the first part
X@#@^      of the unique ID for each whale.  Therefore the whale name is linked
X@#@^      to the files from the run it was first created or spawned in.  See
X@#@^      note on the "Whale ID string" in function fileout() whio.c for more
X@#@^      info on the whale ID.
X@#     Back to running the program:  With the -i option available, it is pos-
X@#        sible to keep track of a long history of breeding from an original
X@#        set of whales.  But this may involve many read-run-output cycles.
X@#        There is another option, -y, which allows for continuous runs.  It
X@#        determines how many mate cycles to go through before finishing.
X@#        There is a 'granularity' involved with the -y opt; it may create a
X@#        few more generations than specified (never less); see the comments
X@#        and code in main(), for more about how the variables "months,"
X@#        "year," and "cycle" affect this option.
X@#     A large -y argument may be used to set up an overnight run, say, of
X@#        many generations.  If the number of whales grows too near the max-
X@#        imum limit (254 in version 1.10), interim files will be written out,
X@#        and then the dead whales will be removed to make room for more live
X@#        ones.  An interim file name is the same as the final name, but with
X@#        two letters appended, e.g., whs120002aa and whc120002aa, whs120002ab
X@#        and whc120002ab, and so on.  Interim files can be written more freq-
X@#        uently, if so desired, by decreasing the defined value of INTERLIM
X@#        in whpl.h, or using -p command line option.
X@#     This should be enough for a start.  There are many other options des-
X@#        cribed in whio.c, which modify number and breed of whales, file I/O,
X@#        and screen and terminal display and messages.  Even more subtle mod-
X@#        ifications can be made by changing the whpl.h header file defines,
X@#        but the user should always check first to see if there is an easier
X@#        way to get the same result via the command line options.
X@#     Some more on the main program loop:
X@#           Besides the main control do-loop in main(), two other loops affect
X@#        whale movement, one just before the do-loop, and one just after it.
X@#        These are 'conditioning' loops.  The first one, controlled by var-
X@#        iable "pre", conditions the world for some months of whale moves to
X@#        'tune' it to the set of whales in the run.  The original growth of
X@#        plankton creates a pretty good random world, But it may give some
X@#        whale's genesets a slight advantage.  This preconditioning prior to
X@#        any mating should remove such advantages.
X@#           The second loop, controlled by variable "post", also contains no
X@#        mating, and is meant to try to give each whale a fair chance of
X@#        reaching it's final energy level, and hence, it's final rank.
X@#           The number of times to run each of these conditioning loops, and
X@#        indeed the number of 'months' between calls to mate() in the do-loop
X@#        are set very conservatavely.  For most genesets, the best whales
X@#        seem to pull ahead pretty quickly regardless of the dispersion of
X@#        plankton (and therefore get the best chances to mate).  So runs
X@#        can probably be made to take much less computer time and still do a
X@#        good job of natural selection on the whales.
X@#           I would recommend to even the non-C-programmer, that modifying
X@#        these sections of the main() function can be very useful for experi-
X@#        mentation.  Careful study (and backing up for safety) of the code
X@#        should make it clear how to do so correctly.
X@#     Just a few more details:
X@#        The fourth file output is a compression of the graphics display and
X@#           is named "world."  In v1.10, there is no way to read this file
X@#           back in again.  If you don't want this file always getting dumped,
X@#           comment out or remove its call from finish().
X@#        The -w option quickly creates a file of "blank" 'live' whales with
X@#           only genes initialized.  Remember to give -w a numeric argument
X@#           for the number of whales, or the next command line opt following
X@#           it may be improperly processed.
X@#        The -t option can be used to show the 'tracks' of individual whales.
X@#           A normal run of hunt/feed/die/mate cycles doesn't happen when
X@#           this option is in effect.  The same is true for the -w option.
X@#        On mixing breeds within the same run:
X@#              This is supported in v1.10, but is a fairly late development
X@#           and not exhaustively tested.  If breeds are too different, it may
X@#           not make much sense to have them mate, so the whpl.h constants
X@#           INBREED1 INBREED2 & TOCLONE are checked in mate() and its asso-
X@#           ciated functions to control the degree of inbreeding allowed.
X@#              Also, since the genes of some genesets tend to make more whale
X@#           location changes than others, it may not be too fair to compare
X@#           them head to head.  To try to even up the playing field, the
X@#           constant NORMAL can be set to 1 in whpl.h, and this will change
X@#           the algorithm in movewhale() to make all whales have the same
X@#           number of moves per turn.  That is, some breeds may have more
X@#           than one gene firing per turn with NORMAL equal to one.
X@#     And finally, a note about the five utility programs:
X@#        sortcount.c - A general-purpose program for counting live, dead,
X@#           male, and/or female whales, and re-writing same into new files,
X@#           if so desired.  Can process several input files at once.
X@#        enerank.c - Creates a new file of whales based on value of either
X@#           energy or percentile rank of the whales in the file(s) input to
X@#           the program.
X@#        dealwh.c - 'Deals' the whales from a single input file to multiple
X@#           output files (up to 16).  A utility for mixing and merging whales
X@#           from several runs into starting files for further runs.
X@#        statgene.c - Reports the relative frequency of the various huntgenes
X@#           and feedgenes of whales.  Useful for tracking which genes are
X@#           selected over a period of time.  Can process several input files
X@#           at once.
X@#        symmet.c - Since each group of 16 genes in a geneset (breed type)
X@#           of 64 are identical, except for the direction they move whales
X@#           in (see comments in genes.c), this utility can make a set of
X@#           whales more "symmetrical," by cloning the input whales into
X@#           three more whales with their genesets "rotated" 90, 180, and 270
X@#           degrees.
X@#              Also, another non-symmetry is built in to whpl.c by virtue
X@#           of the fact that males and females have somewhat different
X@#           mating opportunities.  So symmet.c also contains an option to
X@#           clone whales with identical genesets but of opposite sex.
X@#              In other words, this is a program for those who are fanatical
X@#           about giving each gene an equal chance of expression, at the
X@#           expense of making whpl.c run a little less 'naturally.'
X@#              This utility can process only one input file at a time.
X@#        For all these utilities, more specific information can be found
X@#           within their specific source files.  The programs are sort of
X@#           hacks, but they get their respective jobs done.
X@#}
X@#---------------------------------------------------------------------------*/
X
X/*---------------------------------------------------------------------------*
X Top-level Declaration - includes, externs & globals.
X*----------------------------------------------------------------------------*/
X
X#include "whpl.h"
X
X            /* EXTERNS FROM */
X
X      /* Functions From rando.c: */
X   extern  short   nextrand();
X   extern  void    randinit();
X
X      /* Variables From whio.c: */
X   extern  char    wharcfile[];
X   extern  char    chapend[];
X   extern  char    chappend[];
X   extern  short   wharcflg;
X   extern  short   yearflg;
X   extern  short   trakflg;
X   extern  int     interlim;
X   extern  Uint    initwh;
X   extern  Uint    numwh;
X   extern  Uint    truwh;
X   extern  Uint    malwh;
X   extern  Uint    femwh;
X   extern  short   created;
X   extern  int     regrow;
X   extern  int     stopgrow;
X
X      /* Functions From whio.c: */
X   extern  void    ophandle();
X   extern  void    printscreen();
X   extern  void    saveworld();
X   extern  void    listout();
X   extern  void    fileout();
X   extern  void    lastuff();
X   extern  void    whaleinit();
X   extern  void    look();
X
X      /* Variables From genes.c: */
X   extern  short   randflg;
X   extern  int     mvwhle[];
X   extern  long    aiches;
X   extern  long    effs;
X
X      /* Functions From genes.c: */
X   extern  void    genesets();
X
X      /* Variables From whpl.c: */
X   extern  int     dielim;
X   extern  int     debug;
X   extern  Uint    daterun;
X   extern  Uint    hgpcflg;
X   extern  Uint    fgpcflg;
X   extern  Uchar  *locarr;
X   extern  Uchar  *secarr;
X   extern  Uint    area;
X   extern  Uint    vbias;
X   extern  whale_type   *whale;
X   extern  Uint    whale_size;
X   extern  int     year;
X
X      /* Functions From whpl.c: */
X   extern  void    countwhales();
X   extern  void    clearlocarr();
X   extern  void    plankplace();
X   extern  int     countplank();
X   extern  void    plankgrow();
X   extern  void    plankgrow();
X   extern  int     whaleplace();
X   extern  void    mate();
X   extern  void    whaledie();
X
X
X/*---------------------------------------------------------------------------*
X@^
X@@^ void  finish(parm) - Calling routine for last stuff & I/O at end of run.
X@@^             Input parameter > 1 is passed on to exit().
X@^  input :  Input parameter:
X@^              0     if normal end of program
X@^              1     normal end of program with saveworld() call desired
X@^              > 1   if dumping files due to some internal problem...
X@^                    ...as of version 1.10:
X@^                 3     no live males left to mate with in mate()
X@^                 4     no live females left to mate with in mate()
X@^                 5     way too many males near one location in mate()
X@^                 6     problems in counting live whales in interim()
X@^                 7     problems reallocating whales in interim()
X@^                 8     non-whale calloc(), malloc(), realloc() problems
X@^                 9     whale calloc(), malloc(), realloc() problems in all
X@^                           functions other than interim()
X@^                10     old (fixed) bug; problems in enersave() algorithm
X@^              Note: errors 5 & 6 are not actual bug errors; in normal
X@^                    operation of whpl, the random nature of events may
X@^                    serve to deplete the male or female populations
X@^              Note: parm  0 passed from main() under  -w  cmnd line opt;
X@^                    parm 1 passed from main() at end of usual run
X@^  Note  :  parenthetically, other exit values from the whpl programs (v1.10):
X@^              exit(0)  =  normal termination
X@^              exit(1)  =  not used
X@^              exit(2)  =  cmnd line input error
X@^              exit(20) =  input whale file not standard
X@^              exit(21) =  program constants have illegal values
X@^              exit(22) =  program variables mungged
X@^              exit(23) =  function parameters have illegal values
X@^              exit(24) =  function variables mungged
X@^  output:  Programs it calls handle the run's file output
X@   caller:  interim(), mate(), main()
X@   calls :  countwhales(), lastuff(), fileout(); exit(),
X@               may call listout(), saveworld()
X@
X@*---------------------------------------------------------------------------*/
X 
Xvoid
Xfinish(parm)
X  short   parm;
X{
X  if (parm > 1)
X      if (debug >= 6)
X          listout();
X  countwhales();
X  if(truwh != malwh + femwh)
X    {
X      if (debug >= 2)
X          fprintf(stderr, "finish(): truwh != malwh + femwh; %4d != %4d\n",
X                  truwh, malwh + femwh);
X      truwh = malwh + femwh;
X    }
X  truwh = malwh + femwh;
X  lastuff(0);
X  fileout(0);
X  if (parm > 0)
X      saveworld();
X  free((char*) whale);
X  if (parm > 1)
X    {
X      if (debug >= 5)
X        {
X          fprintf(stderr, "\nDONE -- with INTERRUPTION\n");
X          fprintf(stderr, "\n");
X          fprintf(stderr, "     exit value:  %d\n", parm);
X          fprintf(stderr, "\n");
X        }
X      exit(parm);
X    }
X  else
X    {
X      if (debug >= 5)
X        {
X          fprintf(stdout, "\nDONE\n");
X          fprintf(stdout, "\n");
X        }
X      exit(0);
X    }
X}
SHAR_EOF
if test 19370 -ne "`wc -c < 'whx.c'`"
then
	echo shar: error transmitting "'whx.c'" '(should have been 19370 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0
---

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                |
             Bob Loy            |     Life is the detour you take on the
    ...!sun!sunburn!gtx!loy     |     way to where you're really going.
                                |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~