主题:第73次编程比赛结果
boxertony [专家分:23030] 发布于 2008-10-07 23:29:00
测试结果如下:
2楼:
k=1 :耗时110毫秒;
k=10 :耗时79毫秒;
k=100 :耗时187毫秒;
k=1000 :耗时109毫秒;
k=10000 :耗时31毫秒;
k=100000 :耗时125毫秒;
k=1000000 :耗时156毫秒;
k=5000000 :耗时141毫秒;
总共花费时间938毫秒。
3楼:
k=1 :耗时15毫秒;
k=10 :耗时78毫秒;
k=100 :耗时94毫秒;
k=1000 :耗时187毫秒;
k=10000 :耗时141毫秒;
k=100000 :耗时110毫秒;
k=1000000 :耗时172毫秒;
k=5000000 :耗时250毫秒;
总共花费时间1047毫秒。
4楼: (n=100,000) (程序不太符合要求,函数参数顺序不符合我给定的函数原型)
k=1 :耗时0毫秒;
k=10 :耗时0毫秒;
k=100 :耗时15毫秒;
k=1000 :耗时125毫秒;
k=10000 :耗时1469毫秒;
总共花费时间1609毫秒。
5楼:基本同4楼,不再测试。
6楼:完全不符合要求,不再测试。
7楼:(严格说来也是不符合我的要求的,函数名不一致)
k=1 :耗时125毫秒;
k=10 :耗时141毫秒;
k=100 :耗时94毫秒;
k=1000 :耗时172毫秒;
k=10000 :耗时109毫秒;
k=100000 :耗时125毫秒;
k=1000000 :耗时172毫秒;
k=5000000 :耗时203毫秒;
总共花费时间1141毫秒。
8楼: (错误原因在于由于堆的下标是从0开始的,所以current/2并不一定是parent)
k=1 :耗时16毫秒;
k=10 :耗时0毫秒;
k=100 :耗时16毫秒;
k=1000 :耗时15毫秒;
k=10000 :耗时31毫秒;
k=100000 :耗时125毫秒;
k=1000000 :结果错误;耗时969毫秒;
k=5000000 :结果错误;耗时2156毫秒;
总共花费时间3328毫秒。
10楼:程序不完整,无法测试。
12楼:(与我提供的函数原型参数顺序不匹配)
k=1 :耗时31毫秒;
k=10 :耗时31毫秒;
k=100 :耗时31毫秒;
k=1000 :耗时31毫秒;
k=10000 :耗时78毫秒;
k=100000 :耗时141毫秒;
k=1000000 :耗时94毫秒;
k=5000000 :耗时218毫秒;
总共花费时间655毫秒。
13-17楼:
k=1 :耗时15毫秒;
k=10 :耗时16毫秒;
k=100 :耗时16毫秒;
k=1000 :耗时0毫秒;
k=10000 :耗时31毫秒;
k=100000 :结果错误;耗时156毫秒;
k=1000000 :结果错误;耗时78毫秒;
k=5000000 :结果错误;耗时188毫秒;
总共花费时间500毫秒。
20楼:
k=1 :耗时16毫秒;
k=10 :耗时31毫秒;
k=100 :耗时16毫秒;
k=1000 :耗时32毫秒;
k=10000 :结果错误;耗时2000毫秒;
k=100000 :结果错误;耗时1984毫秒;
k=1000000 :结果错误;耗时2000毫秒;
k=5000000 :结果错误;耗时2000毫秒;
总共花费时间8079毫秒。
从测试结果来看,13-17楼Chipset的程序是最快的,他采用的是快速划分+partial_sort(实际上就是堆排序)来实现的(可惜部分结果错误,但应该可以调整正确的);12楼的程序完全正确速度也非常快,比std::nth_element快40%左右。对于本题来说,我估计是划分+部分堆排序是最快的。我按照Chipset的思路写了一个,测试通过,总耗时在450ms左右。当然了,这个速度还是可以进一步提升的,呵呵
我宣布本次比赛的冠军为天边蓝(12楼),请他主持下次的编程比赛,大家鼓掌,呵呵。
测试环境: 软件 vs2008+winxp+sp3
硬件 Pentium M 3.4g
(ps: 本次比赛存在的问题是:我规定了函数的原型,可大部分人都没有按照我的要求去做。)
最后更新于:2008-10-08 08:15:00
回复列表 (共32个回复)
沙发
eastcowboy [专家分:25370] 发布于 2008-10-08 08:59:00
鼓掌~
板凳
Chipset [专家分:16190] 发布于 2008-10-08 09:18:00
你的测试方法可能存在问题,我的算法理论上没有问题。如果你认为我的程序运行结果跟nth_element应该相同那是不对的,因为实现原理不同,结果不可能相同,如果相同只能是巧合,主要不同点就是我的算法可以动态的适应枢轴偏向一边的情况,而nth_element此时则速度大大下降。
还有,在我的笔记本电脑上(CPU 2.1GHz,用单线程,只用一个核心),总分割时间小于400ms,在你的PC上,CPU高达3.4GHz的主频,速度居然达到500ms,你是否考虑过是不是你的测试方法或者编译器有问题呢??
3 楼
Chipset [专家分:16190] 发布于 2008-10-08 09:20:00
在这里我们只讨论技术问题,没有别的意思。
4 楼
天边蓝 [专家分:1810] 发布于 2008-10-08 09:33:00
太意外了……
说真的,我自己测试我程序的时候,在k比较大的时候(超过30000)速度比std::nth_element慢了40%多~~当时贴代码的时候还犹豫了下~~
不过,Chipset做了很好的优化,值得学习!
5 楼
boxertony [专家分:23030] 发布于 2008-10-08 09:47:00
[quote]你的测试方法可能存在问题,我的算法理论上没有问题。如果你认为我的程序运行结果跟nth_element应该相同那是不对的,因为实现原理不同,结果不可能相同,如果相同只能是巧合,主要不同点就是我的算法可以动态的适应枢轴偏向一边的情况,而nth_element此时则速度大大下降。
还有,在我的笔记本电脑上(CPU 2.1GHz,用单线程,只用一个核心),总分割时间小于400ms,在你的PC上,CPU高达3.4GHz的主频,速度居然达到500ms,你是否考虑过是不是你的测试方法或者编译器有问题呢??[/quote]
不知你的partial_improved经过运算后是否前面的k个数据就是最大的k个?如果是,那就没有问题,因为我都是经过排序以后再比较的。
至于速度,我估计因为是双核的原因,我的电脑任何一个进程占用cpu的比率都不超过50%,也就是说我同时运行两份这个程序,测得的时间耗费也都还是500ms。
6 楼
boxertony [专家分:23030] 发布于 2008-10-08 09:53:00
[quote]太意外了……
说真的,我自己测试我程序的时候,在k比较大的时候(超过30000)速度比std::nth_element慢了40%多~~当时贴代码的时候还犹豫了下~~
不过,Chipset做了很好的优化,值得学习!
[/quote]
你的程序在不同k值与nth_element互有优劣,但总的耗时少些。下面是我测的nth_element的耗时。
k=1 :耗时125毫秒;
k=10 :耗时63毫秒;
k=100 :耗时93毫秒;
k=1000 :耗时125毫秒;
k=10000 :耗时78毫秒;
k=100000 :耗时31毫秒;
k=1000000 :耗时125毫秒;
k=5000000 :耗时156毫秒;
总共花费时间796毫秒。
当然啦,nth_element我测试了几十次,总的时间耗费在800~1000ms内徘徊,平均在900ms左右。
7 楼
天边蓝 [专家分:1810] 发布于 2008-10-08 10:07:00
[quote]
当然啦,我测试了几十次,总的时间耗费在800~1000ms内徘徊,平均在900ms左右。 [/quote]
哈哈,太给面子了,给我公布了个耗时最少的例子655~~谢哈!
8 楼
boxertony [专家分:23030] 发布于 2008-10-08 10:20:00
[quote][quote]
当然啦,我测试了几十次,总的时间耗费在800~1000ms内徘徊,平均在900ms左右。 [/quote]
哈哈,太给面子了,给我公布了个耗时最少的例子655~~谢哈!
[/quote]
呵呵,你误会了,我指的是nth_element测试了几十次。你的程序平均就是600多毫秒
9 楼
天边蓝 [专家分:1810] 发布于 2008-10-08 11:09:00
哦~~[em54]
10 楼
boxertony [专家分:23030] 发布于 2008-10-08 13:26:00
我找到Chipset的错误原因了。下面的语句
RandomAccessIterator cut = unguarded_partition(first, last,
T(median(*first, *(first + (d2 >> 1)), *(last - 1), cmp)));
应改为:
RandomAccessIterator cut = unguarded_partition(first, last,
T(median(*first, *(first + (d2 >> 1)), *(last - 1), cmp)), cmp);
改了后我重新测试了一下,平均470ms
我来回复