//protected Random _random = new Random(0); /// <summary> /// Liefert die nächste zu belegende Variable zurück. /// </summary> /// <remarks>Die Auswahl findet dabei /// über die MRV-Heuristic statt(Minimum Remaining Values). /// Haben mehrere Variablen die gleiche Anzahl verbleibender Werte, dann /// wird die GradHeuristic genutzt, d.h. es wird die Variable genommen, die in /// den meisten Randbedingungen vorkommt. /// </remarks> /// <param name="configuration">Die Konfiguration, die noch nicht belegte Variablen enthält.</param> /// <param name="constraintList">Die Liste mit den Randbedingungen.</param> /// <returns> /// Gibt die als nächstes zu belegende Variable zurück. /// </returns> public Variable GetHeuristicVariable(ConstraintConfiguration configuration, ConstraintList constraintList) { Variable result = null; int minDomainValues = 0; List <Variable> mrvVariables = new List <Variable>(); //// Zufall //SortedList<double, Variable> sortedList = new SortedList<double, Variable>(configuration.Variables.GetLength(0)); //foreach (Variable var in configuration.Variables) //{ // sortedList.Add(_random.NextDouble(), var); //} //// search the variables with the minimum remaining values //foreach(Variable var in sortedList.Values) foreach (Variable var in configuration.Variables) { if (!var.HasAsignedValue) { if (result == null) { result = var; minDomainValues = var.Domain.Count; mrvVariables.Add(var); } else if (minDomainValues > var.Domain.Count) { mrvVariables.Clear(); result = var; minDomainValues = var.Domain.Count; mrvVariables.Add(var); } else if (minDomainValues == var.Domain.Count) { mrvVariables.Add(var); } } } // are there more then one variables we should use the variable with the most constraints if (mrvVariables.Count != 1) { int countConstraints = 0; int varCountConstraints = 0; foreach (Variable var in mrvVariables) { varCountConstraints = constraintList.GetConstraints(var.Name).Count; if (varCountConstraints > countConstraints) { result = var; countConstraints = varCountConstraints; } } } return(result); }
/// <summary> /// Für den übergebenen Knoten werden neue Unterknoten generiert. /// </summary> /// <param name="node">Anhand des übergebenen Knotens werden neue Unterknoten /// generiert.</param> /// <param name="maxCount">Beschränkt die Anzahl der Unterknoten.</param> /// <returns> /// Gibt die Menge der generierten Knoten als Array zurück. /// </returns> public virtual INode[] GenerateChildren(INode node, int maxCount) { ConstraintConfiguration parentConfiguration = (ConstraintConfiguration)node.Data; Variable nextVar = _heuristicVariable.GetHeuristicVariable(parentConfiguration, _constraintList); List <INode> generatedNodes = new List <INode>(); if (nextVar == null) { throw new Exception("nextVar is null"); } //// Zufall //List<KeyValuePair<double, double>> sortedList = new List<KeyValuePair<double, double>>(nextVar.Domain.Count); //foreach (double value in nextVar.Domain) //{ // sortedList.Add(new KeyValuePair<double,double>(_random.NextDouble(), value)); //} //sortedList.Sort(); //foreach (KeyValuePair<double,double> pair in sortedList) foreach (double value in nextVar.Domain) { ConstraintConfiguration configuration = new ConstraintConfiguration(parentConfiguration); Variable currentVar = configuration.GetVariable(nextVar.Name); currentVar.Value = value; List <Constraint> constraints = _constraintList.GetConstraints(nextVar.Name); bool operationFailed = false; foreach (Constraint cons in constraints) { bool tempChanging = false; cons.SetCurrentConfiguration(configuration); // todo: Ist diese Abfrage wirklich notwendig? //if (cons.IsComplied == false) //{ // operationFailed = true; // break; //} if (_consistencyOptions.GetCheckConsistencyActive(ConsistencyCheckRegion.EachNodeGenerating, ConsistencyType.Bounds) && ConstraintForms.CheckBoundsConsistency(cons, ref tempChanging) == false) { operationFailed = true; break; } else if (_consistencyOptions.GetCheckConsistencyActive(ConsistencyCheckRegion.EachNodeGenerating, ConsistencyType.Node) && configuration.CheckNodeConsistency(cons, false) == false) { operationFailed = true; break; } else if (_consistencyOptions.GetCheckConsistencyActive(ConsistencyCheckRegion.EachNodeGenerating, ConsistencyType.Arc) && CheckArcConsistency(configuration) == false) { operationFailed = true; break; } } if (!operationFailed) { // Die Domaene kann gelöscht werden currentVar.Domain = null; generatedNodes.Add(CreateNode(node, configuration)); //configuration.Show(); } } INode[] result; result = new INode[generatedNodes.Count]; generatedNodes.CopyTo(result); return(result); }