- Timestamp:
- 09/12/18 15:12:29 (6 years ago)
- Location:
- branches/2457_ExpertSystem
- Files:
-
- 1 deleted
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2457_ExpertSystem
- Property svn:ignore
-
old new 5 5 .gitignore 6 6 .vs 7 packages
-
- Property svn:ignore
-
branches/2457_ExpertSystem/HeuristicLab.Analysis.FitnessLandscape/3.3/Analysis/InformationAnalysis.cs
r14678 r16137 38 38 39 39 public List<double> InformationContent { get; private set; } 40 public List<double> SymmetricInformationContent { get; private set; } 40 41 public List<double> PartialInformationContent { get; private set; } 41 42 public List<double> DensityBasinInformation { get; private set; } 43 public List<double> SymmetricDensityBasinInformation { get; private set; } 42 44 public List<double> TotalEntropy { get; private set; } 45 public List<double> SymmetricTotalEntropy { get; private set; } 43 46 public List<double> QualityDelta { get; private set; } 44 47 public double InformationStability { get; private set; } … … 46 49 public int Diversity { get; private set; } 47 50 public Peak PeakInformationContent { get; private set; } 48 public Peak Peak PartialInformationContent { get; private set; }51 public Peak PeakSymmetricInformationContent { get; private set; } 49 52 public Peak PeakDensityBasinInformation { get; private set; } 53 public Peak PeakSymmetricDensityBasinInformation { get; private set; } 50 54 public Peak PeakTotalEntropy { get; private set; } 51 52 public InformationAnalysis(IList<double> qualities, int nQuantiles, int shapeSize) { 53 InformationContent = new List<double>(); 54 PartialInformationContent = new List<double>(); 55 DensityBasinInformation = new List<double>(); 56 TotalEntropy = new List<double>(); 57 QualityDelta = new List<double>(); 58 if (shapeSize < 1) 59 throw new ArgumentException("Shape size must be at least 1 (better 2)"); 55 public Peak PeakSymmetricTotalEntropy { get; private set; } 56 57 public InformationAnalysis(IList<double> qualities, int nQuantiles = 20) { 58 InformationContent = new List<double>(nQuantiles); 59 SymmetricInformationContent = new List<double>(nQuantiles); 60 PartialInformationContent = new List<double>(nQuantiles); 61 DensityBasinInformation = new List<double>(nQuantiles); 62 SymmetricDensityBasinInformation = new List<double>(nQuantiles); 63 TotalEntropy = new List<double>(nQuantiles); 64 SymmetricTotalEntropy = new List<double>(nQuantiles); 65 QualityDelta = new List<double>(nQuantiles); 60 66 if (qualities.Count > 1) 61 PerformAnalysis(qualities, nQuantiles , shapeSize);62 } 63 64 private void PerformAnalysis(IList<double> qualities, int nQuantiles , int shapeSize) {67 PerformAnalysis(qualities, nQuantiles); 68 } 69 70 private void PerformAnalysis(IList<double> qualities, int nQuantiles) { 65 71 var differences = Differences(qualities).ToList(); 66 72 InformationStability = differences.Select(Math.Abs).Max(); … … 80 86 PartialInformationContent.DuplicateLast(); 81 87 } else { 82 var slopes = Slopes(eps, differences).ToList(); 83 var shapes = Shapes(shapeSize, slopes).ToList(); 84 var shapeCounts = CountShapes(shapes); 88 var slopes = ToSlopes(eps, differences).ToList(); 89 var shapes = ToShapes(slopes).ToList(); 90 var symmetricShapes = shapes.Select(x => Shape.GetSymmetric(x)).ToList(); 91 92 var shapeFreqs = GetFrequencies(shapes); 93 var symShapeFreqs = GetFrequencies(symmetricShapes); 94 95 foreach (var symShape in Shape.Symmetric.Where(x => x.Sum > 0)) { 96 if (symShapeFreqs.TryGetValue(symShape, out var freq)) { 97 symShapeFreqs[symShape] = freq / 2; 98 } 99 } 85 100 QualityDelta.Add(eps); 86 InformationContent.Add(CalculateEntropy(Shape.GetAll(shapeSize, Shape.Form.NonUni), shapeCounts, shapes.Count)); 87 DensityBasinInformation.Add(CalculateEntropy(Shape.GetAll(shapeSize, Shape.Form.Uni), shapeCounts, shapes.Count)); 88 TotalEntropy.Add(CalculateEntropy(Shape.GetAll(shapeSize, Shape.Form.Any), shapeCounts, shapes.Count)); 101 102 InformationContent.Add(CalculateEntropy(shapeFreqs, Shape.NonUniform.ToList(), shapes.Count)); 103 SymmetricInformationContent.Add(CalculateEntropy(symShapeFreqs, Shape.SymmetricNonUniform.ToList(), symmetricShapes.Count)); 104 105 DensityBasinInformation.Add(CalculateEntropy(shapeFreqs, Shape.Uniform.ToList(), shapes.Count)); 106 SymmetricDensityBasinInformation.Add(CalculateEntropy(symShapeFreqs, Shape.SymmetricUniform.ToList(), symmetricShapes.Count)); 107 108 TotalEntropy.Add(CalculateEntropy(shapeFreqs, Shape.All.ToList(), shapes.Count)); 109 SymmetricTotalEntropy.Add(CalculateEntropy(symShapeFreqs, Shape.Symmetric.ToList(), symmetricShapes.Count)); 110 89 111 PartialInformationContent.Add(CalculatePartialInformationContent(eps, differences)); 90 112 } 91 113 } 92 114 PeakInformationContent = GetPeak(QualityDelta, InformationContent); 115 PeakSymmetricInformationContent = GetPeak(QualityDelta, SymmetricInformationContent); 93 116 PeakDensityBasinInformation = GetPeak(QualityDelta, DensityBasinInformation); 94 Peak PartialInformationContent = GetPeak(QualityDelta, PartialInformationContent);117 PeakSymmetricDensityBasinInformation = GetPeak(QualityDelta, SymmetricDensityBasinInformation); 95 118 PeakTotalEntropy = GetPeak(QualityDelta, TotalEntropy); 119 PeakSymmetricTotalEntropy = GetPeak(QualityDelta, SymmetricTotalEntropy); 96 120 } 97 121 … … 107 131 } 108 132 109 public class Shape : IEnumerable<Slope>, IComparable<Shape> { 110 111 #region types, fields and properties 112 public enum Form { Uni, NonUni, Any } 113 114 private readonly Slope[] slopes; 115 116 private static readonly Dictionary<Tuple<Form, int>, IList<Shape>> SHAPES = 117 new Dictionary<Tuple<Form, int>, IList<Shape>>(); 118 #endregion 119 120 public Shape(IEnumerable<Slope> slopes) { 121 this.slopes = slopes.ToArray(); 122 } 123 124 #region static methods 125 126 public static Shape Get(params Slope[] slopes) { 127 return new Shape(slopes); 128 } 129 130 public static IList<Shape> GetAll(int size, Form type) { 131 var key = Tuple.Create(type, size); 132 IList<Shape> allShapes; 133 if (!SHAPES.TryGetValue(key, out allShapes)) { 134 allShapes = CreateAll(size, type).ToList(); 135 SHAPES[key] = allShapes; 133 public class Shape { 134 private static readonly Shape[] s = new Shape[] { 135 new Shape() { First = Slope.Down, Second = Slope.Down }, // 0 136 new Shape() { First = Slope.Down, Second = Slope.Flat }, // 1 137 new Shape() { First = Slope.Down, Second = Slope.Up }, // 2 138 new Shape() { First = Slope.Flat, Second = Slope.Down }, // 3 139 new Shape() { First = Slope.Flat, Second = Slope.Flat }, // 4 140 new Shape() { First = Slope.Flat, Second = Slope.Up }, // 5 141 new Shape() { First = Slope.Up, Second = Slope.Down }, // 6 142 new Shape() { First = Slope.Up, Second = Slope.Flat }, // 7 143 new Shape() { First = Slope.Up, Second = Slope.Up }, // 8 144 }; 145 public static IEnumerable<Shape> All { get { return s; } } 146 public static IEnumerable<Shape> Uniform { get { return All.Where(x => x.First == x.Second); } } 147 public static IEnumerable<Shape> NonUniform { get { return All.Where(x => x.First != x.Second); } } 148 public static IEnumerable<Shape> Symmetric { get { return All.Where(x => x.Sum >= 0); } } 149 public static IEnumerable<Shape> SymmetricUniform { get { return Uniform.Where(x => x.First != Slope.Down); } } 150 public static IEnumerable<Shape> SymmetricNonUniform { get { return NonUniform.Where(x => x.Sum >= 0); } } 151 152 public Slope First { get; private set; } 153 public Slope Second { get; private set; } 154 155 internal int Sum { get { return (int)First + (int)Second; } } 156 157 public IEnumerable<Slope> Slopes { 158 get { 159 yield return First; 160 yield return Second; 136 161 } 137 return allShapes; 138 } 139 140 private static IEnumerable<Shape> CreateAll(int size, Form type) { 141 if (size == 0) { 142 yield return Get(); 143 } else { 144 foreach (var s in CreateAll(size - 1, type)) { 145 foreach (var s2 in s.ExtendAll(type)) 146 yield return s2; 147 } 148 } 149 } 150 #endregion 151 152 private Shape Extend(Slope s) { 153 return new Shape(slopes.Concat(new[] { s })); 154 } 155 156 private IEnumerable<Shape> ExtendAll(Form t) { 157 if (Length == 0 || t == Form.Any) { 158 yield return Extend(Slope.Up); 159 yield return Extend(Slope.Flat); 160 yield return Extend(Slope.Down); 161 } else if (t == Form.Uni) { 162 yield return Extend(slopes[0]); 163 } else if (t == Form.NonUni) { 164 if (slopes.Last() != Slope.Up) yield return Extend(Slope.Up); 165 if (slopes.Last() != Slope.Flat) yield return Extend(Slope.Flat); 166 if (slopes.Last() != Slope.Down) yield return Extend(Slope.Down); 167 } 168 } 169 170 public int Length { 171 get { return slopes.Length; } 172 } 173 174 public Slope this[int i] { 175 get { return slopes[i]; } 176 } 177 178 #region IEnumerable Members 179 public IEnumerator<Slope> GetEnumerator() { 180 return (IEnumerator<Slope>)slopes.GetEnumerator(); 181 } 182 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { 183 return GetEnumerator(); 184 } 185 #endregion 186 187 #region IComparable Members 188 189 public int CompareTo(Shape other) { 190 if (other.Length < Length) 191 return -1; 192 if (other.Length > Length) 193 return 1; 194 for (var i = 0; i < Length; i++) { 195 var d = slopes[i].CompareTo(other.slopes[i]); 196 if (d != 0) 197 return d; 198 } 199 return 0; 200 } 201 public override bool Equals(object obj) { 202 var s = obj as Shape; 203 if (s == null) return false; 204 return CompareTo(s) == 0; 205 } 206 public override int GetHashCode() { 207 return slopes.Aggregate(0, (a, s) => a * 3 + ((int)s + 1)).GetHashCode(); 208 } 209 210 #endregion 211 212 private string asString; 162 } 163 164 private Shape() { 165 166 } 167 168 public static Shape Get(Slope first, Slope second) { 169 var a = 1 + (int)first; var b = 1 + (int)second; 170 return s[a * 3 + b]; 171 } 172 173 public static Shape GetSymmetric(Shape shape) { 174 if (shape.Sum >= 0) return shape; 175 if (shape.Sum == -2) return s[8]; // both are Slope.Down 176 if (shape.First == Slope.Down) return s[5]; 177 return s[7]; // shape.Second == Slope.Down 178 } 179 213 180 public override string ToString() { 214 return asString ?? (asString = string.Join("", slopes.Select(s => (s == Slope.Down ? "\\" : (s == Slope.Up ? "/" : "-"))))); 215 } 216 } 217 218 private static IEnumerable<Slope> Slopes(double eps, IEnumerable<double> differences) { 181 return string.Join("", Slopes.Select(s => (s == Slope.Down ? "\\" : (s == Slope.Up ? "/" : "-")))); 182 } 183 } 184 185 186 187 private static IEnumerable<Slope> ToSlopes(double eps, IEnumerable<double> differences) { 219 188 return differences.Select(d => (d > eps ? Slope.Up : (d < -eps ? Slope.Down : Slope.Flat))); 220 189 } 221 190 222 private static IEnumerable<Shape> Shapes(int size, IEnumerable<Slope> slopes) { 223 var q = new Queue<Slope>(); 224 foreach (var s in slopes) { 225 q.Enqueue(s); 226 if (q.Count < size) continue; 227 yield return new Shape(q); 228 q.Dequeue(); 229 } 230 } 231 232 private static double CalculateEntropy(IList<Shape> shapes, Dictionary<Shape, int> shapeCounts, int totalNShapes) { 233 return shapes.Aggregate(0.0, (current, s) => current - Entropy(shapeCounts.GetValueOrDefault(s, 0), totalNShapes, shapes.Count)); 191 private static IEnumerable<Shape> ToShapes(IEnumerable<Slope> slopes) { 192 var iter = slopes.GetEnumerator(); 193 if (!iter.MoveNext()) yield break; 194 var prev = iter.Current; 195 while (iter.MoveNext()) { 196 var cur = iter.Current; 197 yield return Shape.Get(prev, cur); 198 prev = cur; 199 } 200 } 201 202 private static double CalculateEntropy(Dictionary<Shape, int> shapeCounts, ICollection<Shape> shapeTypes, int totalShapes) { 203 return shapeTypes.Where(x => shapeCounts.ContainsKey(x)) 204 .Aggregate(0.0, (current, s) => current - Entropy(shapeCounts[s], totalShapes, shapeTypes.Count)); 234 205 } 235 206 236 207 private static double CalculatePartialInformationContent(double eps, ICollection<double> differences) { 237 int slope = 0; 238 int nPeaks = 0; 239 foreach (var d in differences) { 208 var iter = differences.GetEnumerator(); 209 if (!iter.MoveNext()) return 0; 210 211 var slope = iter.Current < -eps ? -1 : (iter.Current > eps ? 1 : 0); 212 var nPeaks = Math.Abs(slope); 213 var count = 1; 214 while (iter.MoveNext()) { 215 var d = iter.Current; 240 216 if (d > eps) { 241 217 if (slope < 0) nPeaks++; … … 245 221 slope = -1; 246 222 } 247 } 248 return 1.0 * nPeaks / differences.Count; 249 } 250 251 private static Dictionary<Shape, int> CountShapes(IEnumerable<Shape> shapes) { 252 var shapeCounts = new Dictionary<Shape, int>(); 253 foreach (var group in shapes.GroupBy(s => s)) 254 shapeCounts[group.Key] = group.Count(); 255 return shapeCounts; 223 count++; 224 } 225 return nPeaks / (double)count; 226 } 227 228 private static Dictionary<Shape, int> GetFrequencies(IEnumerable<Shape> shapes) { 229 return shapes.GroupBy(x => x).ToDictionary(x => x.Key, x => x.Count()); 256 230 } 257 231 258 232 private static double Entropy(int count, int total, int nCases) { 259 if (count == 0) 260 return 0; 261 double freq = 1.0 * count / total; 233 if (count == 0) return 0; 234 var freq = 1.0 * count / total; 262 235 return freq * Math.Log(freq, nCases); 263 236 } -
branches/2457_ExpertSystem/HeuristicLab.Analysis.FitnessLandscape/3.3/Analysis/InformationAnalyzer.cs
r16096 r16137 91 91 92 92 Parameters.Add(new ValueLookupParameter<IntValue>("NQuantiles", "The number of delta quantiles to display", new IntValue(20))); 93 Parameters.Add(new ValueLookupParameter<IntValue>("ShapeSize", "The number of slopes to consider as shapes.", new IntValue(2)));94 93 95 94 Parameters.Add(new LookupParameter<DoubleValue>("InformationContent", "The information content H(0) at eps = 0")); … … 118 117 119 118 var nQuantiles = NQuantilesParameter.ActualValue.Value; 120 var shapeSize = ShapeSizeParameter.ActualValue.Value;121 119 var results = ResultsParameter.ActualValue; 122 120 123 var analysis = new InformationAnalysis(qualities, nQuantiles , shapeSize);121 var analysis = new InformationAnalysis(qualities, nQuantiles); 124 122 var ic = new DoubleValue(analysis.InformationContent.FirstOrDefault()); 125 123 InformationContentParameter.ActualValue = ic;
Note: See TracChangeset
for help on using the changeset viewer.