Moderators: Randy Ping, Fraser, THWOTH


camoguard wrote:1. Start with a random string of 28 characters
2. Copy this string 100 times, with a 5% chance per character of that character being replaced with a random character
3. Compare each new string with the target "METHINKS IT IS LIKE A WEASEL", and give each a score
4. If any of the new strings has a perfect score, halt
5. Otherwise, take the highest scoring string, and go to step 2
There's the algorithm from Wikipedia. Your variables are the eligible characters, the number of copies, the percentage of chance a character is replaced with a random character, the scoring mechanism and the target string. What do you have in mind?
Opt("MustDeclareVars",1)
Opt("GUIOnEventMode",1)
Opt("TrayAutoPause",0)
Dim $weasel, $genes, $children, $mutation, $parent, $fitness, $speed, $wLen, $gLen, $cnt, $lbla, $lblb, $tmp
; //Settings//
$weasel="Me thinks it is like a weasel." ; Make this whatever sentence (species) you want.
$genes="'!?. ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ; Alphabet (genes) including puctuations and spaces.
$children=5 ; Change this to how many children (litter size) each surviving weasel will have.
$mutation=20 ; Odds of mutation per gene = 1 in 'mutation #'. Some weasels may not have any mutations, some several.
$speed=0 ; Slow evolution so you can watch the output easier. 0 = no slowdown, 1000 = 1 second per generation
; //End Settings//
; Let's make a settings file to change settings in the compiled version, NOT required.
; Can either be changed above, as defaults, or changed in Weasel.ini in the same folder as Weasel.au3 or Weasel.exe.
$weasel=IniRead(@ScriptDir&"\Weasel.ini","Settings","weasel",$weasel)
$genes=IniRead(@ScriptDir&"\Weasel.ini","Settings","genes",$genes)
$children=IniRead(@ScriptDir&"\Weasel.ini","Settings","children",$children)
$mutation=IniRead(@ScriptDir&"\Weasel.ini","Settings","mutation",$mutation)
$speed=IniRead(@ScriptDir&"\Weasel.ini","Settings","speed",$speed)
$wLen=StringLen($weasel)
$gLen=StringLen($genes)
$genes=StringSplit($genes,"")
For $i=1 To $wLen ; Create a random first weasel ancestor to evolve
$parent=$parent & $genes[Random(1,$genes[0],1)]
Next
; //Make GUI window//
GuiCreate("Weasel Evolution",500,102,-1,-1,-1)
GUISetOnEvent(-3,"Xit")
GUICtrlCreateLabel($weasel,0,0,500,20,0x1000)
$lbla=GUICtrlCreateLabel($parent,0,30,500,20,0x1000)
$lblb=GUICtrlCreateLabel($parent,0,60,500,20,0x1000)
GUICtrlCreateButton("Breed",195,82,50,20,0x1000)
GUICtrlSetOnEvent(-1,"breed")
GUICtrlCreateButton("Kill",255,82,50,20,0x1000)
GUICtrlSetOnEvent(-1,"Xit")
GuiSetState()
; //GUI done//
$weasel=StringSplit($weasel,"") ; Get whole weasels genetic code for mutations. Each gene mutation can be good, bad, or neutral.
$parent=StringSplit($parent,"") ; Get the first ancestor parent genetic code.
$fitness=0 ; Starting fitness
Sleep(2000000000) ; Will live approximately 23 days unless killed.
Func breed()
While $fitness < $wLen
$tmp=kits()
If IsArray($tmp) Then $parent=$tmp ; Yippie!!! The little kit escaped the big bad wolf!
updGUI()
Sleep($speed)
WEnd
updGUI(1)
EndFunc
Func kits() ; Have # of random children and send back survivor.
Local $child, $fit=0, $kit ; Parent got pregnant.
For $i = 1 To $children ; A litter of this many little weasel pups is on the way.
$kit=$parent; Copy parent, random mutations to be added next.
For $j=1 To $wLen ; Add some random mutations to the poor little weasel kit.
If Random(1,$mutation,1) = 1 Then ; Did we get a mutation on this gene, regardless of good, bad, or neutral?
$kit[$j]=$genes[Random(1,$genes[0],1)] ; If mutated, randomly select any gene (alphabet) to mutate to.
EndIf
Next ; Ouch, labor pains! I hope the next one don't hurt so much.
$tmp=0
For $j=1 To $kit[0] ; Will the poor fellow live, or be diseased, starve, or get eaten by the big bad wolve?
If $kit[$j]==$weasel[$j] Then $tmp=$tmp+1 ; How fit is our cute littel weasel?
Next
If $tmp >= $fitness Then ; I live! I live! As long as my siblings don't take all the milk or the wolf get me :(
$fitness=$tmp
$child=$kit
EndIf
Next ; Ouch! Another one on the way...
Return $child ; I got my milk! Now I go out and have my own pups.
EndFunc
Func Xit()
MsgBox(8240,"Weasel","Please no! I don't want to die!!!")
Exit
EndFunc
Func updGUI($a=0)
Local $t
$cnt=$cnt+1
For $i=1 To $wLen
$t=$t&$parent[$i]
Next
GUICtrlSetData($lbla, $t)
$t="Fitness = "&$fitness&" Generation = "&$cnt
If $a Then $t=$t&" >Finished"
GUICtrlSetData($lblb,$t)
EndFunc
import random
_target = list('METHINKS IT IS LIKE A WEASEL')
_source = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ ')
def mutate(input, prob=5, variance=5, lock=False):
results = []
for i in range(100):
result = list(input)
for (i, v) in enumerate(result):
if lock and v == _target[i]:
continue
if random.randint(1, 100) <= prob:
index = _source.index(v)
index = (index + random.randint(-variance, variance)) % len(_source)
result[i] = _source[index]
results.append(result)
return results
def score(input):
assert(len(input) == len(_target))
score = 0
for (t1, t2) in zip(input, _target):
i1 = _source.index(t1)
i2 = _source.index(t2)
diff = abs(i1 - i2)
score += diff
return score
# Start
input = [random.choice(_source) for i in range(len(_target))]
gen = 0
found = False
while not found:
mutants = mutate(input)
# mutants = mutate(input, lock=True)
best_score = None
best_index = None
for (i, v) in enumerate(mutants):
s = score(v)
if best_score is None or s < best_score:
best_score = s
best_index = i
input = mutants[best_index]
gen += 1
print('Generation: ' + str(gen))
print('Best: ' + ''.join(input))
if input == _target:
break

