欢迎访问 外汇EA下载与MT4/MT5自动交易资源 - 聚合外汇EA、黄金EA、量化交易工具与自动化交易实战内容。
登录 注册

Radix 排序(最快的数字排序)- MetaTrader 5 库

author emer | 845 人阅读 | 0 人评论 |

基数排序通过考虑一串数字对数字数据(整数或浮点数)进行排序,其中从最低有效数字位置到最高有效数字位置逐位排序。

该算法在维基百科页面上有更好的解释https://en.wikipedia.org/wiki/Radix_sort

该算法按 LSD(最低有效数字)顺序迭代 k 个字节位置;对于每个字节位置,它迭代所有 n 个元素以按第 k 个字节对它们进行排序。

这是 LSD RadixSort 在 MQL 中的高度优化实现 使用基数 256(8 位)。这对于对具有数百万个数字的大型数组进行排序非常有用。

该实现基于 Pierre Terdiman 的基数排序,发表于 http://codercorner.com/RadixSortRevisited.htm,其中部分优化由 Michael Herf 发布于 http://stereopsis.com/radix.html 作者:Eddy L O Jansson,作者: https://github.com/eloj/radix-sorting

该函数至少为 快3-10倍 比 MQL 的 内置 数组排序() 功能。 

该函数接受简单类型(char、uchar、short、ushort、int、uint、long、ulong、bool、color、datetime、float、double)的任意维数组作为参数。但是,排序始终应用于第一个(零)维度。 

无论 AS_SERIES 标志值如何,数组始终按升序排序。

请注意,如果数组包含的项目数少于某个阈值(当前为 128),则算法将回退到 ArraySort()。

基数排序应该是对数字数据进行排序的默认值,因为它 经营于 O(n*k) 时间。 C基于比较的排序算法(如快速排序、归并排序和堆排序)运行在 O(n * log n) 时间。因此,数组大小越大,基数排序相对越快。基数排序的缺点是它需要更多内存(临时数组)来完成其工作。

//+------------------------------------------------------------------+
//| RadixSort                                                       |
//+------------------------------------------------------------------+
//|对多维的第一维中的值进行排序    |
//|按升序排列的数值数组。                            |
//|                                                                  |
//|参数:                                                       |
//|数组[]                                                         |
//|   [in][out] :用于排序的数字数组。                         |
//|                                                                  |
//|返回值:成功则返回 true,否则返回 false。               |
//|                                                                  |
//|注:                                                           |
//|   数组始终按升序排序,无论 |
//|   AS_SERIES 标志值的。                                   |
//|                                                                  |
//|   该函数接受简单类型的任意维数组     |
//|   (char、uchar、short、ushort、int、uint、long、ulong、bool、     |
//|   颜色、日期时间、浮点数、双精度)作为参数。  然而,      |
//|   排序始终应用于第一个(零)维度。       |
//|                                                                  |
//|性能:                                                    |
//|   这是 LSD RadixSort 的高度优化实现 |    |
//|   在 MQL 中使用基数 256(8 位)。这可能对      | 有用
//|   对包含数百万个数字的巨大数值数组进行排序。          |
//|   它比内置的 ArraySort() 至少快 3-10 倍。    |
//+------------------------------------------------------------------+
模板<类型名>布尔值基数排序(T &arr[]);//+------------------------------------------------------------------+
//| RadixSort                                                       |
//+------------------------------------------------------------------+
//|对多维的第一维中的值进行排序    |
//|按升序排列的数值数组。                            |
//|                                                                  |
//|高维数值数组的函数重载。         |
//|                                                                  |
//|参数:                                                       |
//|数组[]                                                         |
//|   [in][out] :用于排序的数字数组。                         |
//|                                                                  |
//|返回值:成功则返回 true,否则返回 false。               |
//+------------------------------------------------------------------+
// 对二维数值数组进行排序。
模板<类型名>布尔值RadixSort(T &arr[][]);// 对三维数值数组进行排序。
模板<类型名>布尔值RadixSort(T &arr[][][]);// 对四维数值数组进行排序。
模板<类型名>布尔值RadixSort(T &arr[][][][]);//+------------------------------------------------------------------+
//| RadixSortIndices                                                 |
//+------------------------------------------------------------------+
//|按照排序顺序填充索引[] 数组      |
//|数值数组[]的值按升序排列。          |
//|                                                                  |
//|参数:                                                       |
//| array[]     :要排序的数值数组                  |
//| Index[]   :排序索引的数组                           |
//|                                                                  |
//|返回值:成功则返回 true,否则返回 false。               |
//+------------------------------------------------------------------+
模板<类型名>布尔值基数排序索引(常量T&arr[],整数&索引[]);//+------------------------------------------------------------------+
//| ParallelRadixSort                                               |
//+------------------------------------------------------------------+
//|该函数使用      | 同时对 array[] 和 items[] 进行排序
//|基数排序算法。排序后,items[] 数组已排序 |
//|按 array[] 的数值按升序排列。         |
//|                                                                  |
//|参数:                                                       |
//| array[]     : 使用数字键进行排序的数组                    |
//| items[]     :根据键排序的项目数组              |
//|                                                                  |
//|返回值:成功则返回 true,否则返回 false。               |
//+------------------------------------------------------------------+
模板<类型名吨,类型名项目>布尔值ParallelRadixSort(T &arr[], TItem &items[]);


这是一个基准脚本,展示了 RadixSort() 相对于 MQL 的 ArraySort() 的速度优势:

//+------------------------------------------------------------------+
//|                                          RadixSort_benchmark.mq5 |
//|                                        版权所有 © 2018,阿姆·阿里 |
//|                             https://www.mql5.com/en/users/amrali |
//+------------------------------------------------------------------+
#包括“基数排序.mqh”

#定义尺寸10*1000*1000  // 1000 万
整数     arr1[大小];整数     arr2[大小];//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
空白 启动时()
  {//--- 准备未排序的数组。  为了整数我=0;我<尺寸;我++)
     {
      arr1[i] =数学兰德();
      arr2[i] = arr1[i];
     }//--- ArraySort() 基准测试。  单位t1=获取刻度数();
  数组排序(arr1);
  单位刻度1 =获取刻度数() - t1;//--- RadixSort() 基准测试。  单位t2=获取刻度数();
   基数排序(arr2);
  单位刻度2 =获取刻度数()-t2;//--- 显示结果。  打印格式“对 %d 个整数进行排序:”, 尺寸);
  打印格式“ArraySort() -> %u 毫秒”, 刻度1);
  打印格式“RadixSort() -> %u 毫秒”, 刻度2);
  打印格式“加速系数为 %.1fx”, (双倍的) 刻度 1/刻度 2);
  打印格式“%s”,数组比较(arr1, arr2) ? “RadixSort:排序顺序无效。”””);
  }//+------------------------------------------------------------------+

// 示例输出:
/*
 对 10000000 个整数进行排序:
 ArraySort() -> 953 毫秒
 RadixSort() -> 62 毫秒加速系数为 15.4 倍*/


要在旧的 mq5 或 mqh 文件中将 MQL 的 ArraySort() 替换为 RadixSort(),只需在文件顶部添加这两行:

#包括“基数排序.mqh”
#定义数组排序(a) 基数排序(a)



附件下载

📎 radixsort.mqh (37.14 KB)

📎 radixsort_benchmark.mq5 (3.23 KB)

📎 radixsort_validate_types.mq5 (8.19 KB)

Source: MQL5 #38763

🔐
请登录后参与评论
注册满12小时后评论,即可解锁附件下载
立即登录