//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);
        }
Esempio n. 2
0
        /// <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);
        }