-
Notifications
You must be signed in to change notification settings - Fork 0
Conclusion
This paper has been implemented completely in Python, with the exception of the Diehard tests (http://www.stat.fsu.edu/pub/diehard/) which were written in C. There are four primary utility scripts: generate, fitness, simulate, breed. Each has a corresponding parameters file for simple fine-tuning. The script that ties all of these together to compute current and successive generations is master.py, which has its own parameters file.
The primary performance bottleneck, the fitness testing, is completely parallelized, with a pool of processes that greedily grab functions to simulate and evaluate. Breeding is less of a performance concern, but it is also parallelized due to the ease with which it is possible. There are numerous additional opportunities for algorithmic parallelization that aren’t utilized by our implementation.
Special mention must be given to Psyco (http://psyco.sourceforge.net/) and the processing module (http://pypi.python.org/pypi/processing/). Psyco improves individual script execution by utilizing a JIT compiler, while the processing module allows for quick and efficient parallelization of the algorithm itself.
Unfortunately, the hash functions the algorithm currently generates are very weak, and would at best serve as CRCs or checksums of some sort. However, we believe this machine learning approach holds promise, and given more time, we feel we can produce more substantial and interesting results. There are two primary reasons. First, the randomized generator function is weak. There are in fact four structured generator functions provided, but only one of them is actually used, since the others never produce anything but constants. The single usable generator is itself a manually-created and very trivial hash function. It simply returns some number of bits from the first block of the input. For small inputs, it is a kind of perfect hash function (http://burtleburtle.net/bob/hash/perfect.html), and obviously produces collisions for longer inputs.
Indeed, on first glance, it would seem like a poor candidate for an initial function. However, we conducted several runs (~50 generations) with the initial population consisting entirely of this function, which is 5 lines long. At the end of each of these runs, we noticed that there were two or three long functions (> 300 lines) whose exact hash outputs varied slightly from their initial forms. The variation wasn’t significant, but the fact that phenotypic variation existed at all is a hopeful sign. It stands to reason that if provided additional trivial hash functions that collectively exercised the full power of the assembly language, the generator would allow the algorithm to produce substantially more interesting input.
Secondly, the resources available for the purposes of this paper was limited. We had full-time access to a single dual-core machine that was frequently used for other tasks, and only one time-strapped developer. If the algorithm could be adapted to run on a cluster or in the cloud with the backing of additional human resources, it would allow much more rapid convergence on interesting behavior upon execution.