我想用机器学习方法解决的情况示例

时间:2018-05-16 08:04:25

标签: python-2.7 machine-learning

我想开始学习一些关于机器学习的知识,我决定从一个实际的例子/问题开始,我将在稍后解释,但首先我更愿意告诉你:

  1. 我不是程序员(我对Python有所了解)。
  2. 我将描述的游戏就是一个例子,我真的更感兴趣的是理解如何使用ML的标准方法尽可能独立于我想解决的游戏或问题(如果可能的话) )。
  3. 让我们开始。

    游戏描述如下:

    1. 我们有一个矩形LxH(L可以等于H),里面有两个玩家,A和B(它们是两个像素或两个小图形圆圈)。
    2. 玩家A必须从起始位置(随机)移动到结束位置,结束位置是接近A的矩形边界,以便玩家B在比赛开始时位于玩家A和该边界之间。
    3. 玩家B必须从起始位置(随机)移动到结束位置,结束位置是玩家A的位置。
    4. 如果玩家A在没有被玩家B触及的情况下到达矩形的边界(参见第2点),则A胜出B失败。
    5. 如果玩家B在A到达矩形的边界之前接触玩家A(参见第2点),A输了,B赢了。
    6. 游戏的单轮/比赛被定义为玩家A和B从起始位置(随机)到结束位置执行的一组移动(对于玩家A,在点2处描述的边界,对于玩家B而言)玩家A)的相同位置。模拟被定义为一组匹配,AI可以从中提高自己,并且越来越多地学习如何移动更好的玩家A和玩家B,以便在更短的时间内获得A或B的胜利。

      好吧,我想用机器学习方法来模拟这个简单的游戏,以便:

      一个。第一次开始游戏,随机选择玩家A和B的下一个位置:结果,我看到A和B的混乱动作没有任何意义。

      湾在一些比赛之后,该算法应该从之前的比赛中学到一些东西,以便将球员A主要移动到胜利边界,将球员B主要移动到球员A。

      ℃。在足够数量的匹配之后,即在模拟之后,我想要由AI创建一组规则(例如,针对每种情况的最佳位置值表),其可以用于在玩家玩游戏时B由用户而不是算法/计算机移动(只有玩家A通过计算机移动,其中刚刚创建的AI来自之前完成的模拟)。

      例如,我想不出任何可以帮助我解决b点的事情。也许我可以使用一个时间限制:如果玩家A或玩家B在一段时间后没有从其自己的起始位置转过多于X个像素,那么为玩家A和更大的玩家边界方向赋予更大的权重在单次比赛中为两者选择新位置时,对于玩家B的玩家A的方向加权。但在这种情况下,它将是程序员添加的强制行动,而不是来自简单游戏规则的人工智能的真正改进。或者不是?

      最后,您能否帮助我理解如何处理我描述的问题(推理,心理方法,python工具,库,现有示例代码与我的问题类似等等)?

      感谢任何回复,这些回复将帮助我从实际问题中了解更多关于ML的内容。

      利玛

      更新01:

      我在这里发布了一个python(Python 2.7)脚本,它在模拟过程中绘制了玩家A的路径:

      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个可能的方向[向上,向左,向下,向右]开始。

      我可以通过这种类型的AI获得的最佳结果(基于如果A到达边界时给予向上方向的奖励,并且向上方向的权重是匹配中所有方向的加权平均值),则是权重数组[1,0,0,0],即玩家A“学习”它可以通过沿垂直路径在更短的时间内(并且能量损失更少)到达上边界。这很简单。

      我的问题与玩家B 有关:它必须“学习”去玩家A所在的位置。如果B处于A的相同位置,则B获胜。 你对玩家B的学习AI有什么建议?请注意,现在我不想给玩家A提供更聪明的AI,这对我来说已经足够了它到达边境移动次数最少(垂直路径)。

      例如(我期望的答案的例子):

      1. 玩家B可以在开头有随机方向,但每次与玩家A的路径相交时,为B选择的每个新方向给予方向B-> A更多权重。
      2. 玩家B可以在开头有随机方向,但每次玩家B移动时,根据A和B之间的距离给予方向B-> A更多权重。
      3. ...
      4. 谢谢

1 个答案:

答案 0 :(得分:0)

如果你想在回合制游戏中使用算法(意味着玩家轮流执行动作),那么你可以使用Minimax算法。它是最好的算法,也很容易解释和实现 您可以在here

的TicTacToe游戏中找到Minimax算法的实现