예제 #1
0
        /// <summary>
        /// Remplace chaque occurence d'une variable aléatoirement choisi par une constante, tel que la règle final correspond à un ou plusieurs états de l'environnement.
        /// Echoue si une variable ne peut être remplacé en constante ou que la règle ne correspond à un ou plusieurs états.
        /// </summary>
        /// <param name="index">Index dans l'ensemble d'action.</param>
        /// <param name="actionSet">Ensemble d'action à traiter.</param>
        /// <param name="env">Environnement à prendre en compte.</param>
        /// <returns>Le classifieur fils muté, null si la mutation échoue.</returns>
        private Classifier VarToConst(int index, List <Classifier> actionSet, PerceivedEnvironnement env)
        {
            AppDomainSetup ads = new AppDomainSetup();

            ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
            AppDomain             appDomain = AppDomain.CreateDomain("PrologScript", null, ads);
            string                assembly  = Assembly.GetEntryAssembly().FullName;
            MatchMarshalRefByType mmrbt     =
                (MatchMarshalRefByType)appDomain.CreateInstanceAndUnwrap(assembly,
                                                                         typeof(MatchMarshalRefByType).FullName);

            List <HornClause> knowBase             = fo.knowledgeBase.ToList();
            var assertResult                       = mmrbt.AssertEnvironnement(env, knowBase, boundVarList, fo);
            Dictionary <string, int> usedPredicate = assertResult.Value.Value;
            Dictionary <Classifier, List <Attribute> > usedClassifiers = new Dictionary <Classifier, List <Attribute> >();

            Dictionary <Attribute, List <HornClause> > accMatchSet = new Dictionary <Attribute, List <HornClause> >();
            List <Classifier> matchSetCount = new List <Classifier>();

            bool isMatching = false;

            List <Classifier> actSet = ObjectCopier.Clone(actionSet);
            Random            rand   = new Random();
            Dictionary <ArgType, Dictionary <string, List <int[]> > > varList = GetAllValues(ArgMode.VAR, actionSet, index);

            if (varList.Count != 0)
            {
                ArgType randArgType = varList.Keys.ToArray()[rand.Next(varList.Keys.Count)];;
                string  randVar     = varList[randArgType].Keys.ToArray()[rand.Next(varList[randArgType].Count)];
                if (varList[randArgType][randVar].Count != 0)
                {
                    Attribute   newHead = actSet[index].rule.head;
                    Attribute[] newBody = actSet[index].rule.body;

                    if (randArgType is ArgType.TOKEN)
                    {
                        foreach (string constVar in env.tokenOnBoard)
                        {
                            foreach (int[] argIndex in varList[randArgType][randVar])
                            {
                                if (argIndex[0] == -1)
                                {
                                    if (newHead.predOp.argsOptions[argIndex[1]].argsMode.Contains(ArgMode.CONST))
                                    {
                                        newHead.values[argIndex[1]] = constVar;
                                    }
                                }
                                else
                                {
                                    if (newBody[argIndex[0]].predOp.argsOptions[argIndex[1]].argsMode.Contains(ArgMode.CONST))
                                    {
                                        newBody[argIndex[0]].values[argIndex[1]] = constVar;
                                    }
                                }
                            }

                            Classifier newCl     = new Classifier(currentTime, new HornClause(ObjectCopier.Clone(newHead), ObjectCopier.Clone(newBody)), fo);
                            string[]   accValues = newHead.values.ToArray() as string[];

                            List <Attribute> actionMatchList = mmrbt.GetClassifierMatchList(newCl, env);
                            if (actionMatchList.Count != 0)
                            {
                                matchSetCount.Add(newCl);
                            }
                        }
                    }

                    else
                    {
                        foreach (string constVar in boundVarList[randArgType].Keys)
                        {
                            foreach (int[] argIndex in varList[randArgType][randVar])
                            {
                                if (argIndex[0] == -1)
                                {
                                    if (newHead.predOp.argsOptions[argIndex[1]].argsMode.Contains(ArgMode.CONST))
                                    {
                                        newHead.values[argIndex[1]] = constVar;
                                    }
                                }
                                else
                                {
                                    if (newBody[argIndex[0]].predOp.argsOptions[argIndex[1]].argsMode.Contains(ArgMode.CONST))
                                    {
                                        newBody[argIndex[0]].values[argIndex[1]] = constVar;
                                    }
                                }
                            }

                            Classifier newCl     = new Classifier(currentTime, new HornClause(ObjectCopier.Clone(newHead), ObjectCopier.Clone(newBody)), fo);
                            string[]   accValues = newHead.values.ToArray() as string[];

                            List <Attribute> actionMatchList = mmrbt.GetClassifierMatchList(newCl, env);
                            if (actionMatchList.Count != 0)
                            {
                                matchSetCount.Add(newCl);
                            }
                        }
                    }

                    mmrbt.AbolishEnvironnement(usedPredicate);
                    AppDomain.Unload(appDomain);

                    if (matchSetCount.Count != 0)
                    {
                        return(matchSetCount[rand.Next(matchSetCount.Count)]);
                    }
                }
            }
            return(null);
        }
