Code archives/3D Graphics - Misc/Genetic Algorithm

This code has been declared by its author to be Public Domain code.

Download source code

Genetic Algorithm by kevin80842006
This program demonstrates a simple genetic algorithm code that tries to evolve the perfect creature. Nothing fancy and not optimized. Very easy and fun to write. I'm having thoughts of an Evolution game here :)
Enjoy!
; **************************************************************************************************
; Critters by Kevin Lee Legge (kevin8084@gmail.com)
; **************************************************************************************************
;
; This program is an experiment in genetic algorithms that attempts to combine random chromosomes
; to create a perfect artificial life with these requirements:
; For Male:
; 1. The red color must be 255
; 2. The blue and green colors must be 0
; 3. The sex must be 0
;
; For Female:
; 1. The red and blue colors must be 0
; 2. The green color must be 255
; 3. the sex must be 255
;
; If the above requirements are met (either for male or female) then the solution is found.
;
; Description of chromosome used
;
; 0000 0000 0000 0000
;
; This is a 16-bit chromosome divided into 4-bit segments. Each 4-bit segment is a gene.
; The first segment is the red color segment
; The second segment is the green color segment
; The third segment is the blue color segment
; The fourth segment is the sex segment
; 
; Quick primer on binary numbers:
; The name "binary" comes from the fact that this is a base-2 number system. That is, there are
; only two numbers used in it. In this case, those two numbers are 1 and 0
; Binary numbers are read from the right to the left - the right being the lowest and the left
; the highest.
; The numbers below represent an 8-bit binary system. Each of the numbers are powers-of-2
; That is: 2^0=1 2^1=2 2^2=4 2^3=8 2^4=16 2^5=32 2^6=64 2^7=128
;
; 128  64  32  16  8  4  2  1
;
; The highest number that can be stored in an 8-bit number is 255. Why?
;  1  1  1  1  1 1 1 1 = 255
; 128+64+32+16+8+4+2+1 = 255
;
; If you have the binary number 01100101 can you figure out the decimal equivalent?
;
; 128 64 32 16 8 4 2 1
;  0  1  1  0  0 1 0 1 = 64+32+4+1 = 101 (that's one hundred one)
;
; The binary number 10110000 = ?
;
; 128 64 32 16 8 4 2 1
;  1  0  1  1  0 0 0 0 = 128+32+16 = 176
;
; **************************************
; Genetic Algorithm Theory in a nutshell
; **************************************
;
; First, let's start with a short story
;
; A long time ago there were creatures that looked like whales but lived on the land. They were happy
; creatures for thousands of years but then they noticed that food was getting a bit scarce. Well,
; that was ALMOST true. Food was still plentiful in the oceans. This didn't do the land whales any
; good, though, because they were afraid of the water. One day a baby land whale was born that rather
; ENJOYED the water. The baby, Billy, could only wade out a little way and splash happily while the 
; other land whales all looked on and shook their heads. When the baby grew up, he met a nice female 
; land whale, Suzie, who didn't mind his odd liking of the water. Time passed and the couple had a 
; cute, little baby, Joey. What was THIS? The new baby land whale ALSO liked the water. Though the 
; land whales didn't know it, the first land whale to like the water, Billy, did so because of a 
; mutated gene. This mutation was then passed on to his baby. Well, in another village there was 
; another baby land whale, Cindy, who had longer fingers and broader hands than any other land whales. 
; These would make swimming very easy if this land whale liked the water. Cindy did not, however. 
; Well, more time passed and one day Cindy and Joey met and fell in love. One thing led to another
; and before you knew it, they had a brand new addition to the family - Oscar. Oscar was a puzzle to
; all of the other land whales. He had long fingers, broad hands, AND he liked the water. He was very
; popular with the girl land whales who enjoyed watching him swimming with broad, powerful strokes.
; His unusual hands enabled him to speed through the water as fast as any fish.
;
; We could continue with the story but it is not necessary. The point is that if you combine
; a mutated chromosome with a normal one, the child of such a joining may have that mutated chromosome,
; and if you combine TWO mutated chromosomes, the children just may have both of the mutations.
;
; In genetic algorithm theory, you start off with a population of random chromosomes of a certain length.
; This length can be anything that you like. Each chromosome is divided into different segments, each
; of which describes a specific attribute. These divisions are the "genes".
; When you have your random population of chromosomes, you then check the "fitness" of each gene.
; The fitness is determined by how close the gene comes to solving the problem (of what you are
; looking for.)
; After you have calculated the fitness of all of the genes/chromosomes, you then select two of the
; fittest by using whatever selection process you want. In this case, we are going to use the Roulette
; Selection. Basically this is like playing roulette - wherever the ball lands is which chromosome we
; pick. The wheel is loaded in favor of the fittest chromosomes, however, which take the largest portion
; of the wheel.
; Now that we have our roulette-chosen chromosomes we need to recombine them to form new chromosomes.
; We do this by randomly picking a spot on the chromosome and then swapping all of the genes AFTER that
; point with each other. As an example, suppose we have these two chromosomes:
; 1101001001100101
; 0110100111000011
; and suppose we have randomly picked the number 7 as the swap point. The chromosomes, just prior to
; the swap look like this:
; 1101001 001100101
; 0110100 111000011
; Notice how they are split at the 8th bit - just after the swap point?
; After swapping the bits, they are now:
; 1101001 111000011
; 0110100 001100101
; 
; 1101001001100101 -> 1101001111000011
; 0110100111000011 -> 0110100001100101
; This is called "Crossover", which is simply recombining two chromosomes with each other.
; The rate of crossover is about 0.7. When you generate a random number and check it with
; this rate, if the random number is LESS than the crossover rate, then do the crossover. Otherwise,
; don't do it.
; Finally we mutate the chromosome. The mutation rate varies but it is between .1 and .001. I prefer to 
; use .001 as 1 in 1,000 is a more realistic mutation rate than 1 in 10.
; To mutate the chromosome you iterate through each bit and flip it from a 1 to 0 or 0 to 1 if a
; random number is less then the mutation rate.
; From here you repeat from the calculation of fitness routine until either a chromosome evolves that
; meets your requirements, or until the maximum number of generations is exceeded - in which case the
; solution was not found.

Graphics3D 800,600
SetBuffer BackBuffer()

SeedRnd MilliSecs()

Const player_type=1
Const ground_type=2

Const POPULATION_SIZE	=100 ; we are going to create 100 chromosomes at a time
Const CROSSOVER_RATE#	=0.7 ; .7 is the normal crossover rate when recombining genes
Const MUTATION_RATE#	=0.01; we are going to use this for a 1 in 1000 rate
Const CHROMOSOME_LENGTH	=16  ; our chromosomes are going to be 16-bit binary numbers
Const GENE_LENGTH	=4   ; 4-bit segment lengths for each gene
Const MAX_GENERATIONS	=500 ; going to allow a maximum generation rate of 500

Global rCount,gCount,bCount	; red, green, and blue counter
Global sex					; 0=male,15=female
Global bFound = False       ; used as flag for perfect chromosome found
Global generations = 0      ; counter for how many generations program ran
Global tempGenerations = 0  ; same as above
Global maleCount,femaleCount; not needed
Global offspring1$,offspring2$ ; holds 16-bit chromosome children

Type chromosome
	Field bits$ 	; this holds the 16-bit binary string
	Field fitness#  ; holds the fitness number
End Type

; this is our main chromosome
Global Population.chromosome[POPULATION_SIZE]
; this is a temporary chromosome used to evolve children chromosomes
Global temp.chromosome[POPULATION_SIZE]

Global buffer=CreateBank(CHROMOSOME_LENGTH*4) ; holds decimal conversion of each gene

Global sphere=CreateSphere() ; our male entity's body
HideEntity sphere

Global cube=CreateCube()     ; our female entity's body
HideEntity cube

Global camera=CreateCamera()
CameraRange camera,.1,500
CameraZoom camera,1.6
PositionEntity camera,0,1,0
EntityRadius camera,1
EntityType camera,player_type


Global light=CreateLight()

Global ground=CreatePlane()
PositionEntity ground,0,0,0
EntityColor ground,100,50,10
EntityType ground,ground_type

Collisions player_type,ground_type,2,2

createChromosomes() ; See if the monster lives

MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
HidePointer

While Not KeyHit(1)
If KeyDown(200) Then MoveEntity camera,0,0,1
If KeyDown(208) Then MoveEntity camera,0,0,-1
If KeyDown(203) Then MoveEntity camera,-1,0,0
If KeyDown(205) Then MoveEntity camera,1,0,0

TranslateEntity camera,0,-1,0
mxs#=-MouseXSpeed()/4.0
mys#=MouseYSpeed()/4.0
MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
TurnEntity camera,mys#,mxs#,0
RotateEntity camera,EntityPitch#(camera),EntityYaw#(camera),0
If EntityPitch#(camera)>69 Then RotateEntity camera,69,0,0
If EntityPitch#(camera)<-69 Then RotateEntity camera,-69,0,0


UpdateWorld
RenderWorld
Text 0,0,"Looking for perfect red male or perfect green female..."
If Not bFound Then
	Text 0,10,"No solution found in "+(tempGenerations-1)+" generations."
Else
	Text 0,10,"Solution found in "+(tempGenerations-1)+" generations."
End If

Flip
Delay 10
Wend
FreeBank buffer
End


; **************************************************************************************************
;                                           FUNCTIONS
; **************************************************************************************************

Function createChromosomes()
; this function initializes the chromosomes
While Not bFound ; while perfect chromosome is not found
generations = generations+1 ; increment the generation counter
tempGenerations = generations
If generations > MAX_GENERATIONS Then Return ; if we exceed the maximum generation count, then return
totalFitness#=0.0
For i=0 To POPULATION_SIZE-1 ; POPULATION_SIZE is the size of the population
	Population[i]=New chromosome ; create a new chromosome
	Population[i]\bits$=randomBits(CHROMOSOME_LENGTH) ; get random bits for the chromosome
	parseBits(Population[i]\bits$,buffer)         ; parse the bits - translate from binary to decimal
	Population[i]\fitness#=calculateFitness()     ; get the fitness count for the chromosome
	If Population[i]\fitness#=999.0 Then bFound = True:Return ; we found the perfect chromosome
	
	totalFitness#=totalFitness#+Population[i]\fitness#    ; accumulative count of fitness
Next
 
nPop=0 ; population counter
While nPop < POPULATION_SIZE
temp[nPop]=New chromosome ; create a new chromosome
offspring1$=rouletteSelection(totalFitness)  ; select the fittest chromosome
offspring2$=rouletteSelection(totalFitness)  ; again, select the fittest chromosome
CrossOver(offspring1$,offspring2$)           ; recombine the two fittest chromosomes
Mutate(offspring1$)                          ; mutate
Mutate(offspring2$)                          ; mutate
temp[nPop]\bits$=offspring1$                 ; store offspring1
temp[nPop]\fitness#=0.0                      ; zero out the chromosome's fitness value
nPop = nPop+1                                ; increment the counter
temp[nPop]=New Chromosome                    ; create a new chromosome
temp[nPop]\bits$=offspring2$                 ; store offspring2
temp[nPop]\fitness#=0.0                      ; zero out the chromosome's fitness value
nPop = nPop+1                                ; increment the counter
Wend
For i=0 To POPULATION_SIZE-1
	Population[i] = temp[i]                  ; store temp in Population
	parseBits(Population[i]\bits$,buffer)    ; parse the bits - translate from binary to decimal
	Population[i]\fitness#=calculateFitness(); get the fitness count for the chromosome
	If Population[i]\fitness#=999.0 Then bFound=True:Return
	totalFitness#=totalFitness#+Population[i]\fitness#
Next

nPop=0 ; population counter
While nPop < POPULATION_SIZE
temp[nPop]=New chromosome ; create a new chromosome
offspring1$=rouletteSelection(totalFitness)  ; select the fittest chromosome
offspring2$=rouletteSelection(totalFitness)  ; again, select the fittest chromosome
CrossOver(offspring1$,offspring2$)           ; recombine the two fittest chromosomes
Mutate(offspring1$)                          ; mutate
Mutate(offspring2$)                          ; mutate
temp[nPop]\bits$=offspring1$                 ; store offspring1
temp[nPop]\fitness#=0.0                      ; zero out the chromosome's fitness value
nPop = nPop+1                                ; increment the counter
temp[nPop]=New Chromosome                    ; create a new chromosome
temp[nPop]\bits$=offspring2$                 ; store offspring2
temp[nPop]\fitness#=0.0                      ; zero out the chromosome's fitness value
nPop = nPop+1                                ; increment the counter
Wend

Wend
End Function


Function randomBits$(length)
; returns a string of random bits of length "length"
For i=1 To length
	If Rnd(0,1) > .5 Then ; if random number is greater than .5 then
		tempString$=tempString$+"1" ; add a 1 to the string
	Else
		tempString$=tempString$+"0" ; else add a 0 to the string
	End If
Next
Return tempString$
End Function

Function binary2Decimal%(bits$)
; this function converts the binary string to its decimal equivalent
val=0
value_added=1
For i=Len(bits$) To 1 Step-1
	If Mid$(bits$,i,1)="1" Then
		val=val+value_added
	End If
	value_added = value_added*2
Next
Return val
End Function

Function parseBits%(bits$,buf)
; this function parses the bits and checks for red, green, blue, and sex component values
cBuf=0
this_gene=0
bRed=True ; first number in bank is red component
bGreen=False ; second number in bank is green component
bBlue=False  ; third number in bank is blue component
bSex=False   ; fourth number in bank is sex component
For i=1 To CHROMOSOME_LENGTH Step GENE_LENGTH
	bogus=False
	this_gene=binary2Decimal(Mid$(bits$,i,GENE_LENGTH)) ; convert the chromosome string to its decimal values
	If bRed=True Then ; are we on the red component?
		PokeInt buf,cBuf,this_gene ; yes, then poke the value into the bank
		cBuf=cBuf+4 ; increment counter by 4 - because we are poking ints
		bRed=False  ; set flag to false because we are done checking the red component
		bGreen=True ; set to true because next component to check is green
		bogus=1     ; this emulates the "continue" statement of other languages
	End If
	If bGreen = True And bogus=False Then ; if we are on the green component and not midway through the loop
		PokeInt buf,cBuf,this_gene        ; then poke the green value into the bank
		cBuf=cBuf+4                       ; increment the counter for next position in the bank
		bogus=1                           ; continue from beginning of "For" statement
		bGreen=False                      ; we are done with green
		bBlue=True                        ; next we check the blue component
	End If
	If bBlue=True And bogus=False Then    ; if blue component and not midway through the loop then
		PokeInt buf,cBuf,this_gene        ; poke the blue value into the bank
		cBuf=cBuf+4                       ; increment the counter for next position in the bank
		bogus=1                           ; continue from beginning of loop
		bBlue=False                       ; we are done with blue
		bSex=True                         ; next we check the sex component
	End If
	If bSex=True And bogus=False Then     ; if sex component and not midway through the loop then
		PokeInt buf,cBuf,this_gene        ; poke sex component into the bank
		bogus=1                           ; continue from beginning of loop
		bSex=False                        ; we are done with sex
		bRed=True						  ; next we check the red component again
	End If
Next
Return Int(cBuf/4)                        ; return the number of elements. It is divided by 4
					                      ; because we incremented by 4 to hold int values in bank
End Function

Function calculateFitness#()
; this function calculates how close the value is to the target we set.
tempRed#=PeekInt(buffer,0)*17 ; get red component. Since each component uses 4 bits, then max
		                      ; value is 15. 15*17 = 255, which is max value of color component
tempGreen#=PeekInt(buffer,4)*17; get green component

tempBlue#=PeekInt(buffer,8)*17; get blue component

tempSex#=PeekInt(buffer,12)*17; get sex component

result#=0.0 ; this is the important variable. It is used to tell the program how close the calculated
            ; value is to what is wanted
If tempRed#=200 And tempSex=100 Then
	result#= 5 ; not a bad result, but not what we are looking for
ElseIf tempRed#=255 And tempGreen#=0 And tempBlue#=0 And tempSex=0 Then
	male=CopyEntity(sphere)
	EntityColor male,tempRed#,tempGreen#,tempBlue#
	PositionEntity male,Rand(-50,50),1,Rand(50)
	maleCount=maleCount+1
	PointEntity camera,male
	result#= 999; now THIS is what we are looking for. A pure red male
ElseIf tempGreen#=200 And tempSex=100 Then
	result#= 5
ElseIf tempGreen=255 And tempRed#=0 And tempBlue#=0 And tempSex=255 Then
	female=CopyEntity(cube)
	EntityColor female,tempRed#,tempGreen#,tempBlue#
	PositionEntity female,Rand(-50,50),1,Rand(50)
	femaleCount=femaleCount+1
	PointEntity camera,female
	result#= 999; now THIS is what we are looking for. A pure green female
Else
	result#=0  ; not a good result. We weren't very happy with the findings
End If
Return result# ; tell the calling function how happy/unhappy we were with the results
End Function

Function rouletteSelection$(totalFitness#)
; the chromosome with the fittest value has the best chance of being returned from this function
portion#=Rnd(0,1)*totalFitness#
tempFitness#=0.0
For i=0 To POPULATION_SIZE-1
	tempFitness#=tempFitness#+Population[i]\fitness#
	If tempFitness#>portion# Then
		Return Population[i]\bits$
	End If
Next
Return "" ; we didn't find anything worth returning
End Function

Function Crossover(child1$,child2$)
; this function takes two chromosomes and recombines them into new chromosomes
If Rnd(0,1) < CROSSOVER_RATE# Then 
	crossover=Int(Rnd(0,1)*CHROMOSOME_LENGTH)
	If crossover = 0 Then crossover = 1 ; we want at least ONE combining gene
	; the next two statements takes the genes from crossover to CHROMOSOME_LENGTH and
	; swaps them with each other. Thus, each chromosome is recombined into a new
	; configuration
	c1$=Mid$(child1$,1,crossover)+Mid$(child2$,crossover+1,CHROMOSOME_LENGTH)
	c2$=Mid$(child2$,1,crossover)+Mid$(child1$,crossover+1,CHROMOSOME_LENGTH)
	offspring1$=c1$
	offspring2$=c2$
End If
End Function

Function Mutate(bits$)
; this function mutates the chromosomes
For i=1 To Len(bits$)
	If Rnd(0,1) < MUTATION_RATE# Then
		bits$ = flipBits(bits$,i)
	End If
Next
End Function

Function flipBits$(bits$,where)
; this function changes a "1" to a "0" and a "0" to a "1"
tempString$=""

For i=1 To Len(bits$)
	If i=where Then
		If Mid$(bits$,i,1)="1" Then
			tempString$=tempString$+"0"
		Else
			tempString$=tempString$+"1"
		End If
	Else
		tempString$=tempString$+Mid$(bits$,i,1)
	End If
Next
Return tempString$
End Function

Comments

OJay2006
437 lines of code, that actually do...nothing? interesting :)


/edit: douh! with 5000 generations, a red sphere suddenly appears! woah, cool!





;)


