Feedback

C# - SwingingDoorAlgorithmus (vereinfacht)

Veröffentlicht von am 03.07.2016
(0 Bewertungen)
Problem: Beim WPF-Chart-Control dauert die Aktualisierung bei > 1000 Datenpunkten sehr lange.
Lösung: Reduzierung redundanter Datenpunkte im Pre-Processing durch Anwendung des SwingingDoorAlgorithmus.

Dieser Algorithmus ist verlustbehaftet und eignet sich daher nur bedingt zur Datenreduzierung in einer Datenbank (PI-Server). Bei der optischen Darstellung der Daten in einem Chart fallen die fehlenden Datenpunkte nicht auf, da alle notwendigen Stützpunkte, je nach Toleranz-Einstellung, erhalten bleiben.

Beispielaufruf:


SDA.SwingingDoorAlgorithmus.ExMax = new TimeSpan(24, 0, 0);
SDA.SwingingDoorAlgorithmus.ExDev = .2f;

SDA.SwingingDoorAlgorithmus.CompMax = new TimeSpan(24, 0, 0);
SDA.SwingingDoorAlgorithmus.sMax = 0.2f;
SDA.SwingingDoorAlgorithmus.sMin = 0.2f;

SDA.SwingingDoorAlgorithmus.data_reduction(ref valTemperatur);
SDA.SwingingDoorAlgorithmus.data_reduction(ref valLuft);
SDA.SwingingDoorAlgorithmus.data_reduction(ref valWind);
SDA.SwingingDoorAlgorithmus.data_reduction(ref valRegen);
GFU-Schulungen  [Anzeige]

JavaScript für .NET-Entwickler

Sie sind .NET-Entwickler und nun stehen Sie vor der Aufgabe, JavaScript in Ihre Arbeit einzubinden. Die Schulung vermittelt Ihnen die JavaScript Grundlagen und die Funktionen der Scriptsprache. Sie wissen, wie objektorientierte Programmierung in JavaScript funktioniert und lernen abschließend Best Practicies Fälle kennen.

VB.NET 2017/2015/2013 Einführung

Das Seminar befähigt Sie zur eigenständigen Entwicklung von anwenderorientierten Programmen in VB.NET, worin auch der Einsatz von Datenbanken enthalten ist.

namespace SDA
{
    /// <summary>
    /// Reducing redundant data points
    /// </summary>
    public class SwingingDoorAlgorithmus
    {
        /// <summary>
        /// Exception Max - max time of empty values between 2 reprorted values
        /// </summary>
        public static TimeSpan ExMax = new TimeSpan(24,0,0);
        /// <summary>
        /// Slope Max - max time of empty values between 2 reprorted values
        /// </summary>
        public static TimeSpan CompMax = new TimeSpan(24, 0, 0);
        /// <summary>
        /// Exception Dev - max deviation from the snapshot-value
        /// </summary>
        public static float ExDev = 1.0f;
        /// <summary>
        /// Slope - min deviation from the snapshot-value
        /// </summary>
        public static float sMin = 1.0f;
        /// <summary>
        /// Slope - max deviation from the snapshot-value
        /// </summary>
        public static float sMax = 1.0f;
        /// <summary>
        /// Compression activated (true/false)
        /// </summary>
        public static bool compression = true;

