旋转门算法是一种比较快速的线性拟合算法,常常用于实时数据库中对数据进行压缩,使存储容量大大的减少。在实时数据库中,数据通常具有如下特点:

  • 数据采集量大。
  • 数据临近度高。如果不能对这些数据进行压缩,将对资源造成巨大的浪费。旋转门算法作为线性拟合的一种简便算法,具有效率高、压缩比高、实现简单、误差可控制的优点,现在已成为一种专门算法。

旋转门 - 数据压缩算法:旋转门算法(SDT)的C#实现

public struct point  
    {  
        public point(double pointx, double pointy)  
        {  
            this.x = pointx;  
            this.y = pointy;  
        }  
        private double x;  
        private double y;  
        public double X  
        {  
            get  
            {  
                return x;  
            }  
  
            set  
            {  
                x = value;  
            }  
        }  
        public double Y  
        {  
            get  
            {  
                return y;  
            }  
  
            set  
            {  
                y = value;  
            }  
        }  
    }
public struct SDTPoints  
{  
    private point currentData;//当前读取数据  
    private point lastReadData;//上一个读取数据  
    private point lastStoredData;//上一个保存数据  
  
    public point CurrentData  
    {  
        get  
        {  
            return currentData;  
        }  
  
        set  
        {  
            currentData = value;  
        }  
    }  
  
    public point LastReadData  
    {  
        get  
        {  
            return lastReadData;  
        }  
  
        set  
        {  
            lastReadData = value;  
        }  
    }  
  
    public point LastStoredData  
    {  
        get  
        {  
            return lastStoredData;  
        }  
  
        set  
        {  
            lastStoredData = value;  
        }  
    }  
}
public List<point> SDTcompress(List<point> originData, double AccuracyE,IProgress<int> progress,CancellationToken cancel)//后两个参数为其异步编程使用  
       {  
           List<point> listSDT=new List<point>();  
           double upGate = -double.MaxValue;  
           double downGate = double.MaxValue;  
           double nowUp, nowDown;//当前数据的上下斜率  
           SDTPoints status=new SDTPoints();  
           if (originData.Count <= 0)  
               return null;  
           status.LastReadData = originData[0];  
           status.LastStoredData = status.LastReadData;  
           listSDT.Add(status.LastReadData);  
           int i = 0;  
           foreach (var p in originData)  
           {  
               status.CurrentData = p;  
               nowUp = (p.Y - status.LastStoredData.Y - AccuracyE)/(p.X - status.LastStoredData.X);  
               if (nowUp > upGate)  
                   upGate = nowUp;  
               nowDown = (p.Y - status.LastStoredData.Y + AccuracyE)/(p.X - status.LastStoredData.X);  
               if (nowDown < downGate)  
                   downGate = nowDown;  
               if (upGate >= downGate)  
               {  
                   listSDT.Add(status.LastReadData);//保存前一个点  
                   status.LastStoredData = status.LastReadData;//修改最近保存的点  
                   upGate=(p.Y-status.LastStoredData.Y-AccuracyE)/ (p.X - status.LastStoredData.X);  
                   downGate = (p.Y - status.LastStoredData.Y + AccuracyE) / (p.X - status.LastStoredData.X);  
               }  
               status.LastReadData = p;  
               i++;  
               cancel.ThrowIfCancellationRequested();  
               progress?.Report(i * 100 / originData.Count );  
           }  
           if (listSDT.Count == 1)  
           {  
               listSDT.Add(originData[originData.Count-1]);  
           }  
           return listSDT;  
       }

 

发表评论

邮箱地址不会被公开。 必填项已用*标注