kevin80842006
It is not the program, itself, that the post is about. It is about the genetic algorithm coding used in the program. If you don't have anything intelligent to say, then kindly don't post.
Addendum: here is another genetic algo example that might suit better as it is quicker and doesn't contain any visuals other than text...that is, no pictures :) Enjoy.
Graphics 800,600

SeedRnd MilliSecs()

Const POPULATION_SIZE		=100
Const CHROMOSOME_LENGTH		=16
Const GENE_LENGTH			=4
Const MAX_GENERATIONS		=500

Const BRAINDEAD				=0
Const INTELLIGENT			=1
Const AVERAGE				=2
Const MORONIC				=3

Type chromosome
	Field bits$
	Field fitness#
End Type

Global individual.chromosome[POPULATION_SIZE]
Global temp.chromosome[POPULATION_SIZE]

Global buffer=CreateBank(CHROMOSOME_LENGTH*4)

Global TotalFitness#=0.0
Global generations = 0
Global indFound = 0
Global child1$,child2$


initializePopulace()

While Not indFound
If KeyHit(1) Then indFound=1
Cls
If indFound=1 Then 
	Text 0,0, "Found the dumbass in "+generations+" generations."
Else
	Text 0,0, "Searching..."
End If
If generations >= MAX_GENERATIONS Then Cls:Text 0,0,"Search failed to find anyone intelligent in "+generations+" generations."
Flip
Delay 10
Wend
FreeBank buffer
WaitKey()
End

