public double Apply(NumericVariable numericVariable, MembershipFunction msf) { if (msf.Count == 0) return (numericVariable.MaxValue - numericVariable.MinValue) / 2.0; if (msf[0].Y > 0 && msf[0].X > numericVariable.MinValue) { msf.Add(numericVariable.MinValue, msf[0].Y); } if (msf[msf.Count - 1].Y > 0 && msf[msf.Count - 1].X < numericVariable.MaxValue) { msf.Add(numericVariable.MaxValue, msf[msf.Count - 1].Y); } var numerator = 0d; var denominator = 0d; for (var i = 0; i < msf.Count - 1; i++) { var value1 = msf[i]; var value2 = msf[i + 1]; var min = Math.Min(value1.Y, value2.Y); var max = Math.Max(value1.Y, value2.Y); var line = new LineSegment(value1, value2); var m = line.Gradient.Value; var b = line.B.Value; numerator += ((m / 3.0) * (Math.Pow(value2.X, 3) - Math.Pow(value1.X, 3))) + ((b / 2.0) * (Math.Pow(value2.X, 2) - Math.Pow(value1.X, 2))); denominator += ((max + min) / 2.0) * (value2.X - value1.X); } return numerator / denominator; }
/// <summary> /// Mamdani-implication /// </summary> /// <param name="msf"></param> /// <param name="minValue"></param> /// <returns></returns> public MembershipFunction Apply(MembershipFunction msf, double minValue) { var result = new MembershipFunction(); var count = msf.Count; if(count == 0) return msf; if (count == 1) { foreach (var point in msf) result.Add(point.Key, Math.Min(point.Value, minValue)); } else { for (var i = 0; i < count - 1; i++) { var key = msf.Keys[i]; var nextKey = msf.Keys[i + 1]; var value = msf.Values[i]; var nextValue = msf.Values[i + 1]; if (value <= minValue) { result.Add(key, value); if (nextValue > minValue) { var m = (nextValue - value)/(nextKey - key); var newKey = key + minValue/m; if(!result.Keys.Contains(newKey)) result.Add(newKey, minValue); } } else if (nextValue < minValue) { var m = (nextValue - value)/(nextKey - key); var newKey = key + (minValue - value)/m; result.Add(newKey, minValue); } } if (msf.Values[count - 1] <= minValue) { result.Add(msf.Keys[count - 1], msf.Values[count - 1]); } } return result.ClearUp(); }
private MembershipFunction combine(MembershipFunction first, MembershipFunction second) { if (!first.Any()) return second; if (!second.Any()) return first; var scanPoints = new List<double>(); scanPoints.AddRange(first.Keys); foreach (var key in second.Keys.Where(key => !scanPoints.Contains(key))) scanPoints.Add(key); scanPoints.Sort(); var result = new MembershipFunction(); foreach (var scanPoint in scanPoints) { var valueFirst = first.Apply(scanPoint); var valueSecond = second.Apply(scanPoint); result.Add(scanPoint, valueFirst + valueSecond); } return result.ClearUp(); }
public MembershipFunction Apply(MembershipFunction msf, double value) { var result = new MembershipFunction(); foreach (var point in msf) { result.Add(point.Key, value*point.Value); } return result; }
private static MembershipFunction combine(MembershipFunction first, MembershipFunction second) { if (!first.Any()) return second; if (!second.Any()) return first; var scanPoints = getScanPoints(first, second); var result = new MembershipFunction(); for (var i = 0; i < scanPoints.Count; i++) { var scanPoint = scanPoints[i]; var valueFirst = first.Apply(scanPoint); var valueSecond = second.Apply(scanPoint); result.Add(scanPoint, Math.Max(valueFirst, valueSecond)); // Check if there is an intersection between this scan point and the next // and add it to the list of scan points: var nextKeyFirst = getNextKey(first, scanPoint); var nextKeySecond = getNextKey(second, scanPoint); if (nextKeyFirst.HasValue && nextKeySecond.HasValue) { var nextValueFirst = first[nextKeyFirst.Value]; var nextValueSecond = second[nextKeySecond.Value]; if (valueFirst >= valueSecond && nextValueFirst < nextValueSecond || valueFirst < valueSecond && nextValueFirst >= nextValueSecond) { var lineFirst = new LineSegment(new Point(scanPoint, valueFirst), new Point(nextKeyFirst.Value, nextValueFirst)); var lineSecond = new LineSegment(new Point(scanPoint, valueSecond), new Point(nextKeySecond.Value, nextValueSecond)); var intersection = lineFirst.Intersect(lineSecond); if (intersection != null && !scanPoints.Contains(intersection.X) && intersection.X > scanPoint) scanPoints.Insert(i + 1, intersection.X); } } } return result.ClearUp(); }