McSwan wrote:Hi,
I did a masters degree in Code Generation Design.
Instead of using "METHINKS IT IS LIKE A WEASEL" I attempted to generate valid c++ programs, like "int main(){}" (simplest possible c++ program) and tested it's accuracy through a compiler (experiment 3).
http://codegenerationdesign.webs.com/index.htm ( There are videos of the experiments)
Experiment 3 is probably closest to what your looking for, it uses a genetic algorithm to form the simplest c++ program.
Experiment 6
"A program that can learn it's own code, and change itself to what the user wants, provided what the user wants is a combination of what it knows."
Is also interesting in the sense that it is proof of the future of evolution, ie once we know how to program DNA, we'd be able to write our own life forms.
ie Evolutionary changes in the future will likely be instantaneous due to Genetic engineering. After testing itself, the program re-wites itself to the ideal life-form in a single iteration.
camoguard wrote:That's actually really cool McSwan.
OHSU, what is the time frame between now and the science fair?
lordshipmayhem wrote:I'd head off to the nearest Linux Users' Group, you should be able to Google one close to you and contact them through their website. They tend to be greybearded old programmers with a wealth of contacts. In other words if nobody there can help you, chances are they know someone who can.
(When I first went to a local LUG meeting, I was expecting a ton of eager youngsters in their 20's. I turned out to be the youngest one there, most of the others being eager "youngsters" in their 50's and 60's.)
OHSU wrote:Could they write a Windows app for me?
pcCoder wrote:OHSU wrote:Could they write a Windows app for me?
What language would be used? With Python a simple Python/wxWidgets app is quite easy to make. A C++ app could also be made with a little more work. With Python, you would have to download the Python and wxPython installers, but it would be very easy to change the code without recompiling it. With C++ statically linked the only thing needed would be the executable, but it would have to be recompiled after changes, which would still require downloading a compiler (MinGW) and the GUI toolset (wxWidgets) if not coding it directly in the Windows API. You could also have one made in HTML/Javascript where it could simply be loaded in a web browser, such as this: http://pastebin.com/f54d05a8e
Edited: html example
NineBerry wrote:Hey, I am just NineBerry, 31 year old software engineer from Germany. There is not much more to know.
OHSU wrote:lordshipmayhem wrote:I'd head off to the nearest Linux Users' Group, you should be able to Google one close to you and contact them through their website. They tend to be greybearded old programmers with a wealth of contacts. In other words if nobody there can help you, chances are they know someone who can.
(When I first went to a local LUG meeting, I was expecting a ton of eager youngsters in their 20's. I turned out to be the youngest one there, most of the others being eager "youngsters" in their 50's and 60's.)
Could they write a Windows app for me?

OHSU wrote:I have some questions, though. What, exactly, do the "skip" buttons do? What does it mean to "skip 100 generations"? What effect does that have on the process?
NineBerry wrote:OHSU wrote:I have some questions, though. What, exactly, do the "skip" buttons do? What does it mean to "skip 100 generations"? What effect does that have on the process?
I wasn't very content with the word, either. I was looking for a better one that is short enough to fit on the buttons but couldn't find one.Maybe someone has a better idea:
"Skip" runs the given number of generations without applying the "delay" before each generation. This can be used for two purposes:
While the normal breeding process is running, this might be used to "skip forward" a given number of generations like you would do with your VCR when watching a boring sequence of a film because you are impatient.
It is also a way of running the given number of generations while the breeding process is paused. For example, when starting the breeding process by clicking "(Re)Start", first check the check box "Start paused". So the system will reset and is ready to work but is paused and doesn't run automatically. You can now use the skip buttons to run a given number of generations.
That might be useful if you want to log an experiment to draw a chart, for example. Just start the experiment paused. Then repeatedly hit the "skip 100 generations" button to run 100 generations at once. So, you can easily write down the current mutated texts and the distances to the target after 100, 200, 300, 400, 500, 600 ... generations.
Users browsing this forum: alanesq, Daan, Eryemil, ff5167, Gareth1984, Goldenmane, Harmonica, Mononoke, Nautyskin, Or Bar, tap1966 and 29 guests