Function initializePopulace()
While Not indFound
Text 0,0,"Searching..."
generations = generations + 1
If generations=MAX_GENERATIONS Then Return
DebugLog generations

For i=0 To POPULATION_SIZE-1
	individual[i] = New chromosome
	getChromosomes(individual[i])
	individual[i]\fitness# = calculateFitness(individual[i]\bits$,MORONIC)
	TotalFitness#=TotalFitness#+individual[i]\fitness#
	If individual[i]\fitness#=999 Then indFound = 1:Cls:Text 0,0,"Found knuckle-walker in "+generations+" generations.":Return
Next
nPop=0
While nPop<POPULATION_SIZE-1
temp[nPop]=New chromosome
child1$=doRoulette(TotalFitness#,temp[nPop])
child2$=doRoulette(TotalFitness#,temp[nPop])
Crossover(child1$,child2$)
mutate(child1$)
mutate(child2$)
temp[nPop]\bits$=child1$
temp[nPop]\fitness#=0.0
nPop = nPop + 1
temp[nPop]=New chromosome
temp[nPop]\bits$=child2$
temp[nPop]\fitness#=0.0
nPop = nPop+1

Wend
For i=0 To POPULATION_SIZE-1
	individual[i]=temp[i]
Next
Wend
End Function

Function getChromosomes(this.chromosome)
For i=0 To CHROMOSOME_LENGTH-1
	If Rnd(0,1) > .5 Then
		bits$=bits$+"1"
	Else
		bits$=bits$+"0"
	End If
Next
this\bits$=bits$
End Function

Function calculateFitness(bits$,target)
parseBits(bits$,buffer)
tempBrainy=PeekInt(buffer,0)
tempGenius=PeekInt(buffer,4)
tempDolt  =PeekInt(buffer,8)
tempBent  =PeekInt(buffer,12)
result#=0.0
If tempBrainy>14 And tempGenius=0 And tempBrainy=tempDolt And tempBrainy>tempBent Then
	result#=999:Return result#
Else
	result#=1
End If
Return 1/Abs(result-target)
End Function

Function parseBits#(bits$,buf)
bufCounter=0
this_gene=0
For i=1 To CHROMOSOME_LENGTH Step GENE_LENGTH
	bogus=0
	this_gene=binary2Decimal(Mid$(bits$,i,GENE_LENGTH))
	PokeInt buf,bufCounter,this_gene
	bufCounter = bufCounter+4
Next
Return bufCounter/4
End Function

Function binary2Decimal%(bits$)
val=0
value_added=1
	For i=Len(bits$) To 1 Step-1
		If Mid$(bits$,i,1)="1" Then
			val=val+value_added
		End If
		value_added=value_added*2
	Next
Return val
End Function

Function doRoulette$(totalFit#,this.chromosome)
portion#=Rnd(0,1)*totalFit#
thisFitness#=0.0
For i=0 To POPULATION_SIZE-1
	thisFitness#=thisFitness#+this\fitness#
	If thisFitness#>portion# Then
		Return this\bits$
	End If
Next
Return ""
End Function

Function Crossover(child1$,child2$)
If Rnd(0,1)<CROSSOVER_RATE# Then
	crossover=Int(Rnd(0,1)*CHROMOSOME_LENGTH)
	If crossover=0 Then crossover=1
	c1$=Mid$(child1$,1,crossover)+Mid$(child2$,crossover+1,CHROMOSOME_LENGTH)
	c2$=Mid$(child2$,1,crossover)+Mid$(child1$,crossover+1,CHROMOSOME_LENGTH)
	child1$=c1$
	child2$=c2$
End If
End Function

Function mutate(bits$)
For i=1 To Len(bits$)
	If Rnd(0,1)<MUTATION_RATE# Then
		bits$=flipBits(bits$,i)
	End If
Next
End Function

Function flipBits$(bits$,where)
tempString$=""
For i=1 To Len(bits$)
	If i=where Then
		If Mid$(bits$,i,1)="1" Then
			tempString$=tempString$+"0"
		Else
			tempString$=tempString$+"1"
		End If
	Else
		tempString$=tempString$+Mid$(bits$,i,1)
	End If
Next
Return tempString$
End Function




puki2006
This looks interesting. Now go right a Spore-clone before it is released.

Don't worry about graphics - everything can be geometrical shapes.


kevin80842006
Thank you...I've checked out the game, Spore, and it looks like it would be fun to make. Right now I'm looking into Neural Networks - did research on Genetic algorithm as a means of inputting information to a NN's nodes. The second code, by the way, is only a quasi-genetic algorithm - it doesn't fully utilize the capabilities/functions...that is, some of the code is not used.


Code Archives Forum