游戏编程中的人工智能 补

先抱怨下Windows 64Bit下的交叉编译简直折磨死人,倒腾了几天之后决定还是切到Linux下算了。虚拟机虽然不给力,但是好歹能看出来优化后的结果。本文没什么讲的,只是将上文说到的扫雷机的进化过程中耗时最长的函数用C重新写一遍后比较下运行速度,废话不多说,直接贴代码,看结果。

Python代码

原来判断两条直线AB和CD的python代码是长下面这样的,原理不再赘述。

def LineIntersection2D(Ax, Ay, Bx, By, Cx, Cy, Dx, Dy):
    Bx_Ax = Bx-Ax
    Dy_Cy = Dy-Cy
    By_Ay = By-Ay
    Dx_Cx = Dx-Cx
    Ay_Cy = Ay-Cy
    Dx_Cx = Dx-Cx
    Ax_Cx = Ax-Cx
    Dy_Cy = Dy-Cy

    Denominator = float(Bx_Ax*Dy_Cy - By_Ay*Dx_Cx)

    if -0.000005<Denominator<0.000005: # rDenominator == sDenominator
        # lines are parallel
        return -1.0

    rNumerator  = Ay_Cy*Dx_Cx - Ax_Cx*Dy_Cy
    sNumerator  = Ay_Cy*Bx_Ax - Ax_Cx*By_Ay

    r = rNumerator / Denominator
    s = sNumerator / Denominator
    #print rNumerator, sNumerator, Denominator, r, s
    if 0<=r<=1.0 and 0<=s<=1.0:
        return r
    else:
        return -1.0

再重复下python的代码的运行效率如下:
修改之前

C代码

LineIntersection2D用Python来运行实在是太慢了,用C改写后的代码如下,可以看到逻辑上是完全一样的:

float LineIntersection2D(float Ax, float Ay, float Bx, float By, float Cx, float Cy, float Dx, float Dy) {
    float Bx_Ax = Bx-Ax;
    float Dy_Cy = Dy-Cy;
    float By_Ay = By-Ay;
    float Dx_Cx = Dx-Cx;
    float Ay_Cy = Ay-Cy;
    float Ax_Cx = Ax-Cx;

    float retVal = -1.0;

    float Denominator = (Bx_Ax*Dy_Cy - By_Ay*Dx_Cx);

    if (-0.000005<Denominator && Denominator<0.000005){
        return retVal;
    }

    float rNumerator  = Ay_Cy*Dx_Cx - Ax_Cx*Dy_Cy;
    float sNumerator  = Ay_Cy*Bx_Ax - Ax_Cx*By_Ay;

    float r = rNumerator / Denominator;
    float s = sNumerator / Denominator;
    //printf("%f, %f, %f, %f\n", rNumerator, sNumerator, r, s);
    if(0<=r && r<=1.0 && 0<=s && s<=1.0){
        retVal = r;
    }
    return retVal;
}

用C重写后的速度如下:
重写之后

局部的函数速度提高了非常多,但是代码中还有很多其他需要优化的地方,总体速度只提升了大概60%。不过本系列只讨论遗传算法和神经网络,就不再深究python代码的瓶颈在哪儿了。(其实是水平太差又懒,不知道也懒得深究 >_<)

附上C代码的完整代码凑凑字数. :)

CCollision.c

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "Python.h"

float LineIntersection2D(float Ax, float Ay, float Bx, float By, float Cx, float Cy, float Dx, float Dy) {
    float Bx_Ax = Bx-Ax;
    float Dy_Cy = Dy-Cy;
    float By_Ay = By-Ay;
    float Dx_Cx = Dx-Cx;
    float Ay_Cy = Ay-Cy;
    float Ax_Cx = Ax-Cx;

    float retVal = -1.0;

    float Denominator = (Bx_Ax*Dy_Cy - By_Ay*Dx_Cx);

    if (-0.000005<Denominator && Denominator<0.000005){
        return retVal;
    }

    float rNumerator  = Ay_Cy*Dx_Cx - Ax_Cx*Dy_Cy;
    float sNumerator  = Ay_Cy*Bx_Ax - Ax_Cx*By_Ay;

    float r = rNumerator / Denominator;
    float s = sNumerator / Denominator;
    //printf("%f, %f, %f, %f\n", rNumerator, sNumerator, r, s);
    if(0<=r && r<=1.0 && 0<=s && s<=1.0){
        retVal = r;
    }
    return retVal;

}

static PyObject *
CCollision_LineIntersection2D(PyObject *self, PyObject *args) {
    int res;
    float Ax, Ay, Bx, By, Cx, Cy, Dx, Dy;
    float returnV;
    PyObject* retval;
    //从输入参数解析出两个整型数据
    res = PyArg_ParseTuple(args, "ffffffff", &Ax, &Ay, &Bx, &By, &Cx, &Cy, &Dx, &Dy);
    if (!res) {
        return NULL;
    }
    //调用C函数进行实际操作
    returnV = LineIntersection2D(Ax, Ay, Bx, By, Cx, Cy, Dx, Dy);
    //将结果转换成一个python对象返回
    retval= (PyObject *)Py_BuildValue("f", returnV);
    return retval;
}

static PyMethodDef
CCollisionMethods[] = {
    {"LineIntersection2D", CCollision_LineIntersection2D, METH_VARARGS},
    {NULL, NULL},
};

void initCCollision() {
    Py_InitModule("CCollision", CCollisionMethods);
}

setup.py

#!/usr/bin/env python
from distutils.core import setup, Extension
MOD = 'CCollision'
setup(name=MOD, ext_modules=[Extension(MOD, sources=['CCollision.c'])])

编译安装CCollision的命令是:

python setup.py install
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值