Выбор колеса рулетки для минимизации функции

Этот вопрос отвечает на псевдокод для выбора колеса рулетки. Но это для проблемы максимизации. Но моя проблема в том, чтобы минимизировать значение фитнес-функции. Это означает, что люди с низкой физической подготовкой получают более высокую вероятность быть выбранными, чем люди с высокой физической подготовкой. Как я могу это реализовать?

Заранее спасибо.


person Masud Hasan    schedule 06.01.2012    source источник


Ответы (6)


import java.util.Random;
import java.util.Arrays;
import java.util.Comparator;

class MyComparator implements Comparator
{
    public int compare(Object o1, Object o2)
    {
        Number n1 = (Number) o1;
        Number n2 = (Number) o2;

        if(n1.jump > n2.jump)
        {
            return 1;
        }
        else if(n1.jump < n2.jump)
        {
            return -1;
        }
        else
        {
            return 0;
        }
    }
}


class Number
{
    public double i;
    public int pos;
    public double jump = 0;


    public Random r = new Random();

    public Number(int pos)
    {
        this.pos = pos;

        i = r.nextInt();
    }
}


public class Temp
{
    public static  void main(String[] args)
    {
        Number[] n = new Number[50];

        double total = 0;

        for(int i=0; i<50; i++)
        {
            n[i] = new Number(i);

            total += n[i].i;
        }

        for(int i=0; i<50; i++)
        {
            n[i].jump = n[i].i/total;
        }


        Arrays.sort(n, new MyComparator());     

        for(int i=0; i<50; i++)
        {
            System.out.print(n[i].pos + ", ");
        }

        System.out.println();

        for(int i=0; i<50; i++)
        {
            n[i].jump = n[i].i / total;
            n[i].jump = 1-n[i].jump;
        }

        Arrays.sort(n, new MyComparator());     

        for(int i=0; i<50; i++)
        {
            System.out.print(n[i].pos + ", ");
        }

        System.out.println();   
    }
}

В приведенном выше примере, скажем, Number class - это ваш индивидуальный класс, i - фитнес, jump - это вероятность быть выбранным в качестве родительского. Сначала мы вычисляем вероятность быть выбранным в качестве родителя, как и раньше. На этом этапе более высокая пригодность будет иметь более высокую вероятность. Затем мы вычитаем вероятность из 1. Это дает человеку с более низкой пригодностью более высокую приспособленность (псевдопригодность ради выбора). Теперь пересчитайте вероятность. Видите, порядок бытия полностью перевернут.

person user    schedule 06.01.2012

Используйте тот же алгоритм, но сделайте пропорцию каждого человека = maxfitness - fitness

person Larry OBrien    schedule 06.01.2012
comment
Для реальной жизненной проблемы очень маловероятно знать MAX_FITNESS так же, как MIN_FITNESS. - person user; 06.01.2012
comment
Я не должен был использовать заглавные буквы с постоянной индикацией. maxFitness для вашего колеса рулетки - это максимальная пригодность текущего поколения, поскольку размер колеса рулетки / лотереи является суммой пригодностей текущего поколения. - person Larry OBrien; 06.01.2012

Колесо рулетки нельзя использовать для минимизации из-за масштабирования. Кроме того, его также нельзя использовать при отрицательной или нулевой пригодности, потому что их вероятность будет отрицательной или нулевой.

Как предложил Ларри, вы можете использовать локальную нормализацию, вычитая до максимальной приспособленности вашей популяции приспособленность каждого человека, но опять же вам придется зафиксировать максимальную приспособленность, чтобы она не имела нулевой вероятности.

Я предлагаю вам использовать турнирную подборку, которая многократно зарекомендовала себя лучше, чем рулетка.

person mitch    schedule 08.01.2012

Измените фитнес на fitness_new = 1 / fitness_old, и у вас снова возникнет проблема с максимизацией. Если fitness_old = 0 возможно, добавьте 1 к знаменателю, чтобы избежать деления на ноль.

person CGFoX    schedule 03.12.2014

Может быть, уже слишком поздно, но я не рекомендую max_fitness - fitness, так как вы потеряете худшие элементы (они могут помочь в исследовании). Вместо этого вы можете сделать что-то вроде инверсии.

def roulette_selection(population):
    fs = [fitness(i) for i in population]
    sum_fs = sum(fs)
    max_fs = max(fs)
    min_fs = min(fs)
    p = random()*sum_fs
    t = max_fs + min_fs
    choosen = population[0]
    for i in population:
        if MAXIMIZATION:
            p -= fitness(i)
        elif MINIMIZATION:
            p -= (t - fitness(i))
        if p < 0:
            choosen = i
            break
    return choosen
person Josue Ttito    schedule 11.10.2014

Простой способ изменить порядок вероятности:

Скажем, исходный список вероятностей [p1,p2,p3,...,pn] предназначен для отдельных лиц в популяции.

Чтобы изменить порядок, для каждого pi в этом списке мы получаем new_pi = (1-pi) / (n-1).

Пояснение:

Начиная с 0<=pi<=1, значение (1-pi) заставляет меньшую вероятность получить большее значение.

Поскольку сумма (1-pi) для i от 1 до n становится n-1, после деления на (n-1) (нормализация) мы убеждаемся, что 0<=new_pi<=1.

Пример кода:

def rouletteWheelSelect(population):
    fitnessSum = 0
    for individual in population:
        fitnessSum += individual.fitness
    for individual in population:
        individual.selectProb = individual.fitness / fitnessSum
    probSum = 0
    wheelProbList = []
    if MAXIMIZATION_PROBLEM:
        for individual in population:
            probSum += individual.selectProb
            wheelProbList.append(probSum)
    elif MINIMIZATION_PROBLEM:
        for individual in population:
            probSum += (1-individual.selectProb) / (POPULATION_SIZE-1)
            wheelProbList.append(probSum)
    r = random.random()  # 0<=r<1
    for i, p in enumerate(wheelProbList):
        if r < p:
            return population[i]
    return None
person Instein    schedule 02.03.2020