public Expression(Operation operation, IExpressionMember member) { _operation = operation; _members = new List <IExpressionMember>() { member }; }
/// <summary> /// Добавляет выражение в список выражений. /// </summary> /// <param name="member"></param> public void AddMember(IExpressionMember member) { if (_operation == Operation.Neg) { throw new Exception("Unable to add an member."); } _members.Add(member); }
public static dynamic Parse(string expression) //interface { expression = ReplaceStringsWithIndexes(expression); //because there can be strings like "12 + 8" expression = CleanExpression(expression); //clean must be after replacing strings expression = ReplaceBracketsWithIndexes(expression); IExpressionMember ExpressionTreeRoot = BuildExpressionTree(expression); return(SolveExpressionTree(ExpressionTreeRoot)); }
static dynamic SolveExpressionTree(IExpressionMember root)//recursive { if (root.GetType() == typeof(Function)) { if ((root as Function).parameters == null)//function without parameters { return((root as Function).Evaluate(null)); } List <dynamic> evaluated_params = new List <dynamic>(); foreach (var param in (root as Function).parameters) { evaluated_params.Add(SolveExpressionTree(param)); } return((root as Function).Evaluate(evaluated_params.ToArray())); } else if (root.GetType() == typeof(Array)) { List <int> evaluated_params = new List <int>(); foreach (var param in (root as Array).parameters) { evaluated_params.Add((int)SolveExpressionTree(param)); } return((root as Array).Evaluate(evaluated_params.ToArray())); } else if (root.GetType() == typeof(Operand)) { return((root as Operand).Evaluate()); } else//if root type equals operator { List <dynamic> evaluated_operands = new List <dynamic>(); foreach (var operand in (root as Operator).Operands) { evaluated_operands.Add(SolveExpressionTree(operand)); } return((root as Operator).Evaluate(evaluated_operands.ToArray())); } }
/// <summary> /// Производит обучение. /// </summary> /// <param name="learningExamples"></param> /// <param name="starSize"></param> /// <param name="heapSize"></param> /// <param name="isRandom"></param> public void Learn(List <LearnableExample> learningExamples, int starSize = 3, int heapSize = 3, bool isRandom = false) { if (learningExamples == null || learningExamples.Count == 0) { throw new ArgumentException("Недопустимый список атрибутов."); } if (starSize < 1) { throw new ArgumentException("Недопустимое значение StarSize: " + starSize + "."); } // список записей вида «значение типа решающего атрибута», «список положительных примеров», «список отрицательных примеров» List <Tuple <AttributeValue, List <LearnableExample>, List <LearnableExample> > > CArr = new List <Tuple <AttributeValue, List <LearnableExample>, List <LearnableExample> > >(); // тип решающего атрибута AttributeType attributeType = learningExamples[0].DecisiveAttribute.Type; _cover = new List <ProductionRule>(); // цикл по всем значениям типа решающего атрибута foreach (var value in attributeType.Values) { var cArr = new Tuple <AttributeValue, List <LearnableExample>, List <LearnableExample> >( new AttributeValue(attributeType, value), new List <LearnableExample>(), new List <LearnableExample>()); CArr.Add(cArr); // цикл по всем обучающим примерам foreach (var example in learningExamples) { // если очередное значение типа решающего атрибута эквивалентно значению решающего атрибута очереднеого примера if (value.Equals(example.DecisiveAttribute.Value)) { cArr.Item2.Add(example); } else { cArr.Item3.Add(example); } } Random random = new Random(); int nextSeed = 0; // пока есть примеры в POS while (cArr.Item2.Count > 0) { List <LearnableExample> NEG = new List <LearnableExample>(cArr.Item3); nextSeed = isRandom ? random.Next(0, cArr.Item2.Count - 1) : nextSeed; if (isRandom) { nextSeed = random.Next(0, cArr.Item2.Count - 1); } LearnableExample SEED = cArr.Item2[nextSeed]; if (!isRandom) { nextSeed++; } Expression STAR = new Expression(Operation.Con); bool isStarCoversNEG = true; int nextNeg = 0; //todo обработать ситуацию бесконечного цикла // пока условия STAR покрывают NEG (cArr.Item3) while (isStarCoversNEG) { if (isRandom) { nextNeg = random.Next(0, NEG.Count - 1); } if (nextNeg >= NEG.Count) { nextSeed = 0; break; } LearnableExample Eneg = NEG[nextNeg]; if (!isRandom) { nextNeg++; } Expression EXTENSION = new Expression(Operation.Con); for (int i = 0; i < SEED.PredictiveAttributes.Count; i++) { if (!SEED.PredictiveAttributes[i].Equals(Eneg.PredictiveAttributes[i]) && EXTENSION.Members.Count < heapSize) { EXTENSION.AddMember(new Expression(Operation.Dis, new List <IExpressionMember>() { SEED.PredictiveAttributes[i] /*, new Expression(Operation.Neg, Eneg.PredictiveAttributes[i])*/ })); } } if (!STAR.Members.Contains(EXTENSION)) { STAR.AddMember(EXTENSION); } NEG.Remove(Eneg); bool needBreak = true; foreach (var example in NEG) { if (STAR.IsCover(example)) { needBreak = false; break; } } if (needBreak) { break; } } //todo удалить дублирующие устолия STAR List <Tuple <IExpressionMember, int> > starExpressions = new List <Tuple <IExpressionMember, int> >(); foreach (var starExpression in STAR.Members) { int coveredExamplesCount = 0; foreach (var example in cArr.Item2) { if (starExpression.IsCover(example)) { coveredExamplesCount++; } } starExpressions.Add(new Tuple <IExpressionMember, int>(starExpression, coveredExamplesCount)); } // сортировка по возрастанию полезности starExpressions = starExpressions.OrderBy(starExpression => starExpression.Item2).ToList(); if (STAR.Members.Count > starSize) { for (int i = 0; STAR.Members.Count > starSize; i++) { STAR.Members.Remove(starExpressions[i].Item1); } } IExpressionMember BEST = starExpressions.Last().Item1; //COVER.AddMember(BEST); _cover.Add(new ProductionRule(BEST, cArr.Item1)); for (int i = 0; i < cArr.Item2.Count; i++) { if (BEST.IsCover(cArr.Item2[i])) { cArr.Item2.RemoveAt(i); i--; } } } } }
public ProductionRule(IExpressionMember condition, AttributeValue result) { _condition = condition; _result = result; IsDefault = false; }