c# - 在 map/2d 数组中查找最近的(几何上)非零值

标签 c# algorithm graph multidimensional-array complexity-theory

我有一个二维数组,代表图片中的选择性数据。所有无趣的数据都设置为 0。从两个索引中,我需要找到最接近的值 - 在几何上 - 不为索引(表示坐标)的 0。

到目前为止,我的方法是在圆圈中检查以兴趣点为中心的值,在每个没有找到非零值的圆圈通过后增加半径。

此方法的复杂度呈指数级增长,当最近点距离超过 ~25 像素时,程序会花费很长时间。

对于实现此目的的不同方法/现有算法,您有什么建议吗?

编辑:根据请求,我当前的代码如下:

        int height;
        int width;
        ushort[,] _2dfat;

        private ushort getAssociatedFat(int centerX, int centerY) 
        {
            int radiusmax = (int)Math.Ceiling(Math.Sqrt(Math.Pow(height,2) + Math.Pow(width, 2) + 1));
            return getAssociatedFat(1, centerX, centerY,radiusmax); 
        }

        private ushort getAssociatedFat(int radius, int centerX, int centerY,int radiusmax) //RECURSIVE METHOD: requires extensive analysis and testing
        {

            ushort max=circleSym8(centerX, centerY, radius);
            if (max != 0) return max;
            else if (radius <= radiusmax)
                return getAssociatedFat(radius + 1, centerX, centerY, radiusmax);
            else 
            { 
                MessageBox.Show("WARNING: empty fat array/image"); 
                return 0; 
            }
        }

        private ushort getMax(ushort max, int x, int y)
        {
            try
            {
                if (_2dfat[y, x] == 0) return max;
                else if (_2dfat[y, x] > max) return _2dfat[y, x];
                else return max;
            }
            catch (IndexOutOfRangeException) { return max; }


        }

        private ushort circleSym8(int xCenter, int yCenter, int radius)
        {
            int x, y, r2;
            r2 = radius * radius;
            ushort max=0;
            max=getMax(max, xCenter, yCenter + radius);
            max = getMax(max, xCenter, yCenter - radius);
            max = getMax(max, xCenter + radius, yCenter);
            max = getMax(max, xCenter - radius, yCenter);

            y = radius;
            x = 1;
            y = (int)(Math.Sqrt(r2 - 1) + 0.5);
            while (x < y)
            {
                max = getMax(max, xCenter + x, yCenter + y);
                max = getMax(max, xCenter + x, yCenter - y);
                max = getMax(max, xCenter - x, yCenter + y);
                max = getMax(max, xCenter - x, yCenter - y);
                max = getMax(max, xCenter + y, yCenter + x);
                max = getMax(max, xCenter + y, yCenter - x);
                max = getMax(max, xCenter - y, yCenter + x);
                max = getMax(max, xCenter - y, yCenter - x);
                x += 1;
                y = (int)(Math.Sqrt(r2 - x * x) + 0.5);
            }
            if (x == y)
            {
                max = getMax(max, xCenter + x, yCenter + y);
                max = getMax(max, xCenter + x, yCenter - y);
                max = getMax(max, xCenter - x, yCenter + y);
                max = getMax(max, xCenter - x, yCenter - y);
            }
            return max;
        }

最佳答案

您可以将有趣的数据存储为 Quadtree 中的点或 kd-tree并以这种方式执行范围搜索。这些数据结构针对您正在执行的查找类型进行了优化,并且会降低每次搜索的复杂性。

我设想一个足够的四叉树实现提供以下内容:

// Given some point in the quadtree, walk upwards and outwards
// returning points found ordered by distance
var nearestNeighbor = quadTree.Neighbors(point)
                              .OrderBy(pp => point.Distance(pp))
                              .First();

关于c# - 在 map/2d 数组中查找最近的(几何上)非零值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13459121/

相关文章:

c# - 将鼠标事件传递给父控件

c# - 用户控件中的条件

algorithm - 在社交网络中查找 “publisher” 的 O(n) 算法

数组元素的PHP组合

java - OrientDB顶点标签和顶点类的区别

c# - 将 app.config 文件重定位到自定义路径

c# - Fluent Nhibernate where 子句一对多

c++ - 查找圆内最近的坐标

c++ - 使用 Boost Graph Library 将 boost 动态属性写入文件

algorithm - Flood It 游戏算法