起因

周六被小伙伴拖去游泳,美名其曰:锻炼身体。其实某人就是去泡澡的,哈哈。说正题吧,游完泳在体育场里闲逛,里面很大,转着转着看到一个保龄球馆,怀着对未知事物的好奇,决定和某人去尝试一下。我和S同学一人买了一局,按照说明,每一局分为10次,每一次有两次机会扔球。最后的比分就不说了,反正玩的很爽,最后也在边上一个厉害的大叔指点下,学会了基本的扔球姿势。

看到这你以为这是一篇叙事文?那就错了,起因是从这里开始的,我们的次数用完后,留在里面打台球(这里也有台球桌),看到不断有穿着队服一类东西的人进来,应该是来比赛的,同时又看到了赛道上面的牌子,有一个写着:289分。那分数是怎么计算的呢,怀着好奇心搜索起保龄球的积分规则来。在了解之后,我就在想一个问题:__如果是让我开发一个保龄球的游戏,那么计分程序要怎么写呢?__今天我们就从这里说起。。。

规则

先简述一下保龄球的规则,这里引用百度知道的别人的回答,每一局比赛有10格,每格有两次击球机会,我们这里关注它的得分情况,这里分为两种情况:

1-9格击球

每一格有3种可能:

第一次击球全部击倒:这种情况得分就是击倒的瓶数(10)+后两次击球击倒的总数

两次击球全部击倒:这样得分为击倒的瓶数(10)+后一次击球击倒的总数

两次击球没有全部击倒:得分为两次击倒总瓶数

第10格击球

这一格有两种可能:

前两次未能将瓶全部击倒:得分为击倒总瓶数+第9格的得分

前两次将瓶全部击倒,获得一次追加机会:得分为两次击倒总数(10)+追加时击倒的总瓶数+第9格分数

程序

规则也了解了,下面就到了写代码的时候了,为了方便,这里选择Python,版本为3.6

考虑到直观性,这里没有用交互式的程序,而是直接将击中情况抽象成矩阵(数组),算出最后总分。

输入的数据大概是这个样子:

[[0, 3], [2, 6], [3, 6], [0, 3], [3, 0], [9, 1], [6, 3], [6, 2], [4, 6], [4, 2]]

10x2的数组,代表前10格每格的击倒瓶数,如果一格内不需要第二次击球,也算作0。这里先写一个简单的数据生成函数。

import random

def top_10():

for i in range(10):

for j in range(2):

if j == 0 :

a[i][j] = random.randint(0,10)

else :

a[i][j] = random.randint(0,10-a[i][j-1])

return a

同时,我们注意到了,这个生成函数还少了点什么,没错,就是第十格的追加击球数。所以,这里再定义一个追加球生成函数

这里为了后面计算方便,也定义为[[x,y]]这种格式

def addto_num(a):

return [[random.randint(0,10),0]] if sum(a[9]) == 10 else [[0,0]]

原始数据的生成我们完成了,接下来要定义计算函数了,计算总分数

def calc_total(top):

sums = 0

index = 0

for x in top:

if x[0] == 10:

sums += 10

if top[index+1][0] == 10:

sums += 10 + top[index+2][0]

else:

sums += sum(top[index+1])

elif sum(x) == 10:

sums += 10 + top[index+1][0]

else:

sums += sum(x)

index+=1

if index == 9:

break

sums += sum(top[8]+top[9]+top[10])

return sums

代码写的不是很好看,大家请谅解啊,不过整个完整的功能是做完了,我们可以写个方法测试下

tmp1 = top_10()

add1 = addto_num(tmp1)

c = calc_total(tmp1+add1)

print(c)

78

神经网络版

想必大家也了解,当下最火的就是AI,而作为实现AI的其中一种手段,深度学习必不可少。最近也在学习这方面的知识(ps:给沐神疯狂打call,强烈推荐他的深度学习课程,链接大家自己去搜,就不做广告了),虽然说自己连入门都算不上,但还是想实现一下自己版本的。

于是就有了这个:

深度学习版本的保龄球得分计算方法

这里我们用到了mxnet这个深度学习框架,最基础的部分的两个库ndarray和autograd

首先,我们是基于线性回归这个最简单也是最基础的神经网络实现的,模型看起来就像这样

