How should I Test a Genetic Algorithm

2019-03-07 16:38发布

I have made a quite few genetic algorithms; they work (they find a reasonable solution quickly). But I have now discovered TDD. Is there a way to write a genetic algorithm (which relies heavily on random numbers) in a TDD way?

To pose the question more generally, How do you test a non-deterministic method/function. Here is what I have thought of:

  1. Use a specific seed. Which wont help if I make a mistake in the code in the first place but will help finding bugs when refactoring.

  2. Use a known list of numbers. Similar to the above but I could follow the code through by hand (which would be very tedious).

  3. Use a constant number. At least I know what to expect. It would be good to ensure that a dice always reads 6 when RandomFloat(0,1) always returns 1.

  4. Try to move as much of the non-deterministic code out of the GA as possible. which seems silly as that is the core of it's purpose.

Links to very good books on testing would be appreciated too.

10条回答
来,给爷笑一个
2楼-- · 2019-03-07 17:21

I wrote a C# TDD Genetic Algorithm didactic application: http://code.google.com/p/evo-lisa-clone/

Let's take the simplest random result method in the application: PointGenetics.Create, which creates a random point, given the boundaries. For this method I used 5 tests, and none of them relies on a specific seed:

http://code.google.com/p/evo-lisa-clone/source/browse/trunk/EvoLisaClone/EvoLisaCloneTest/PointGeneticsTest.cs

The randomness test is simple: for a large boundary (many possibilities), two consecutive generated points should not be equal. The remaining tests check other constraints.

查看更多
做个烂人
3楼-- · 2019-03-07 17:23

Seems to me that the only way to test its consistent logic is to apply consistent input, ... or treat each iteration as a single automaton whose state is tested before and after that iteration, turning the overall nondeterministic system into testable components based on deterministic iteration values.

For variations/breeding/attribute inheritance in iterations, test those values on the boundaries of each iteration and test the global output of all iterations based on known input/output from successful iteration-subtests ...

Because the algorithm is iterative you can use induction in your testing to ensure it works for 1 iteration, n+1 iterations to prove it will produce correct results (regardless of data determinism) for a given input range/domain and the constraints on possible values in the input.

Edit I found this strategies for testing nondeterministic systems which might provide some insight. It might be helpful for statistical analysis of live results once the TDD/development process proves the logic is sound.

查看更多
何必那么认真
4楼-- · 2019-03-07 17:25

You could write a redundant neural network to analyze the results from your algorithm and have the output ranked based on expected outcomes. :)

Break your method down as much as your can. Then you can also have a unit test around just the random part to check the range of values. Even have the test run it a few times to see if the result changes.

查看更多
放荡不羁爱自由
5楼-- · 2019-03-07 17:26

If you're talking TDD, I would say definitely start out by picking a constant number and growing your test suite from there. I've done TDD on a few highly mathematical problems and it helps to have a few constant cases you know and have worked out by hand to run with from the beginning.

W/R/T your 4th point, moving nondeterministic code out of the GA, I think this is probably an approach worth considering. If you can decompose the algorithm and separate the nondeterministic concerns, it should make testing the deterministic parts straightforward. As long as you're careful about how you name things I don't think that you're sacrificing much here. Unless I am misunderstanding you, the GA will still delegate to this code, but it lives somewhere else.

As far as links to very good books on (developer) testing my favorites are:

查看更多
你好瞎i
6楼-- · 2019-03-07 17:27

I would highly suggest looking into using mock objects for your unit test cases (http://en.wikipedia.org/wiki/Mock_object). You can use them to mock out objects that make random guesses in order to cause you to get expected results instead.

查看更多
ゆ 、 Hurt°
7楼-- · 2019-03-07 17:34

I would test random functions by testing them a number of times and analyzing whether the distribution of return values meets the statistical expectations (this involves some statistical knowledge).

查看更多
登录 后发表回答