예제 #2
0
        /// <summary>
        /// Ajoute un prédicat au corps de la règle et lui octroie des arguments aléatoires entres constantes, variables libres ou liées.
        /// Si une constante est à ajouter, la règle finale doit correspondre à un ou plusieurs états de l'environnement.
        /// </summary>
        /// <param name="index">Index dans l'ensemble d'action.</param>
        /// <param name="actionSet">Ensemble d'action à traiter.</param>
        /// <param name="env">Environnement à prendre en compte.</param>
        /// <returns>Le classifieur fils muté, null si la mutation échoue.</returns>
        private Classifier AddAtom(int index, List <Classifier> actionSet, PerceivedEnvironnement env)
        {
            bool retry = false;

            Attribute newHead = ObjectCopier.Clone(actionSet)[index].rule.head;

            Attribute[] newBody = ObjectCopier.Clone(actionSet)[index].rule.body;
            Classifier  newCl   = null;

            List <string> availablePredicates = new List <string>();

            foreach (Attribute state in env.states)
            {
                if (!availablePredicates.Contains(state.name))
                {
                    availablePredicates.Add(state.name);
                }
            }


            Random rand         = new Random();
            string randAtomName = availablePredicates[rand.Next(availablePredicates.Count)];

            string[] randValues = new string[fo.statePredicateOptions[randAtomName].argsOptions.Count()];
            Dictionary <int, List <string> > constList = new Dictionary <int, List <string> >();

            int atomCount = 0;

            foreach (Attribute predicate in actionSet[index].rule.body)
            {
                if (predicate.name.Equals(randAtomName))
                {
                    atomCount++;
                }
            }

            if (atomCount <= fo.statePredicateOptions[randAtomName].max && actionSet[index].rule.body.Length < fo.maxPredicate)
            {
                for (int i = 0; i < randValues.Count(); i++)
                {
                    int accRand;
                    do
                    {
                        retry = false;
                        switch (fo.statePredicateOptions[randAtomName].argsOptions[i].argsMode[accRand = rand.Next(fo.statePredicateOptions[randAtomName].argsOptions[i].argsMode.Count())])
                        {
                        case ArgMode.CONST:
                            if (fo.statePredicateOptions[randAtomName].argsOptions[i].argType is ArgType.TOKEN)
                            {
                                if (!constList.ContainsKey(i))
                                {
                                    constList.Add(i, env.tokenOnBoard);
                                }
                            }
                            else
                            {
                                if (!constList.ContainsKey(i))
                                {
                                    constList.Add(i, boundVarList[fo.statePredicateOptions[randAtomName].argsOptions[i].argType].Keys.ToList());
                                }
                            }
                            break;

                        case ArgMode.VAR:
                            randValues[i] = fo.statePredicateOptions[randAtomName].argsOptions[i].argType.ToString() + varCount[fo.statePredicateOptions[randAtomName].argsOptions[i].argType];
                            varCount[fo.statePredicateOptions[randAtomName].argsOptions[i].argType]++;
                            break;

                        case ArgMode.BOUND:
                            Dictionary <ArgType, Dictionary <string, List <int[]> > > boundList = GetAllValues(ArgMode.BOUND, actionSet, index);
                            if (!boundList.ContainsKey(fo.statePredicateOptions[randAtomName].argsOptions[i].argType) ||
                                boundList[fo.statePredicateOptions[randAtomName].argsOptions[i].argType].Count == 0)
                            {
                                return(null);
                            }
                            string randBound = new List <string>(boundList[fo.statePredicateOptions[randAtomName].argsOptions[i].argType].Keys)[rand.Next(boundList[fo.statePredicateOptions[randAtomName].argsOptions[i].argType].Keys.Count)];
                            randValues[i] = randBound;
                            break;

                        default:
                            retry = true;
                            break;
                        }
                    } while (retry);
                }

                if (constList.Count != 0)
                {
                    AppDomainSetup ads = new AppDomainSetup();
                    ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
                    AppDomain             appDomain = AppDomain.CreateDomain("PrologScript", null, ads);
                    string                assembly  = Assembly.GetEntryAssembly().FullName;
                    MatchMarshalRefByType mmrbt     =
                        (MatchMarshalRefByType)appDomain.CreateInstanceAndUnwrap(assembly,
                                                                                 typeof(MatchMarshalRefByType).FullName);

                    List <HornClause> knowBase             = fo.knowledgeBase.ToList();
                    var assertResult                       = mmrbt.AssertEnvironnement(env, knowBase, boundVarList, fo);
                    Dictionary <string, int> usedPredicate = assertResult.Value.Value;
                    Dictionary <Classifier, List <Attribute> > usedClassifiers = new Dictionary <Classifier, List <Attribute> >();

                    Dictionary <Attribute, List <HornClause> > accMatchSet = new Dictionary <Attribute, List <HornClause> >();
                    List <Classifier> matchSetCount = new List <Classifier>();

                    List <Attribute> accMatchList = new List <Attribute>();

                    Dictionary <int, int> accIterators = new Dictionary <int, int>();
                    foreach (int i in constList.Keys)
                    {
                        accIterators.Add(i, 0);
                    }
                    bool endIterators = false;

                    int accIndex = fo.statePredicateOptions[randAtomName].argsOptions.Count();

                    while (!endIterators)
                    {
                        newHead = ObjectCopier.Clone(actionSet)[index].rule.head;
                        newBody = ObjectCopier.Clone(actionSet)[index].rule.body;

                        foreach (int i in constList.Keys)
                        {
                            randValues[i] = constList[i][accIterators[i]];
                        }

                        var acc = ObjectCopier.Clone(newBody).ToList();
                        acc.Add(new Attribute(randAtomName, randValues.ToArray(), fo.statePredicateOptions[randAtomName]));
                        newBody = acc.ToArray();
                        newCl   = new Classifier(currentTime, new HornClause(newHead, newBody.ToArray()), fo);

                        if ((accMatchList = mmrbt.GetClassifierMatchList(newCl, env)).Count != 0)
                        {
                            matchSetCount.Add(newCl);
                        }

                        for (int i = 0; i <= constList.Last().Key; i++)
                        {
                            if (constList.Keys.Contains(i))
                            {
                                accIterators[i]++;
                                while (i <= constList.Last().Key&& (!constList.Keys.Contains(i) || accIterators[i] >= constList[i].Count))
                                {
                                    if (constList.Keys.Contains(i))
                                    {
                                        accIterators[i] = 0;
                                    }
                                    i++;
                                }

                                if (accIterators.Values.Sum() == 0 || accIterators[i] < constList[i].Count())
                                {
                                    if (accIterators.Values.Sum() == 0)
                                    {
                                        endIterators = true;
                                    }
                                    break;
                                }
                            }
                        }
                    }

                    mmrbt.AbolishEnvironnement(usedPredicate);
                    AppDomain.Unload(appDomain);
                    if (matchSetCount.Count == 0)
                    {
                        return(null);
                    }
                    else
                    {
                        return(matchSetCount[rand.Next(matchSetCount.Count)]);
                    }
                }

                List <Attribute> predicateList = new List <Attribute>(actionSet[index].rule.body.ToArray());
                predicateList.Add(new Attribute(randAtomName, randValues, fo.statePredicateOptions[randAtomName]));
                Attribute[] newRule = predicateList.ToArray();
                return(new Classifier(currentTime, new HornClause(actionSet[index].rule.head, newRule), fo));
            }
            return(null);
        }