$$\boldsymbol{\hat{y}} = X \boldsymbol{w} + b$$

同时定义它的损失函数,也就是计算预测值和实际值的差距,这里用两个的平方误差来计算,模型是这样

$$\sum_{i=1}^n (\hat{y}_i-y_i)^2.$$

首先,我们要__创建数据集__

因为我们之前定义的是Python的list,所以在这里要转换成mxnet的内置数组ndarray

不过在此之前我们要先改进下我们的生成函数,之前是由两个函数组成,现在为了方便,我们合成一个。同时,计算方法改造成ndarray版本的。

from mxnet import ndarray as nd

from mxnet import autograd

def init_data():

for i in range(0,10):

for j in range(0,2):

if j == 0 :

a[i][j] = random.randint(0, 10)

else :

a[i][j] = random.randint(0,10-a[i][j-1])

return a+[[random.randint(0,10),0]] if sum(a[9]) == 10 else a+[[0,0]]

def calc_total_nd(top):

sums = 0

index = 0

for x in top:

if x[0].asscalar() == 10:

sums += 10

if top[index+1][0].asscalar() == 10:

sums += 10 + top[index+2][0].asscalar()

else:

sums += nd.sum(top[index+1]).asscalar()

elif nd.sum(x).asscalar() == 10:

sums += 10 + top[index+1][0].asscalar()

else:

sums += nd.sum(x).asscalar()

index+=1

if index == 9:

break

sums += nd.sum(top[8]+top[9]+top[10]).asscalar()

return sums

num_inputs = 22

num_examples = 1000

X = nd.zeros(shape=(num_examples,11,2))

for i in X:

i[:] = nd.array(init_data())

y = nd.array([calc_total_nd(i) for i in X])

然后是定义 数据读取方法

目的是在后面训练时随机遍历我们的数据集,这里参考了沐神教程里的方法。

import random

batch_size = 10

def data_iter():

# 产生一个随机索引

idx = list(range(num_examples))

random.shuffle(idx)

for i in range(0, num_examples, batch_size):

j = nd.array(idx[i:min(i+batch_size,num_examples)])

yield nd.take(X, j), nd.take(y, j)

尝试着读取一个

for data, label in data_iter():

print(data, label)

break

[[[ 2. 0.]

[ 7. 0.]

[ 1. 7.]

[ 2. 2.]

[ 6. 2.]

[ 0. 5.]

[ 0. 5.]

[ 7. 1.]

[ 6. 4.]

[ 3. 0.]

[ 0. 0.]]

[[ 6. 3.]

[ 4. 2.]

[ 2. 4.]

[ 8. 2.]

[ 4. 6.]

[ 6. 3.]

[ 2. 6.]

[ 6. 3.]

[ 2. 3.]

[ 8. 2.]

[ 7. 0.]]

[[ 10. 0.]

[ 8. 0.]

[ 2. 2.]

[ 8. 2.]

[ 0. 3.]

[ 10. 0.]

[ 10. 0.]

[ 6. 3.]

[ 10. 0.]

[ 1. 7.]

[ 0. 0.]]

[[ 5. 1.]

[ 6. 2.]

[ 10. 0.]

[ 3. 6.]

[ 8. 2.]

[ 10. 0.]

[ 4. 4.]

[ 2. 4.]

[ 2. 0.]

[ 7. 3.]

[ 10. 0.]]

[[ 6. 2.]

[ 8. 0.]

[ 0. 0.]

[ 9. 0.]

[ 6. 4.]

[ 5. 3.]

[ 5. 0.]

[ 1. 6.]

[ 0. 1.]

[ 4. 4.]

[ 0. 0.]]

[[ 5. 5.]

[ 6. 3.]

[ 0. 7.]

[ 2. 8.]

[ 10. 0.]

[ 4. 0.]

[ 1. 5.]

[ 1. 2.]

[ 1. 2.]

[ 0. 2.]

[ 0. 0.]]

[[ 10. 0.]

[ 0. 3.]

[ 3. 7.]

[ 3. 1.]

[ 8. 1.]

[ 4. 2.]

[ 8. 1.]

[ 6. 4.]

[ 10. 0.]

[ 5. 0.]

[ 0. 0.]]

[[ 8. 2.]

[ 10. 0.]

[ 6. 0.]

[ 10. 0.]

[ 1. 4.]

[ 2. 6.]

[ 9. 0.]

[ 5. 5.]

[ 7. 1.]

[ 5. 1.]

[ 0. 0.]]

[[ 9. 1.]

[ 7. 1.]

[ 6. 3.]

[ 0. 5.]

[ 7. 3.]

[ 7. 1.]

[ 6. 3.]

[ 3. 1.]

[ 3. 3.]

[ 10. 0.]

[ 6. 0.]]

[[ 0. 10.]

[ 4. 3.]

[ 2. 6.]

[ 2. 6.]

[ 4. 1.]

[ 8. 1.]

[ 5. 4.]

[ 3. 6.]

[ 6. 4.]

[ 4. 2.]

[ 0. 0.]]]

