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. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~