Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.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

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
C#-加速使用嵌套for循环的列表比较_C#_Algorithm_List_Object_For Loop - Fatal编程技术网

C#-加速使用嵌套for循环的列表比较

C#-加速使用嵌套for循环的列表比较,c#,algorithm,list,object,for-loop,C#,Algorithm,List,Object,For Loop,我目前正在开发一个测试程序,以确保主板上的孔不会彼此太近或重叠 为了做到这一点,我将保留名为holeInfo的对象中所有孔的X、Y坐标和半径,以及列表holeInfo列表中的对象 我目前正在使用嵌套for循环遍历所有孔,并使用基本数学公式检查孔之间的距离 以下是我使用的函数: public void checkHoleConditions() { for (int i = 0; i < holeInfoList.Count - 1; i++) { error

我目前正在开发一个测试程序,以确保主板上的孔不会彼此太近或重叠

为了做到这一点,我将保留名为holeInfo的对象中所有孔的X、Y坐标和半径,以及列表holeInfo列表中的对象

我目前正在使用嵌套for循环遍历所有孔,并使用基本数学公式检查孔之间的距离

以下是我使用的函数:

public void checkHoleConditions()
{
    for (int i = 0; i < holeInfoList.Count - 1; i++)
    {
        errorType = new List<string>();

        for (int j = i + 1; j < holeInfoList.Count; j++)
        {
            holeMinSpaceFailed = false;

            if (failsHoleConditions(holeInfoList[i], holeInfoList[j])) 
            {
                if (holeMinSpaceFailed)
                {
                    errorType.Add("X: " + holeInfoList[j].holeXCoordinate + " Y: " + holeInfoList[j].holeYCoordinate + "R: " + holeInfoList[j].holeDiameter + " too close.");
                }
                else
                {
                    errorType.Add("X: " + holeInfoList[j].holeXCoordinate + " Y: " + holeInfoList[j].holeYCoordinate + "R: " + holeInfoList[j].holeDiameter + " overlap.");
                }

                invalidHole = new InvalidHole(holeInfoList[i], errorType);
                invalidHoleList.Add(invalidHole);
                Console.WriteLine("Hole Error Detected");
            }
            else
            {
                Console.WriteLine("Hole Check Successful");
            }
        }
    }
}

public bool failsHoleConditions(HoleInfo holeOne, HoleInfo holeTwo)
    {
        float holeOneXCoordinate = holeOne.holeXCoordinate;
        float holeOneYCoordinate = holeOne.holeYCoordinate;
        float holeOneRadius = holeOne.holeDiameter / 2;

        float holeTwoXCoordinate = holeTwo.holeXCoordinate;
        float holeTwoYCoordinate = holeTwo.holeYCoordinate;
        float holeTwoRadius = holeTwo.holeDiameter / 2;

        float holeXDifferenceSquared = (float)Math.Pow((holeOneXCoordinate - holeTwoXCoordinate), 2);
        float holeYDifferenceSquared = (float)Math.Pow((holeOneYCoordinate - holeTwoYCoordinate), 2);
        float distanceBetweenCenters = (float)Math.Sqrt(holeXDifferenceSquared + holeYDifferenceSquared);

        float distanceBetweenHoles = distanceBetweenCenters - (holeOneRadius + holeTwoRadius);

        if (distanceBetweenHoles <= 0)
        {
            return true;
        }
        else if (distanceBetweenHoles <= minimumSpace)
        {
            holeMinSpaceFailed = true;
            return true;
        }
        return false;
    }