        /// <summary>
        /// Main-Methode call
        /// </summary>
        /// <param name="RawValues">ref List[KeyValuePair[DateTime, float]]</param>
        public static void data_reduction(ref List<KeyValuePair<DateTime, float>> RawValues)
        {
            if (RawValues.Count < 3) { return; }

            Exception(ref RawValues);

            if (compression)
            {
                Compression(ref RawValues);
            }
        }
        /// <summary>
        /// Reducing redundant, horizontal data points
        /// </summary>
        /// <param name="RawValues">Liste[KeyValuePair[DateTime, float]]</param>
        private static void Exception(ref List<KeyValuePair<DateTime, float>> RawValues)
        {
            //Last Saved Record
            KeyValuePair<DateTime, float> SnapShot = RawValues[0];
            //The previous record
            KeyValuePair<DateTime, float> PrevValue = RawValues[0];

            //All records except the first and until the penultimate process..
            for (int i = 1; i < RawValues.Count-2; i++)
            {
                if (RawValues[i].Key - SnapShot.Key > ExMax)
                {
                    //Time threshold has been exceeded - save DS

                    //Predecessor is now
                    PrevValue = RawValues[i];
                    //The current DS is the new Snapshot
                    SnapShot = RawValues[i];
                }
                else if (Math.Abs(RawValues[i].Value - SnapShot.Value) > ExDev)//The current record triggers Exception!
                {
                    //The current DS is the new Snapshot
                    SnapShot = RawValues[i];

                    //if the last spoked DS is not the predecessor
                    if (RawValues[i - 1].Key != PrevValue.Key)
                    {
                        //Add predecessors again
                        RawValues.Insert(i - 1, PrevValue);
                        //Index 1 position forward
                        i++;
                    }

                    //Predecessor is now current DS
                    PrevValue = RawValues[i];
                }
                else //Can be omitted..
                {
                    //Predecessor is now the current DS
                    PrevValue = RawValues[i];
                    //remove DS - Index 1 position back
                    RawValues.RemoveAt(i--);
                }
            }
        }
        /// <summary>
        /// Reducing the data points with the same tendency
        /// </summary>
        /// <param name="RawValues">Liste[KeyValuePair[DateTime, float]]</param>
        private static void Compression(ref List<KeyValuePair<DateTime, float>> RawValues)
        {

            //Last Saved Record
            KeyValuePair<DateTime, float> SnapShot = RawValues[1];
            //The previous record
            KeyValuePair<DateTime, float> PrevValue = RawValues[0];

            double ParentSlope = 0.0f;

            //All records except the first and last process..
            for (int i = 1; i < RawValues.Count-1; i++)
            {

                double slope = Slope((float)SnapShot.Key.ToOADate(), SnapShot.Value, (float)RawValues[i].Key.ToOADate(), RawValues[i].Value);

                if (double.IsNaN(slope) || double.IsInfinity(slope))
                {
                    //Ignore, move next
                }
                else if (RawValues[i].Key - SnapShot.Key > CompMax)
                {
                    //Time threshold has been exceeded - save DS

                    //Predecessor is now.. 
                    PrevValue = RawValues[i];
                    //The current DS is the new Snapshot
                    SnapShot = RawValues[i];

                    ParentSlope = slope;
                }
                else if (slope > (ParentSlope + sMax) || slope < (ParentSlope - sMin))//The current record triggers Exception!
                {
                    //The current DS is the new Snapshot
                    SnapShot = RawValues[i];

                    //If the last spoked DS is not the predecessor
                    if (RawValues[i].Key != PrevValue.Key)
                    {
                        //Add predecessors again
                        RawValues.Insert(i, PrevValue);
                        //Index 1 position forward
                        i++;
                    }

                    //Predecessor is now.. 
                    PrevValue = RawValues[i];

                    ParentSlope = slope;
                }
                else //Can be omitted..
                {
                    Debug.Print("Compressed: PS" + ParentSlope + " AS" + slope);
                    //Predecessor is now..
                    PrevValue = RawValues[i];
                    ParentSlope = slope;
                    //remove DS - Index 1 position back
                    RawValues.RemoveAt(i--);
                }
            }
        }
        /// <summary>
        /// computing trend
        /// </summary>
        /// <param name="x1">previous Timestamp</param>
        /// <param name="y1">previous Value</param>
        /// <param name="x2">Timestamp</param>
        /// <param name="y2">Value</param>
        /// <returns></returns>
        private static double Slope(double x1, double y1, double x2, double y2)
        {
            return (y2- y1) / (x2 - x1);
        }
    }
}

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!