Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 人工检查器与程序员(was:检测是否有圆圈重叠的算法)_Algorithm_Language Agnostic - Fatal编程技术网

Algorithm 人工检查器与程序员(was:检测是否有圆圈重叠的算法)

Algorithm 人工检查器与程序员(was:检测是否有圆圈重叠的算法),algorithm,language-agnostic,Algorithm,Language Agnostic,问题 这个问题实际上是在今天的工作中提出来的。我们正在计划一项实验,向用户展示一系列地图。每张地图上有31个符号。每个符号也有一个标签。我们注意到,在少数情况下,标签重叠,导致其中一个标签无法读取 我们最终以老式的方式识别问题符号——通过逐个查看地图并记下我们发现的任何问题符号的ID——但我认为这个问题可以用算法很容易地解决。目视检查所有地图(使用公认笨重的实验数据收集工具)大约需要一个人小时 我很好奇这个网站上的人能以多快的速度解决这个问题,我也对你提出的算法感兴趣。(注意:这不是一个家庭作业

问题

这个问题实际上是在今天的工作中提出来的。我们正在计划一项实验,向用户展示一系列地图。每张地图上有31个符号。每个符号也有一个标签。我们注意到,在少数情况下,标签重叠,导致其中一个标签无法读取

我们最终以老式的方式识别问题符号——通过逐个查看地图并记下我们发现的任何问题符号的ID——但我认为这个问题可以用算法很容易地解决。目视检查所有地图(使用公认笨重的实验数据收集工具)大约需要一个人小时

我很好奇这个网站上的人能以多快的速度解决这个问题,我也对你提出的算法感兴趣。(注意:这不是一个家庭作业问题,尽管我认为这会成为一个有趣的家庭作业或面试问题。)

规格

  • 地图:24
  • 地图大小(像素):1024 X 768
  • 每个地图的符号(圆圈):31
  • 符号直径(像素):60
符号坐标存储在具有以下列的电子表格(假定为制表符分隔的文本文件)中:

  • MapId
    (范围:1-24)
  • SymbolId
    (范围:1-744(24个地图x 31个符号/地图=744个总符号)
  • XCoordinate
    (范围:0-1024)
  • YCoordinate
    (范围:0-768)
假设所有四列都包含
整数

目标

你能以多快的速度想出一个算法(你选择的语言):

  • 读取包含输入数据的以制表符分隔的文本文件
  • 确定每个贴图是否有任何符号重叠
  • 如果有任何符号重叠,则
    SymbolId
    s的报告不符合要求
  • 您的答案应包含

  • 您的算法必须满足上述三个目标
  • 你花了多长时间来思考和写作(以你的名义)。注意:你不需要计算阅读和理解问题所花的时间,但一旦你开始思考解决方案的想法,就开始计时
  • 我对您的算法运行速度或内存使用效率不感兴趣。我正在寻找一个快速、肮脏但准确、可靠的问题解决方案。

    对于每个映射:

    If distance(A.center, B.center) < (A.radius+B.radius)
       the circles overlap.
    
    如果距离(A.中心,B.中心)<(A.半径+B.半径)
    圆圈重叠。
    
    在你的例子中,似乎每个圆都有相同的半径,但我考虑了每个圆有不同半径的可能性,以防万一

    至于要想多久,有点难说——比加载完整描述的页面所花的时间要少。然后我必须阅读一些资料,以确认基本问题是从标题看出来的是什么

    编辑:如果你有很多圆圈,可能值得做一些排序来消除不必要的重叠测试,但如果每张地图只有30个圆圈,那可能不值得——你需要一台真正古老的计算机来完成这项工作,需要一整秒钟

    对不起,我必须离开一段时间让孩子们参加一个滚轴曲棍球比赛。不管怎样,虽然我还没有测试过,但我在C++中的程序大概是10-12分钟,我必须在那里打个电话,所以我没有确切的时间):

    #包括
    #包括
    #包括
    结构点{
    int-id,x,y;
    };
    std::istream&operator>>(std::istream&is,point&p){
    返回值为>>p.id>>p.x>>p.y;
    }
    typedef-std::向量映射;
    双区(点常数和a,点常数和b){
    双x=a.x-b.x;
    双y=a.y-b.y;
    返回sqrt(x*x+y*y);
    }
    int main(){
    std::矢量地图(24);
    int mapID;
    而(std::cin>>mapID){
    点温;
    标准:cin>>温度;
    映射[mapID]。推回(临时);
    }
    
    对于(int i=0;i我的第一个想法是Jerry已经发布的简单的O(N2)算法,除了一个小的例外:距离2更容易计算,因为它不需要平方根,所以将其与(半径之和)2进行比较

    我的第二个想法是通过包含您的所有观点的解决方案来增强该解决方案,这有助于减少需要进行的比较的数量

    写这个答案要比想出这两种解决方案花费更长的时间——也许10秒。这种问题在计算机图形学中很常见,我只是在重复我以前看到的


    在Haskell中快速编写解决方案1的实现(耗时不到一分钟):

    import-Control.Monad
    导入数据。列表
    半径=30
    main=do
    
    点如果你在寻找加速答案的方法,你也可以尝试“扫除和修剪”。

    这里有一些比O(n^2)更快的方法其中n=符号数。使用动态数组矩阵,如STL
    vector
    来表示图像中的每个像素。计算每个圆所占用的像素,并
    将其
    symbol
    推入圆中每个像素的数组中。处理完所有圆后,只需查看每个像素,如果有任何像素具有如果数组中有多个符号,您就知道哪个
    symbold
    s是冲突的

    所用时间:~5分钟


    更新:根据新的要求,我的初始算法可以稍加修改,以读取每一行,更新上面为每个符号定义的像素-
    符号地图,然后转到下一个地图。

    假设您的电子表格软件具有SQL功能,我会通过查询运行它:

    select 
       s1.symbolId,s2.symbolId
    from 
       symbols s1 
       join 
       symbols s2 
    where 
       s1.mapid=s2.mapid 
       and 
       s1.symbolid<s2.symbolid 
       and 
       ((s1.xcoordinate-s2.xcoordinate)*
       (s1.xcoordinate-s2.xcoordinate)+
       (s1.ycoordinate-s2.ycoordinate)*
       (s1.ycoordinate-s2.ycoordinate))
       <(r+r)*(r+r)
    
    选择
    s1.符号化,s2.符号化
    从…起
    符号s1
    参加
    符号s2
    哪里
    s1.mapid=s2.mapid
    及
    
    s1.符号数据
    XCoordinate
    YCoordinate
    整数?是的,我编辑了m
    import Control.Monad
    import Data.List
    radius = 30
    main = do
        points <- fmap (map (map read . words) . lines) getContents
        mapM_ print $ overlapping (points :: [[Int]])
    overlapping list = do
        [m1, s1, x1, y1]:rest <- tails list
        [m2, s2, x2, y2] <- rest
        guard $ m1 == m2 && (x2-x1)^2 + (y2-y1)^2 < 2*radius^2
        return ((m1, s1), (m2, s2))
    
    select 
       s1.symbolId,s2.symbolId
    from 
       symbols s1 
       join 
       symbols s2 
    where 
       s1.mapid=s2.mapid 
       and 
       s1.symbolid<s2.symbolid 
       and 
       ((s1.xcoordinate-s2.xcoordinate)*
       (s1.xcoordinate-s2.xcoordinate)+
       (s1.ycoordinate-s2.ycoordinate)*
       (s1.ycoordinate-s2.ycoordinate))
       <(r+r)*(r+r)