[ 73. 104. 133. 118. 70. 87. 107. 118. 105. 99.]

数据准备好了,现在要定义一个__初始化的模型参数__

这里随机生成一个就好了,后面我们会通过训练,慢慢学习完善这个参数,这也是深度学习的目的

w = nd.random_normal(shape=(num_inputs, ))

b = nd.random_normal(shape=(1,))

params = [w, b]

print(params)

[

[ 0.50869578 -0.16038011 0.91511744 0.84187603 -0.49177799 -1.00553632

-1.55609238 3.13221502 -0.15748753 -0.4358989 -0.52664566 -0.49295077

-0.17884982 1.43718672 0.43164727 -0.31814137 0.46760127 -0.16282491

0.17287086 0.6836102 0.76158988 1.61066961]

,

[ 9.91063134e-05]

]

然后附上梯度,也就是让后面autograde可以对这个函数求导

for param in params:

param.attach_grad()

定义模型和损失函数

这里要注意的是:我们的维度不是1,所以要把数组的维度reshape一下变成一维数组

def net(X):

return nd.dot(X.reshape((-1,num_inputs)), w) + b

def square_loss(yhat, y):

return (yhat - y.reshape(yhat.shape)) ** 2

然后是优化方法,也就是学习方法,让函数去学习参数

def SGD(params, lr):

for param in params:

param[:] = param - lr * param.grad

最后就是__训练__了

epochs = 5

learning_rate = .0001

for e in range(epochs):

total_loss = 0

for data, label in data_iter():

with autograd.record():

output = net(data)

loss = square_loss(output, label)

loss.backward()

SGD(params, learning_rate/batch_size)

total_loss += nd.sum(loss).asscalar()

print("Epoch %d, average loss: %f" % (e, total_loss/num_examples))

Epoch 0, average loss: 82.049488

Epoch 1, average loss: 82.009441

Epoch 2, average loss: 81.810044

Epoch 3, average loss: 82.243776

Epoch 4, average loss: 82.023799

最后来验证下我们的预测结果

for data, label in data_iter():

print("实际分数")

print(label)

print("预测分数")

print(net(data))

break

实际分数

[ 108. 77. 102. 115. 85. 110. 76. 124. 78. 87.]

预测分数

[ 107.43678284 86.52748871 101.92710114 116.50645447 90.5655899

115.31760406 80.10424805 118.94145203 84.49520111 95.17882538]

