【问题标题】:Optimizing a simple pinball solver优化一个简单的弹球求解器
【发布时间】:2014-03-18 09:31:12
【问题描述】:

我正在尝试解决编程挑战,但只成功了一部分;我需要优化解决方案 - 这就是 的用武之地。首先,参数:

  • 给你一些线段int x1, y1, x2, y2
  • 您将获得球的起点int px, py = INT_MAX
  • 您将模拟一个球从px, py 直接向下“掉落”(y 值较小)
    • 当它与一条线相交时,它会沿着这条线直到它的下端点
    • 当没有更多的线相交时,输出px

所以,我的想法是:

  • 将行读入行元组列表int xtop, ytop, xbot, ybot
  • ybot 对行进行排序。这使我们可以跳过球已通过的线,
  • 跟踪索引imin 使得所有i < iminlines[i].ybot >= py,然后直到没有找到相交:
    • 最大化垂直相交yi = kx + m
    • 设置px, py = lines[i].{x, y}bot

问题是这个时间复杂度 ∈ θ(n2) - IOW,大输入很糟糕。

一个想法是使用k-d tree 之类的东西,但问题是计算哪些行进入哪些所谓的半空间是否不会很昂贵。

【问题讨论】:

  • 线条不能相交,对吗?
  • 只需在不可见的上下文中绘制线条,然后放下球。然后检查球是否在具有线条颜色的像素上(检查球的实际位置的颜色(也是邻居)),它是相交的。 O(1)
  • "它沿着这条线直到它的下端点。"然后它又开始直线下降了吗?还是继续沿袭上一条路线?还有什么?
  • @DavidEisenstat,他们确实不能相交。
  • @JimMischel 他们直接往下掉。

标签: c performance algorithm optimization game-physics


【解决方案1】:

听起来您好像对point location in a planar subdivision 感兴趣。我链接到的平板分解方法是更简单的选择之一;简而言之,您从线段的每个端点延伸垂直线,形成 2n + 1 个垂直 slabs。对于每个板,您计算一棵二叉树,从上到下指示哪些线段穿过板。然后,要找到球击中的位置,确定它在哪个板中,然后它击中了哪个部分(如果有的话);这两个操作都是 O(log n) 时间。

首先要计算二叉树,请使用扫描线算法。从一棵空二叉树开始,按 x 坐标的排序顺序处理端点。对于左端点,将段插入树中。对于右侧,将其从树中移除。假设段不交叉,则永远不需要在树中重新排序。天真地,我们必须在每一步之后复制树,但是将存储从 O(n^2) 降低到 O(n log n) 的一个简单策略是使用纯函数式红黑树,从而避免需要副本。

这种方法的总体运行时间和空间是 O(n log n)。

【讨论】:

    猜你喜欢
    • 2016-07-27
    • 2023-03-27
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    • 2011-04-17
    • 1970-01-01
    • 2017-06-10
    • 1970-01-01
    相关资源
    最近更新 更多