public void checkHoleConditions()
{
for(int i=0;i如果(孔之间的距离如果需要对所有孔进行测试,一种优化方法是将它们放在一个nxn矩阵中,而不是一个列表中。然后,并行执行验证。矩阵越大,核越多越好。并行也可以在列表中执行,但我不能100%确定.Net是否会决定等待每个孔由于算法是连续的,所以一直读到最后


如果您的方法使用欧几里德距离,您可以尝试根据此距离对列表进行排序。sqr(x)+sqr(y)关于0,可以先进行排序。我认为.Net可以轻松处理此排序。稍后,只需运行您的算法,直到第一个允许的电路。然后,您知道必须接受其余的,因此您将只对列表的第一个元素执行

此解决方案的灵感来自物理引擎,以及其中的优化注意碰撞检测

我并不完全知道它是如何工作的,为了更好的解决方案,你应该尝试研究ODE或Bullet动力学

基本上,解决方案是将对象(孔)分离成孤岛,并仅将每个对象的位置与同一个孤岛中的对象进行比较。如果无法找到正确分离孤岛的方法,您可以这样做:

假设一个正方形区域上有125个对象,5乘5。您可以将其划分为25个主要正方形岛,然后是8个相交岛(长岛,沿着主要岛的边缘。这些岛的最小边应该是您要计算的最小距离).Islands可能重叠。您必须分析整个列表一次才能进行此拆分。这意味着到目前为止,我们总共循环了125项-
O(n)

接下来,对于每个孤岛(总共33个,
O(n^(2/3))
,通过使用这些相同的嵌套循环,找到比必须更接近的对象。每个孤岛的总复杂度是
O((n/n^(2/3))^2)
=
O(n^(2/3))
。乘以孤岛的数量,我们得到该算法的总复杂度=
O(n^(4/3))
,它小于最初显示的
O(n^2)

希望这是有意义的。如果你想的话,我可以写一个Python演示。只是需要很多代码

编辑:
或者,您可以使用2D物理引擎,将对象绘制为直径等于孔之间最小距离的圆,然后让它检测碰撞。或者从那里获取相关代码(如果许可证允许),因为整个物理引擎对于任务来说有点过度。

编辑2:

254列出对象


我以为您正在分析254个不同的电路板。我强调的这个解决方案只有在巨大的计算负载下才有意义。

如果failsHoleConditions为真,holeMinSpaceFailed将永远不会为真
别这样胡说逻辑

x*x
Math.Pow

无需使用Sqrt-只需使用平方最小空间

类似于此。运行100万300毫秒。您的代码在几分钟内出错

static byte HoleTooClose(HoleInfo x, HoleInfo y, float minDistance)
{
    float holeSize = (x.Diameter + y.Diameter) / 2;
    float deltaX = y.X - x.X;
    float deltaY = y.Y - x.Y;

    float distanceSquared = deltaX * deltaX + deltaY * deltaY - holeSize * holeSize;

    if (distanceSquared <= 0)
    {
        return 0;
    }

    float minDistanceSquared = minDistance * minDistance;
    if (distanceSquared <= minDistanceSquared)
    {
        return 1;
    }

    return 2;
}

internal struct HoleInfo
{
    public float Diameter { get; internal set; }
    public float X { get; internal set; }
    public float Y { get; internal set; }
    public HoleInfo (float x, float y, float diameter)
    {
        X = x;
        Y = y;
        Diameter = diameter;
    }
}


static bool DistanceTooClose(System.Windows.Point x, System.Windows.Point y, Double minDistance)
{
    double deltaX = Math.Abs(y.X - x.X);
    double deltaY = Math.Abs(y.Y - x.Y);
    double distanceSquared = deltaX * deltaX + deltaY * deltaY;
    //double distance = Math.Sqrt(distanceSquared);
    Double minDistanceSquared = minDistance * minDistance;
    return (distanceSquared <= minDistanceSquared);
}
静态字节HoleTooClose(HoleInfo x,HoleInfo y,float minDistance)
{
浮动孔尺寸=(x.直径+y.直径)/2;
浮动deltaX=y.X-X.X;
浮动三角洲=y.y-x.y;
浮动距离平方=deltaX*deltaX+deltaY*deltaY-holeSize*holeSize;
如果(距离平方)看起来更合适