【问题标题】:Time Complexity of fitness function for GA遗传算法适应度函数的时间复杂度
【发布时间】:2017-09-26 15:26:13
【问题描述】:

我正在尝试计算我编写的遗传算法的适应度函数的时间复杂度。

我做了什么:我已经阅读了一些文章和示例

然而,这些都不是真正令人满意的,我可以说:现在我知道如何在我的代码中应用它了。

让我向您展示我的适应度函数,我猜了几个执行时间。

    public static List<double> calculateFitness(List<List<Point3d>> cF, Point3d startpoint)
    {
        List<double> Fitness = new List<double>(); // 1+1
        for (int i = 0; i < cF.Count; i++)  // 1 ; N+1 ; N
        {
            Point3d actual;  // N 
            Point3d next;  // N
            double distance;  // N 
            double totalDistance = startpoint.DistanceTo(cF[i][0]);  // (1+1+1+1)*N
            for (int j = 0; j < cF[i].Count - 1; j++)  // { 1 ; N ; N-1 }*N
            {
                actual = cF[i][j];  // (1+1)*(N-1)
                next = cF[i][j + 1];  // (1+1)*(N-1)

                distance = actual.DistanceTo(next);  // (1+1+1+1)*(N-1)
                totalDistance += distance;  // (1+1)*(N-1)
            }
            totalDistance += cF[i][cF[i].Count - 1].DistanceTo(startpoint);  // (1+1+1+1)*N
            Fitness.Add(totalDistance);  // N
        }
        return Fitness;  // 1
    }

您知道任何有示例的链接,以便我可以学习如何计算面向使用的时间复杂度。 或者也许有人可以在这里解释。例如,对于这段代码,我完全不确定:double totalDistance = startpoint.DistanceTo(cF[i][0]); --> (1+1)N ? 或者这样:actual = cF[i][j]; --> (1+1)NN ?

所以一般来说,时间复杂度是:1+1+ (1+N+1+N+N+N+N+4N+ N*{ 1+N+N-1+2*(N-1 )+2*(N-1)+4*(N-1)+2*(N-1) } +4N+N) = 2 + (2+14N+ N*{12N-10}) = 12N^2 + 4N + 4 = O(N^2)

【问题讨论】:

标签: c# time-complexity genetic-algorithm


【解决方案1】:

通常在进行 Big-O 分析时,我们会忽略常数时间运算(即 O(1))和任何常数因素。我们只是想了解算法与 N 的缩放程度。这在实践中意味着我们正在寻找循环和非常量时间操作

考虑到这一点,我在下面复制了您的代码,然后注释了某些兴趣点。

public static List<double> calculateFitness(List<List<Point3d>> cF, Point3d startpoint)
{
    List<double> Fitness = new List<double>();
    for (int i = 0; i < cF.Count; i++)  // 1.
    {
        Point3d actual;  // 2. 
        Point3d next; 
        double distance;  
        double totalDistance = startpoint.DistanceTo(cF[i][0]);  // 3.
        for (int j = 0; j < cF[i].Count - 1; j++)  // 4.
        {
            actual = cF[i][j];  // 5.
            next = cF[i][j + 1];

            distance = actual.DistanceTo(next);
            totalDistance += distance;
        }
        totalDistance += cF[i][cF[i].Count - 1].DistanceTo(startpoint);
        Fitness.Add(totalDistance); // 6.
    }
    return Fitness;
}
  1. i 循环将执行 N 次,其中 NcF.Count。如果我们非常正式,我们会说比较i &lt; cF.Count 需要一些恒定时间c,而i++ 需要一些恒定时间d。由于它们被执行了 N 次,所以这里的总时间是 cdN。但正如我提到的,Big-O 忽略了这些常数因素,因此我们说它是 O(N)。

  2. 这些声明是常数时间,O(1)。

  3. 索引到 .NET List is documented 为 O(1)。我找不到 DistanceTo 方法的文档,但我无法想象它只是 O(1),因为它是简单的数学运算。

  4. 这里我们有另一个循环执行 N 次。如果我们对此要求严格,我们将在这里引入第二个变量,因为cF[i].Count 不一定等于cF.Count。我不会那么严格的。

  5. 同样,索引到列表是 O(1)。

  6. 这实际上是一个棘手的问题。 Add方法is documented如下:

    如果 Count 小于 Capacity,则此方法是 O(1) 操作。如果需要增加容量以容纳新元素,则此方法变为 O(n) 操作,其中 n 为 Count。

    • 这通常是如何实现的,操作大部分时间是 O(1),但偶尔是 O(n),其中 n 是列表的长度在这种情况下被添加到Fitness。这通常称为amortized O(1)。

所以最后你主要只有 O(1) 操作。但是,在另一个 O(N) 循环中存在一个 O(N) 循环。所以整个算法是O(N) * O(N) = O(N2) .

【讨论】:

  • 您好,感谢您抽出宝贵时间。你的回答真的很有帮助。我实际上知道,当您进行 Big-O 分析时,您必须忽略常数时间操作。但是我必须写一份关于我的遗传算法的报告,我希望分析是完整的。只有当我真正理解它时,我才能写出时间复杂度。 for 循环中的声明;不是执行了N次吗?因为每次迭代都会执行它?你介意再看看我认为时间复杂度可能是多少?我将在我的问题块中更改它。我真的很感激。
猜你喜欢
  • 1970-01-01
  • 2020-05-12
  • 1970-01-01
  • 2023-02-20
  • 2011-10-07
  • 1970-01-01
  • 2011-04-07
  • 2011-12-21
  • 2023-03-15
相关资源
最近更新 更多