using HEAL.Attic; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace HeuristicLab.Algorithms.OESRALPS.DriftDetection { [StorableType("714CAAE4-A88F-44A1-A2D0-92F4D8252C04")] public abstract class ADWIN { [Storable] public int MinCutSize { get; set; } [Storable] public int MinKeepSize { get; set; } [Storable] public double Delta { get; set; } public ADWIN() { } public ADWIN(double delta, int minKeepSize, int minCutSize) { Delta = delta; MinKeepSize = minKeepSize; MinCutSize = minCutSize; } public bool CheckHistogramForCut(Histogram histogram, IEnumerator buckets, int numCutPointsToCheck) { double keepTotal = histogram.Total; double keepVariance = histogram.Total; int keepSize = histogram.NumElements; double cutTotal = 0; double cutVariance = 0; int cutSize = 0; double bucketTotal, bucketVariance, bucketSize, bucketMean; int cutPointsChecked = 0; while (buckets.MoveNext()) { cutPointsChecked++; bucketTotal = buckets.Current.Total; bucketVariance = buckets.Current.Variance; bucketSize = buckets.Current.NumElements; bucketMean = buckets.Current.Mean; keepTotal -= bucketTotal; keepVariance -= bucketVariance + keepSize * bucketSize * Math.Pow(keepTotal / keepSize - bucketMean, 2) / (keepSize + bucketSize); keepSize -= (int)bucketSize; cutTotal += bucketTotal; if (cutSize > 0) cutVariance += bucketVariance + cutSize * bucketSize * Math.Pow(cutTotal / cutSize - bucketMean, 2) / (cutSize + bucketSize); cutSize += (int)bucketSize; if (keepSize >= MinKeepSize && cutSize >= MinCutSize && IsCutPoint(histogram, keepTotal, keepVariance, keepSize, cutTotal, cutVariance, cutSize)) { return true; } else if (keepSize < MinKeepSize) { return false; } else if (cutPointsChecked == numCutPointsToCheck) { return false; } } return false; } private bool IsCutPoint(Histogram histogram, double keepTotal, double keepVariance, int keepSize, double cutTotal, double cutVariance, int cutSize) { double absMeanDifference = Math.Abs(keepTotal / keepSize - cutTotal / cutSize); double dd = Math.Log(2.0 * Math.Log(histogram.NumElements) / Delta); double m = 1.0 / (keepSize - MinKeepSize + 3) + 1.0 / (cutSize - MinCutSize + 3); double epsilon = Math.Sqrt(2.0 * m * (histogram.Variance / histogram.NumElements) * dd) + 2.0 / 3.0 * dd * m; return absMeanDifference > epsilon; } public abstract bool Execute(ref Histogram histogram); public abstract void Terminate(); } }