/// <summary> /// Cloning an object to obtain a new object, not a reference to previous /// </summary> /// <returns>A new list of indexes for the selected decision according to the previous object</returns> public ListOfDecision Clone() { ListOfDecision x = new ListOfDecision(); x.ValueOfDecision = ValueOfDecision; foreach (var item in Indexes) { x.Indexes.Add(item); } return(x); }
/// <summary> /// Finding the number of occurrences and not occurrences /// </summary> /// <param name="listOfOption">The list of options</param> /// <param name="decision">Current decision for searching</param> /// <returns></returns> private List <ListOfOption> GetEnterAndNotEnter(List <ListOfOption> listOfOption, ListOfDecision decision) { List <ListOfOption> tmpListOfOption = new List <ListOfOption>(); foreach (var option in listOfOption) { var tmpRowsWithThisDecision = decision.Indexes.Intersect(option.Indexes); option.CountOfEnter = tmpRowsWithThisDecision.Count(); option.CountNotEnter = option.Indexes.Count - option.CountOfEnter; if (option.CountOfEnter > 0) { tmpListOfOption.Add(option); } } if (tmpListOfOption.Count > 0) { return(tmpListOfOption); } else { throw new EnterNotEnterException("Not found Entered and Not Entered"); } }
/// <summary> /// Finding all the rules /// </summary> /// <param name="decisionIndexes">Indexes of rows for which rules were still not finding</param> /// <param name="decision">Current decision for searching</param> /// <param name="listOfOption">The list of options</param> /// <param name="index">Decision index in ListOfALLDecisions</param> /// <param name="rule">Rule</param> /// <param name="oldOp">The previous option was selected</param> private void GetRules(List <int> decisionIndexes, ListOfDecision decision, List <ListOfOption> listOfOption, int index, Rule rule = null, List <int> oldOp = null) { //ListOfALLDecisions[index].Indexes - X в псевдокоді //if (G == 0) return; - в псевдокоді while G != 0 //If the list of decisionIndexes is empty, the interrupt recursion if (decisionIndexes.Count == 0) { return; } //Якщо список поточної шуканої децизії пустий і список децизій не пустий //то поточній децизії присвоїти список децизій if (decision.Indexes.Count == 0) { if (oldDec == null) { oldDec = new List <int>(); foreach (var item in decisionIndexes) { oldDec.Add(item); } } else { //Check for looping var difference = oldDec.Except(decisionIndexes); if (difference == null) { loopCount++; } if (loopCount >= 2) { Wrong += decisionIndexes.Count; oldDec.Clear(); decisionIndexes.Clear(); loopCount = 0; } } foreach (var item in decisionIndexes) { decision.Indexes.Add(item); } } try { //The announcement list to preserve all options in which the number of occurrences > 0 List <ListOfOption> tmpListOfOption = GetEnterAndNotEnter(listOfOption, decision); //Defining options with the highest occurrence var allOptionsWithMaxEnter = tmpListOfOption.Where(z => z.CountOfEnter == tmpListOfOption.Max(x => x.CountOfEnter)); //The definition of the option with the smallest number of occurrences var optionWithMinNotEnter = allOptionsWithMaxEnter.Where(z => z.CountNotEnter == allOptionsWithMaxEnter.Min(x => x.CountNotEnter)).First(); //Set to save the difference between the selected option and decision IEnumerable <int> rowsWithThisDecision = null; if (oldOp == null) { rowsWithThisDecision = optionWithMinNotEnter.Indexes.Except(ListOfALLDecisions[index].Indexes); } else { //Determining common parts between the old and new option var oldOpBoth = oldOp.Intersect(optionWithMinNotEnter.Indexes).ToList(); if (oldOpBoth.Count == 0) { List <ListOfOption> newListOfOption = new List <ListOfOption>(); foreach (var item in listOfOption) { newListOfOption.Add(item); } newListOfOption.Remove(optionWithMinNotEnter); GetRules(decisionIndexes, decision, newListOfOption, index, rule, oldOp); return; } //Definition of the difference between a common part and decision rowsWithThisDecision = oldOpBoth.Except(ListOfALLDecisions[index].Indexes); } if (rule == null) { //To create a new rule and adding the first part Dictionary <string, string> attrAndValue = new Dictionary <string, string>(); attrAndValue.Add(optionWithMinNotEnter.AttrName, optionWithMinNotEnter.Value); rule = new Rule() { AttrAndValue = attrAndValue }; } //If the number of differences = 0, it means that the new collection contains only elements of decision //and as a result we have a rule if (rowsWithThisDecision.Count() == 0) { if (oldOp != null) { rule.AttrAndValue.Add(optionWithMinNotEnter.AttrName, optionWithMinNotEnter.Value); } rule.DecisionClass = ListOfALLDecisions[index].ValueOfDecision; bool ruleChanged; do { ruleChanged = false; var partCount = rule.AttrAndValue.Count; for (int i = 0; i < partCount; i++) { var exceptAttr = rule.AttrAndValue.Keys.Except(new List <string>() { rule.AttrAndValue.ElementAt(i).Key }).ToList(); var exceptVal = rule.AttrAndValue.Values.Except(new List <string>() { rule.AttrAndValue.ElementAt(i).Value }).ToList(); Dictionary <string, string> dict = new Dictionary <string, string>(); for (int k = 0; k < exceptAttr.Count(); k++) { dict.Add(exceptAttr[k], exceptVal[k]); } List <int> foundObj = FindObj(dict); if (foundObj != null && !foundObj.Except(ListOfALLDecisions[index].Indexes).Any()) { rule.AttrAndValue.Remove(rule.AttrAndValue.ElementAt(i).Key); ruleChanged = true; break; } } } while (ruleChanged); //Adding to the list of rules a new rule Rules.Add(rule); //The rule is clean to save the following rules rule = null; //Remove indexes of decision for which the rule was created if (oldOp == null) { var both = optionWithMinNotEnter.Indexes.Intersect(decisionIndexes); foreach (var item in both) { decisionIndexes.Remove(item); } } else { var both = oldOp.Intersect(optionWithMinNotEnter.Indexes).Intersect(decisionIndexes); foreach (var item in both) { decisionIndexes.Remove(item); } } //To run the function with new data GetRules(decisionIndexes, new ListOfDecision(), ListOfAllOptions, index, rule); } else { //Add the next part of the rule if (oldOp != null) { rule.AttrAndValue.Add(optionWithMinNotEnter.AttrName, optionWithMinNotEnter.Value); } //Create a new list of options and delete the previous option List <ListOfOption> newListOfOption = new List <ListOfOption>(); foreach (var item in listOfOption) { newListOfOption.Add(item); } newListOfOption.Remove(optionWithMinNotEnter); //To run the function with new data if (oldOp == null) { GetRules(decisionIndexes, decision, newListOfOption, index, rule, optionWithMinNotEnter.Indexes); } else { ListOfDecision listOfDec = new ListOfDecision(); var dec = oldOp.Intersect(optionWithMinNotEnter.Indexes) .Intersect(decisionIndexes); foreach (var item in dec) { listOfDec.Indexes.Add(item); } GetRules(decisionIndexes, listOfDec, newListOfOption, index, rule, oldOp.Intersect(optionWithMinNotEnter.Indexes).ToList()); } } } //Catch the exception that indicates the inability to find options with the entry for this decision catch (EnterNotEnterException) { //Define the number of rows which could not be determined Wrong += decisionIndexes.Count; return; } }