有效实施健身比例“轮盘”选择

时间:2009-08-14 05:53:05

标签: c genetic-algorithm keyboard-layout roulette-wheel-selection

我目前正在用C语言编写一个键盘布局优化算法(例如Peter Klausler设计的算法),我想实现这里描述的适应性比例选择(PDF Link):

  

选择轮盘赌选项   基于a的人口成员   roullete轮模型。做个馅饼   图表,成员的区域   切片到整个圆圈的比例   成员的总数   人口。正如你可以看到一点   关于圈子的循环是   随机挑选那些人口   具有较高效率的成员将拥有一个   被选中的概率较高。   这确保了自然选择   的地方。

问题是,我没有看到如何有效地实施它。我想到了两种方法:一种是不可靠的,另一种是慢的。

首先,慢一点:

对于长度为N的键盘池,创建一个长度为N的数组,其中数组的每个元素实际上包含两个元素,即最小值和最大值。每个键盘都有相应的最小值和最大值,范围基于键盘的适应性。例如,如果键盘零的适应度为10,键盘一的适应度为20,而键盘二的适应度为25,则它看起来像这样: 代码:

array[0][0] = 0; // minimum
array[0][1] = 9; // maximum
array[1][0] = 10;
array[1][1] = 30;
array[2][0] = 31;
array[2][1] = 55;

(在这种情况下,较低的适应性更好,因为这意味着需要更少的努力。)

然后生成一个随机数。对于该数字落入的范围,相应的键盘被“杀死”并被替换为不同键盘的后代。根据需要多次重复此操作。

问题在于它非常慢。完成O(N ^ 2)次操作。

接下来的快速:

首先弄清楚键盘的最低和最高配合度。然后在(最低适应度)和(最高适应度)之间生成一个随机数,并杀死所有健身高于生成数量的键盘。这是有效的,但不能保证只能杀掉一半的键盘。它也有一些与“轮盘赌”选择不同的机制,所以甚至可能不适用。

所以问题是,什么是有效的实施?

本书第36页([{3}})有一种有效的算法,但问题是,只有轮盘赌选择只有一次或几次才有效。是否有任何有效的方法可以同时进行多种轮盘选择?

1 个答案:

答案 0 :(得分:1)

首先,如果您想要“扼杀”您的选择(这可能是高的键盘,听起来您正在谈论不合适分数评分)。

我认为没有必要维护两个数组。我认为最简单的方法是维护一个分数数组,然后你可以通过迭代来做出选择:

/* These will need to be populated at the outset */
int scores[100];
int totalScore;

for (gen = 0; gen < nGenerations; ++gen) {
    /* Perform a selection and update */
    int r = rand() % totalScore;        /* HACK: using % introduces bias */
    int t = 0;
    for (i = 0; i < 100; ++i) {
        t += scores[i];
        if (r < t) {
            /* Bingo! */
            totalScore -= scores[i];
            keyboards[i] = generate_new_keyboard_somehow();
            scores[i] = score_keyboard(keyboards[i]);
            totalScore += scores[i];    /* Now totalScore is correct again */
        }
    }
}

每个选择/更新对n个键盘花费O(n)时间。