예제 #3
0
        /// <summary>
        /// Crée de nouveaux classifieurs dérivant de ceux présents dans l'ensemble d'action en appliquant des opérations de mutations.
        /// Insère les nouveaux classifieurs dans la population et en supprime si la population est dépassée en terme de capacité.
        /// Ne se lance que si le temps moyen écoulé depuis le dernier lancement de l'algorithme génétique sur l'ensemble des classifieurs de l'ensemble d'action est plus grand qu'une limite <see cref="FOXCSOptions.geneticThresh"/>.
        /// </summary>
        /// <param name="actionSet">Ensemble d'action à traiter.</param>
        /// <param name="env">Environnement à utiliser.</param>
        private void RunGeneticAlgorithm(List <Classifier> actionSet, PerceivedEnvironnement env)
        {
            int timeNumSum = 0;
            int numSum     = 0;

            foreach (Classifier cl in actionSet)
            {
                timeNumSum += cl.timeStamp * cl.numerosity;
                numSum     += cl.numerosity;
            }

            if (numSum == 0)
            {
                return;
            }
            if (currentTime - timeNumSum / numSum > fo.geneticThresh)
            {
                Console.WriteLine("Executing Genetic Algorithm.");
                Classifier newClassifier = null;
                Random     rand          = new Random();
                double     prob          = -1;
                for (int i = 0; i < actionSet.Count; i++)
                {
                    actionSet[i].timeStamp = currentTime;
                    while (newClassifier == null)
                    {
                        prob = rand.NextDouble();

                        if (fo.probMutationRange.mutRanges[0].InRange(prob))
                        {
                            newClassifier = DeleteAtom(i, actionSet, env);
                        }
                        else if (fo.probMutationRange.mutRanges[1].InRange(prob))
                        {
                            newClassifier = ConstToVar(i, actionSet, env);
                        }
                        else if (fo.probMutationRange.mutRanges[2].InRange(prob))
                        {
                            newClassifier = VarToAnonym(i, actionSet, env);
                        }
                        else if (fo.probMutationRange.mutRanges[3].InRange(prob))
                        {
                            newClassifier = AddAtom(i, actionSet, env);
                        }
                        else if (fo.probMutationRange.mutRanges[4].InRange(prob))
                        {
                            newClassifier = VarToConst(i, actionSet, env);
                        }
                        else if (fo.probMutationRange.mutRanges[5].InRange(prob))
                        {
                            newClassifier = AnonymToVar(i, actionSet, env);
                        }
                        else if (fo.probMutationRange.mutRanges[6].InRange(prob))
                        {
                            newClassifier = Reproduction(i, actionSet, env);
                        }
                        if (newClassifier != null)
                        {
                            int popIndex = ActionSetIndexOf(actionSet, newClassifier);
                            if (popIndex != -1)
                            {
                                actionSet[popIndex].numerosity++;
                            }
                            else
                            {
                                popIndex = PopSetIndexOf(newClassifier);
                                if (popIndex != -1)
                                {
                                    popSet[popIndex].numerosity++;
                                }
                                else
                                {
                                    popSet.Add(newClassifier);
                                }
                            }
                            DeleteFromPopulation();
                        }
                    }
                }
            }
        }
