Numpy random — укажите несколько границ и шагов

#python #numpy #random #genetic-algorithm

#python #numpy #Случайный #генетический алгоритм

Вопрос:

Мне нужно сгенерировать начальную совокупность генетического алгоритма. Рассмотрим следующий вектор:

 [20, 2, 20, 1.5, 5, 20, 5, 0.5, -0.5, 5, 20, 5, 3, 14, 70, 30, 10, 5, 5, 20, 8, 20, 2.5]
  

Я бы сделал это:

 new_population = numpy.random.uniform(low=0.1, high=50.0, size=pop_size)
  

Проблема в том, что некоторые хромосомы в проблемном пространстве имеют разные шаги и разные максимальные значения. Элемент 0 должен быть 1-100 с шагом 1 (таким образом, int). Элемент 3 должен быть 0.1-10 с шагом 0.1 (с плавающей точкой). Какой самый простой способ выполнить эту рандомизацию?

Ответ №1:

Поскольку кажется, что диапазоны для ваших хромосом жестко запрограммированы, я предлагаю вам сгенерировать все числа только с одним numpy.random.uniform() с наименьшим диапазоном, который вам нужен, т. Е. 0,1-10 в вашем примере, а затем вы умножаете это полученное число на следующее соотношение:

желаемый диапазон / базовый диапазон

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

Комментарии:

1. таким образом, вы можете столкнуться с проблемами, когда соотношение шага и границ не будет совпадать.

2. вы правы, я все еще заканчивал редактировать свой ответ

Ответ №2:

Вы не предоставили достаточно данных, чтобы увидеть какой-либо шаблон для более короткого кода.

Однако вы могли бы сделать следующее: составить список списков, где каждый подсписок состоит из следующих элементов: bounds = [[low, high, step], ...]

Затем инициализируйте пустой массив numpy, т. Е. new_population = np.empty(23) И после этого вы можете просто перебирать границы с помощью цикла for и генерировать каждый элемент:

 for i, value in enumerate(bounds):
    new_population[i] = np.random.uniform((low=value[0], high=value[1], size=value[2])
  

Ответ №3:

numpy.vectorize Декоратор позволяет легко определять функции, которые действуют над массивами значений, по одному элементу за раз. Вы можете определить свой конкретный случай как

 @np.vectorize
def vectorized_random(low, high, step):
    # whatever kind of random value you want
  

который можно напрямую использовать над массивами входных данных.

 >>> vectorized_random([1, 1, 0.1], [100, 10, 10], [1, 1, 0.1])
array([...])