Скалолазание
Вы можете попробовать некоторые алгоритмы стохастической оптимизации, например, Hill Climbing, в котором вы начинаете со случайного решение (как указал @Don Reba) и посмотрите на набор соседних решений для тех, которые лучше с точки зрения функции стоимости. Я буду использовать пример кода Python, чтобы объяснить идею.
Получить соседние решения
Для соседей в вашем случае вы можете использовать простую функцию, например:
n_params = 5 # number of parameters
upper_bound = 5 # upper limit of your parameters
lower_bound = 0 # lower limit of your parameters
def get_neighbors(solution):
neighbors = []
for i in range(n_params):
x = copy.deepcopy(solution)
if x[i] < upper_bound:
x[i] += 1 # increment one of the components
neighbors.append(x)
x = copy.deepcopy(solution)
if x[i] > lower_bound:
x[i] -= 1 # decrement one of the components
neighbors.append(x)
return neighbors
Если у вас есть текущее решение [1,3,4,2,2], увеличивая или уменьшая любой из компонентов, вы получаете 10 разных соседей, как показано ниже:
[2, 3, 4, 2, 2],
[0, 3, 4, 2, 2],
[1, 4, 4, 2, 2],
[1, 2, 4, 2, 2],
[1, 3, 5, 2, 2],
[1, 3, 3, 2, 2],
[1, 3, 4, 3, 2],
[1, 3, 4, 1, 2],
[1, 3, 4, 2, 3],
[1, 3, 4, 2, 1]
Здесь мы предполагаем, что каждый параметр является целым числом. Вы можете добиться большей детализации, отрегулировав размер шага (например, 0,05).
Итерации подъема в гору
def hill_climb():
initial_solution = np.random.randint(lower_bound, upper_bound, n_params)
current_solution = initial_solution
print 'initial solution', initial_solution
current_cost = get_cost(initial_solution)
step = 1
while True:
#try to replace each single component w/ its neighbors
lowest_cost = current_cost
lowest_solution = current_solution
print 'hill-climbing cost at step %6d: %d' % (step, lowest_cost)
neighbors = get_neighbors(current_solution)
for new_solution in neighbors:
neighbor_cost = get_cost(new_solution)
if neighbor_cost < lowest_cost:
lowest_cost = neighbor_cost
lowest_solution = new_solution
if lowest_cost >= current_cost:
break
else:
current_solution= lowest_solution
current_cost = lowest_cost
step += 1
return current_solution
Функция стоимости
Для полноты картины я буду использовать свою собственную функцию стоимости (просто для демонстрационных целей), которая
f(x) = x1^1 - x2^2 + x3^3 - x4^4 + x5^5
То есть :
def get_cost(solution):
cost = 0
for i,param in enumerate(solution):
cost += (-1.)**i * param**(i+1)
return cost
Результат оптимизации:
Вот результат. Мы используем случайное начальное предположение [4, 0, 1, 3, 1]. После 14 шагов (оценка 14 * 10 = 140 соседей) мы находим оптимальный ответ [0, 5, 0, 5, 0], который минимизирует стоимость. Для грубой силы вы должны оценить 6 ^ 6 = 46656 решений. Можно сэкономить гораздо больше времени работы, если у вас есть решение с высокой размерностью.
Обратите внимание, поскольку это стохастический метод, в качестве конечного результата находится локальный минимум (хотя иногда он идентичен глобальному минимуму, это не гарантируется). Однако практически это достаточно хорошо.
initial solution: [4 0 1 3 1]
hill-climbing cost at step 1: -75
hill-climbing cost at step 2: -250
hill-climbing cost at step 3: -619
hill-climbing cost at step 4: -620
hill-climbing cost at step 5: -621
hill-climbing cost at step 6: -622
hill-climbing cost at step 7: -623
hill-climbing cost at step 8: -624
hill-climbing cost at step 9: -627
hill-climbing cost at step 10: -632
hill-climbing cost at step 11: -639
hill-climbing cost at step 12: -648
hill-climbing cost at step 13: -649
hill-climbing cost at step 14: -650
Final solution: [0 5 0 5 0]
Связанный пост
Связанный, но более сложный вопрос здесь: Алгоритм выбора n векторов из набора при минимальных затратах
Все приведенные выше коды можно найти здесь.
person
greeness
schedule
02.12.2012