예제 #4
0
        private void DeleteFromPopulation()
        {
            int    popSize    = 0;
            double fitnessSum = 0;

            foreach (Classifier cl in popSet)
            {
                popSize    += cl.numerosity;
                fitnessSum += cl.fitness;
            }

            while (popSize > fo.popMaxSize)
            {
                double averageFitnessInPop = fitnessSum / popSize;

                double voteSum = 0;
                foreach (Classifier cl in popSet)
                {
                    voteSum += DeletionVote(cl, averageFitnessInPop);
                }

                double choicePoint = new Random().NextDouble() * voteSum;
                voteSum = 0;

                for (int i = 0; i < popSet.Count; i++)
                {
                    voteSum += DeletionVote(popSet[i], averageFitnessInPop);
                    if (voteSum > choicePoint)
                    {
                        if (popSet[i].numerosity > 1)
                        {
                            popSet[i].numerosity--;
                        }
                        else
                        {
                            Classifier accCl = popSet[i];
                            popSet.RemoveAt(i);
                            if (matchSet.Count != 0)
                            {
                                foreach (KeyValuePair <Attribute, List <Classifier> > matchSubSet in ObjectCopier.Clone(matchSet))
                                {
                                    if (matchSubSet.Value.Contains(accCl))
                                    {
                                        matchSubSet.Value.RemoveAll(cl => cl.rule == accCl.rule);
                                        if (matchSubSet.Value.Count == 0)
                                        {
                                            matchSet.Remove(matchSubSet.Key);
                                        }
                                    }
                                }
                            }
                        }

                        break;
                    }

                    popSize    = 0;
                    fitnessSum = 0;
                    foreach (Classifier cl in popSet)
                    {
                        popSize    += cl.numerosity;
                        fitnessSum += cl.fitness;
                    }
                }
            }
        }
 public YPMatchThread(ref Classifier cl, Attribute action)
 {
     this.cl          = cl;
     this.action      = action;
     this.clMatchList = new List <Attribute>();
 }
            /// <summary>
            /// Méthode gérant la concordance d'un classifieur
            /// </summary>
            /// <param name="cl">Classifieur à vérifier.</param>
            /// <param name="env">Environnement à insérer dans la base de prédicats.</param>
            /// <param name="knowledgeBase">Clause constiuant la base de connaissance.</param>
            /// <returns></returns>
            public List <Attribute> GetClassifierMatchList(Classifier cl, PerceivedEnvironnement env)
            {
                List <Attribute>         clMatchList   = new List <Attribute>();
                Dictionary <string, int> usedPredicate = new Dictionary <string, int>();

                List <YPMatchThread> ypts    = new List <YPMatchThread>();
                List <Task>          threads = new List <Task>();

                foreach (Attribute action in env.actions)
                {
                    if (cl.rule.head.name.Equals(action.name))
                    {
                        if (cl.rule.clause == null)
                        {
                            lock (_lock)
                                cl.rule.YPwriteAndCompile();
                        }
                        ypts.Insert(0, new YPMatchThread(ref cl, action));
                        threads.Insert(0, new Task(ypts[0].ActionMatch));
                        threads[0].Start();
                    }

                    /*
                     *
                     *
                     * if (cl.rule.head.name.Equals(action.name))
                     * {
                     *  if (cl.rule.clause == null)
                     *      lock (_lock)
                     *          cl.rule.YPwriteAndCompile();
                     *  foreach (bool l1 in cl.rule.Match(action.values))
                     *  {
                     *      clMatchList.Add(action);
                     *      break;
                     *  }
                     * }
                     *
                     */
                }


                for (int j = 0; j < threads.Count; j++)
                {
                    try
                    {
                        threads[j].Wait();
                        threads[j].Dispose();
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Erreur provenant de YieldProlog, relancement du thread YPThread.");
                        Console.ReadKey();
                        Console.WriteLine(e);
                        threads[j].Dispose();
                        threads.Insert(0, new Task(ypts[j].ActionMatch));
                    }
                }

                foreach (YPMatchThread ypt in ypts)
                {
                    foreach (Attribute actionMatch in ypt.clMatchList)
                    {
                        if (!clMatchList.Contains(actionMatch))
                        {
                            clMatchList.Add(actionMatch);
                        }
                    }
                }

                return(clMatchList);
            }