保龄球计分java代码_从 保龄球得分计算方法 浅析 深度学习相关推荐

  1. 从 保龄球得分计算方法 浅析 深度学习

    起因 周六被小伙伴拖去游泳,美名其曰:锻炼身体.其实某人就是去泡澡的,哈哈.说正题吧,游完泳在体育场里闲逛,里面很大,转着转着看到一个保龄球馆,怀着对未知事物的好奇,决定和某人去尝试一下.我和S同学一 ...

  2. 一文弄懂元学习 (Meta Learing)(附代码实战)《繁凡的深度学习笔记》第 15 章 元学习详解 (上)万字中文综述

    <繁凡的深度学习笔记>第 15 章 元学习详解 (上)万字中文综述(DL笔记整理系列) 3043331995@qq.com https://fanfansann.blog.csdn.net ...

  3. 脑电EEG代码开源分享 【6. 分类模型-深度学习篇】

    往期文章 希望了解更多的道友点这里 0. 分享[脑机接口 + 人工智能]的学习之路 1.1 . 脑电EEG代码开源分享 [1.前置准备-静息态篇] 1.2 . 脑电EEG代码开源分享 [1.前置准备- ...

  4. 给定下面的java代码_则运行_会产生类型的异常_JavaSE_笔试题_单选选择题

    JavaSE_笔试题_单选选择题1 1. 下面哪一种描述是正确的()? A:abstract修饰符可修饰字段.方法和类. B:抽象方法的body部分必须用一对大括号{}包住. C:声明抽象方法,大括号 ...

  5. 连连看java代码_连连看 - java代码库 - 云代码

    [java]代码库/* * To change this license header, choose License Headers in Project Properties. * To chan ...

  6. 关联规则java代码_重量挖掘关联规则挖掘方法,哪个大神可以将以下伪代码转换为Java代码?...

    重量挖掘关联规则挖掘方法,哪个大神可以将以下伪代码转换为Java代码? 10 改进的加权关联规则算法的基本步骤与Apriori算法相似: 首先找到加权支持度不小于用户指定的最小加权支持度的所有频繁项集 ...

  7. amd cpu不能在cmd环境下运行java代码_「我们一起学Java02」JDK、JRE、JVM简介,Java开发平台的搭建...

    Hello,各位头条的读者大家好!接下来一段时间小编将和大家一起学习Java,"我们一起学Java"专题将会持续更新,欢迎大家关注.这里是"我们一起学Java" ...

  8. amd cpu不能在cmd环境下运行java代码_如何在Windows10中配置java的JDK环境

    今天给大家分享一下如何配置java的JDK环境.操作步骤如下: 1.下载好 jdk 的安装文件,我下载的是 jdk-10.0.1_windows-x64_bin.exe 这个版本的安装文件: 2.使用 ...

  9. java 代码 _程序员用1.5小时写出的Java代码,让同事瞠目结舌!直呼优秀

    1.曾经不止一次在生产中见过类似这样的代码: 这有很多变种,例如用 Integer.valueOf(1). (Integer)1 之类的,那些细节都不重要.重要的是:凭空用一个 Integer 对象作 ...

  10. 双表查询java代码_多表增删改查

    [java]代码库package com.ww.service; import java.lang.reflect.Array; import java.sql.Connection; import ...

最新文章

  1. BigBiGAN问世,“GAN父”都说酷的无监督表示学习模型有多优秀?
  2. 张亚勤2020寄语哥伦比亚大学毕业生:引领未知时代
  3. dao加service加mysql实例_SpringBoot项目整合mybatis的方法步骤与实例
  4. Linkis源码目录结构详解
  5. linux vi删除操作,vi删除操作
  6. 前端笔记-thymeleaf显示数据及隐藏数据
  7. python fun函数、求4x4整型数组的主对角线元素的和_python中多维数组中列major的numpy整形...
  8. php钓鱼怎么使用方法,路亚钓法操作步骤及抛投技巧
  9. 挑战程序设计竞赛: 三角形
  10. 华为安装gsm框架_gms安装器华为下载-GMS安装器 安卓版v3.0-PC6安卓网
  11. 站在商业、技术与人文三叉路口的实体书店
  12. 祥云杯2020 Crypto wp
  13. 基于hi3531、ffmpeg、x264的h264压缩
  14. 计算机键盘重复,电脑怎么设置键盘重复延迟和重复速度?
  15. modprobe 及 配置文件 /etc/modprobe.conf
  16. PS里面的快速选区工具
  17. 融云限量开放通信云服务 IM商用版199元首购享优惠
  18. 新手入门——计算机概论
  19. Flash 编程视频教程
  20. 如何使用Flutter的指纹设置本地认证

热门文章

  1. windows server域服务器作用,windows server 2012 r2AD域搭建以及域的简单功能介绍
  2. linux phy fixed-link
  3. 解决 button 的背景图片被拉伸
  4. 广域网加速方案--Riverbed
  5. 从PCC到MIC,理解变量之间的相关性
  6. 写得太好了,大约《越狱》批评(发布)
  7. 用计算机如何计算投资回收期,动态投资回收期怎么算的?
  8. JS封装小写字母转大写
  9. xshell生成xsh文件路径
  10. equal和==的区别