Я хотел бы начать изучать кое-что о машинном обучении, и я решил начать с практического примера / проблемы, которую я сейчас объясню, но сначала я предпочитаю сказать вам, что:
- Я не программист (я кое-что знаю о Python).
- Игра, которую я опишу, является примером, и на самом деле меня больше интересует понимание того, как использовать стандартный подход с ML, который так же независимнасколько это возможно из игры или проблемы, которую я хочу решить (если это возможно).
Давайте начнем.
Игра описана следующим образом:
- У нас есть прямоугольник LxH (L может быть равен H), и внутри него есть два игрока, A и B (это два пикселя или два маленьких графических круга).
- Игрок A должен быть перемещен изНачальная позиция (случайная) до конечной позиции, а конечная позиция - это граница прямоугольника ближе к A, так что игрок B в начале матча находится между игроком A и этой границей.
- Игрок B должен бытьперемещается из начальной позиции (случайной) в конечную позицию, а конечной позицией является позиция игрока A.
- Если игрок A достигает границы прямоугольника (см. пункт 2), не будучи затронутым игроком B, A выигрываети B. проигрывает.
- Если игрок B касается игрока A до того, как A достигает границы прямоугольника (см. пункт 2), A проигрывает и выигрывает B.
один раунд / матчигры определяется как набор движений, выполняемых игроками A и B из начальной (случайной) позиции в конечную позицию (для игрока A граница, описанная в точке 2, для игрока B - та же позиция игрока A).Симуляция определяется как набор матчей, в которых ИИ может совершенствоваться и узнавать все больше и больше о том, как лучше двигаться игроку А и игроку Б, чтобы получить выигрыш А или В. за меньшее время.
Ну, я хотел бы смоделировать эту простую игру с подходом машинного обучения, чтобы:
a.Сначала начните игру с полного случайного выбора следующей позиции для игроков A и B: в результате я вижу беспорядочные движения A и B без какого-либо смысла.
b.Алгоритм после некоторых матчей должен чему-то научиться из предыдущих матчей, чтобы переместить игрока A в основном к границе победы, а игрока B - к игроку A.
c.После достаточного количества матчей, то есть после симуляции, я хотел бы иметь набор правил, созданных ИИ (например, таблицу наилучших значений позиций для каждой ситуации), которые можно использовать, чтобы играть в игру, когда игрокB перемещается пользователем, а не алгоритмом / компьютером (только игрок A перемещается компьютером с только что созданным AI из предыдущего завершенного моделирования).
Например, я не могу думать ничего, что могло бы помочь мнео пункте б.Возможно, я мог бы использовать временное ограничение: если через некоторое время игрок A или игрок B не отвернулся более чем на X пикселей от своей исходной позиции, то придавал больший вес направлению границы выигрыша для игрока A и большийвес в направлении игрока A для игрока B при выборе новой позиции для обоих во время одного матча.Но в этом случае это будет принудительное действие, добавленное программистом, а не реальное улучшение искусственного интеллекта, основанное на простых правилах игры.Или нет?
Итак, наконец, не могли бы вы помочь мне понять, как справиться с проблемой, которую я описал (рассуждения, умственные подходы, инструменты на python, библиотеки, примеры кода, аналогичного моей проблеме и т. Д.)?
Спасибо за любые ответы, которые помогут мне лучше понять ML, начиная с практической задачи.
Matteo
ОБНОВЛЕНИЕ 01:
Я публикую здесь скрипт на Python (Python 2.7), который отображает путь игрока А во время симуляции:
from __future__ import division
from numpy.random import choice
import numpy as np
import matplotlib.pyplot as plt
import random
import sys #sys.exit()
import time
import operator
import math
## parameters:
number_of_matches = 100 # for one simulation
max_number_of_movements_in_single_match = 100
directions = [1, 2, 3, 4] #1=up, 2=left, 3=down, 4=right
weights = [0.25, 0.25, 0.25, 0.25]
up_direction_weight = weights[0]
rectangle_width = 8 #x
rectangle_lenght = 12 #y
plot_expiration = 0.01 # seconds
## initialization:
vector_i = []
direction_i = []
half_rectangle_width = rectangle_width/2 #x
half_rectangle_lenght = rectangle_lenght/2 #y
## main code:
for j in range(number_of_matches): #j=single match
ax = plt.gca()
ax.set_aspect(aspect=1)
ax.set_xlim([0,rectangle_width])
ax.set_ylim([0,rectangle_lenght])
plt.text(0, rectangle_lenght+1.5, 'match number: ' + str(j+1), fontsize=10)
plt.text(0, rectangle_lenght+0.5, 'weights: ' + str(np.around(weights, decimals=2)), fontsize=10)
x = []
y = []
x_init = int(0 + (rectangle_width)*random.random())
#y_init = int(0 + (half_rectangle_lenght)*random.random())
y_init = int(0 + (rectangle_lenght)*random.random())
x.append(x_init)
y.append(y_init)
i=0
while True: #inside it we calculate the directions for player A in the match j
plt.scatter(x, y, s=4)
plt.plot(x, y)
plt.pause(plot_expiration)
if y_init == rectangle_lenght: # if the upper border of rectangle has been reached by player A, calculate new weights array for match j+1, the match j ends
number_of_up_directions = direction_i.count(1) # to know how many up directions in match j
var1 = number_of_up_directions / i
if var1 > up_direction_weight:
var2 = 1 - var1
var3 = var2 / 3
weights = [var1, var3, var3, var3]
up_direction_weight = var1
direction_i = []
x = []
y = []
x_init=half_rectangle_width
y_init=half_rectangle_lenght
x.append(x_init)
y.append(y_init)
break # exit from match j to start next match j+1
if i >= max_number_of_movements_in_single_match: # if single match takes too time, exit from match j to start next match j+1
direction_i = []
x = []
y = []
x_init=half_rectangle_width
y_init=half_rectangle_lenght
x.append(x_init)
y.append(y_init)
break # exit from match j to start next match j+1
i=i+1 # next position for player A in the match j
# weighed random choise/calculation of the direction for player A in the match j
direction = choice(directions, p=weights)
direction_i.append(direction)
# update position of player A in match j, according to geometric constraints
if direction == 1:
y_new = y_init + 1
if y_new >= 0 and y_new <= rectangle_lenght:
x.append(x_init)
y.append(y_new)
y_init = y_new
else:
x.append(x_init)
y.append(y_init)
if direction == 2:
x_new = x_init - 1
if x_new >= 0 and x_new <= rectangle_width:
x.append(x_new)
y.append(y_init)
x_init = x_new
else:
x.append(x_init)
y.append(y_init)
if direction == 3:
y_new = y_init - 1
if y_new >= 0 and y_new <= rectangle_lenght:
x.append(x_init)
y.append(y_new)
y_init = y_new
else:
x.append(x_init)
y.append(y_init)
if direction == 4:
x_new = x_init + 1
if x_new >= 0 and x_new <= rectangle_width:
x.append(x_new)
y.append(y_init)
x_init = x_new
else:
x.append(x_init)
y.append(y_init)
plt.show(block=False)
time.sleep(plot_expiration)
plt.close()
print(weights)
Коддалеко не оптимизирован и не может воспроизвести то, что я спрашиваю в моем первоначальном вопросе, но это первая попытка заставить что-то работать без каких-либо больших и сложных библиотек, таких как TensorFlow, Unity и т. д.…. Это очень просто, он отображает путь игрока A (см. Мой оригинальный вопрос) в нескольких матчах, и когда игрок A достигает верхней границы прямоугольника, код обновляет массив весов направления.
ИИ начинается со случайного выбора одного из 4 возможных направлений [вверх, влево, вниз, вправо].
Лучший результат, который я могу получить с этим типом ИИ (на основе бонуса, получаемого за направление вверх, если А достигает границы вверх, а вес для направления вверх является средневзвешенным значением для всех направлений в матче), это вес массив [1,0,0,0], то есть игрок А «узнает», что он может достичь верхней границы за меньшее время (и с меньшими потерями энергии), пройдя по вертикальной траектории. Это довольно просто.
Мой вопрос связан с игроком B : он должен «научиться» идти туда, где находится игрок A. Если B находится в той же позиции, что и A, B выигрывает. Что вы предлагаете для учебного ИИ игрока B? Обратите внимание, что сейчас я не хочу давать более умный ИИ игроку А, мне достаточно, чтобы он достиг верхней границы в наименьшее количество движений (вертикальная траектория).
Например (ожидаемые примеры ответов):
- игрок B может иметь случайные направления в начале, но каждый раз, когда он пересекает путь игрока A, придавать больший вес направлению B-> A для каждого нового направления, выбранного для B.
- игрок B может иметь произвольные направления в начале, но каждый раз, когда игрок B движется, придавайте больший вес направлению B-> A в зависимости от расстояния между A и B.
- ...
Спасибо