我的C#Windows窗体应用程序中有一段代码如下所示:
List<string> RESULT_LIST = new List<string>();
int[] arr = My_LIST.ToArray();
string s = "";
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < arr.Length; i++)
{
int counter = i;
for (int j = 1; j <= arr.Length; j++)
{
counter++;
if (counter == arr.Length)
{
counter = 0;
}
s += arr[counter].ToString();
RESULT_LIST.Add(s);
}
s = "";
}
sw.Stop();
TimeSpan ts = sw.Elapsed;
string elapsedTime = String.Format("{0:00}", ts.TotalMilliseconds * 1000);
MessageBox.Show(elapsedTime);
我使用此代码获取“我的列表”编号的任意组合。我对My_LIST表现得像递归一样。下面的图片非常清楚地表明了我的目的:
我需要做的就是:
制定公式计算这两者的近似运行时间 嵌套for循环以猜测任何长度的运行时间并帮助 用户知道他/她必须等待的大致时间。
我使用了 C#秒表这样:Stopwatch sw = new Stopwatch();
显示运行时间,以下是结果(请注意,为了减少出错的可能性,我重复了每个长度计算三次,数字分别显示第一次,第二次和第三次尝试的纳秒秒的时间。):
arr.Length = 400;
127838 - 107251 - 100898 arr.Length = 800;
751282 - 750574 - 739869 arr.Length = 1200;
2320517 - 2136107 - 2146099 arr.Length = 2000;
8502631 - 7554743 - 7635173 请注意,My_LIST中只有一位个数字来计算时间 在列表中添加大致相等的数字。
如何找出arr.Length
与运行时间之间的关系?
答案 0 :(得分:6)
首先,假设您已经检查过该算法,并注意到它在数组长度上似乎是二次方的。这向我们表明,运行所需的时间应该是形式的函数
t = A + B n + C n 2
您通过使用不同的n值和测量t多次运行代码来收集一些观察结果。这是一个很好的方法。
现在的问题是:A,B和C的最佳值是什么,以便它们与您的观察结果紧密匹配?
这个问题可以通过各种方式解决;我建议您使用最小二乘回归方法来开始,看看您是否获得了良好的结果。这里有一个页面:
www.efunda.com/math/leastsquares/lstsqr2dcurve.cfm
更新:我只是再次查看你的算法并意识到它是立方的,因为你在内部循环中有一个二次字符串连接。所以这种技术可能效果不好。我建议您使用StringBuilder
使算法成为二次方。
现在,假设你提前不知道问题是二次方的。那你如何确定公式呢?一个好的开始是在日志规模纸上绘制你的点数;如果它们大致形成一条直线,则该线的斜率为您提供关于多项式幂的线索。如果他们没有形成一条直线 - 那么,当你来到它时,穿过那座桥。
答案 1 :(得分:2)
那你要在这里做一些数学。
由于总运行次数恰好是n ^ 2,因此不是O(n ^ 2),而是n ^ 2次。
然后你可以做的是为处理的项目数量保留一个计数器变量,并使用数学来找出估计值
int numItemProcessed;
int timeElapsed;//read from stop watch
int totalItems = n * n;
int remainingEstimate = ((float) totalItems - numItemProcessed) / numItemProcessed) * timeElapsed
答案 2 :(得分:1)
不要假设算法在时间复杂度上必然是N ^ 2。
获取数字的平均值,并在对数 - 对数图上绘制最佳拟合,然后测量梯度。这将使您了解多项式中的最大项。 (见维基百科log-log plot)
完成后,您可以进行最小二乘回归,以计算出正确顺序的多项式系数。这将允许从数据中估计出看不见问题所花费的时间。
注意:正如Eric Lippert所说,这取决于您想要测量的内容 - 根据您的使用情况,平均值可能不合适 - 第一次运行时间可能更正确。
此方法适用于任何多项式算法。它还会告诉您算法是否为多项式(非多项式运行时间不会在对数 - 对数图上给出直线)。