web-dev-qa-db-fra.com

Comment gérer des milliers de règles IF ... THEN ... ELSE?

J'envisage de créer une application qui, à la base, consisterait en des milliers de déclarations if ... then ... else. Le but de l'application est de pouvoir prédire comment les vaches se déplacent dans n'importe quel paysage. Ils sont affectés par des choses comme le soleil, le vent, la source de nourriture, les événements soudains, etc.

Comment gérer une telle application? J'imagine qu'après quelques centaines d'instructions IF, il serait aussi imprévisible que le programme réagisse et le débogage de ce qui conduirait à une certaine réaction signifierait qu'il faudrait parcourir l'arborescence entière des instructions IF à chaque fois.

J'ai lu un peu sur les moteurs de règles, mais je ne vois pas comment ils contourneraient cette complexité.

215
David

Le langage de programmation logique Prolog peut être ce que vous recherchez. Votre énoncé de problème n'est pas suffisamment précis pour que j'évalue s'il convient, mais il est plutôt similaire à ce que vous dites.

Un programme Prolog se compose de faits et de règles appliqués. Voici un exemple de règle simple qui stipule "Une vache se déplace vers un endroit si la vache a faim et qu'il y a plus de nourriture dans le nouvel emplacement que dans l'ancien emplacement":

moves_to(Cow, Location) :-
  hungry(Cow),
  current_location(Cow, OldLoc),
  food_in(OldLoc, OldFood), food_in(Location, NewFood),
  NewFood > OldFood.

Toutes les choses en majuscules sont des variables, des choses dont vous ne connaissez pas la valeur. Prolog tente de trouver des valeurs pour ces variables qui satisfont à toutes les conditions. Ce processus est effectué avec un algorithme puissant appelé unification qui est au cœur des environnements de programmation logique Prolog et similaires.

En plus des règles, une base de données de faits est fournie. Un exemple simple qui fonctionne avec les règles ci-dessus pourrait être quelque chose comme:

current_location(white_cow, pasture).

current_location(black_cow, barn).
hungry(black_cow).

current_location(angry_bull, forest).
hungry(angry_bull).

food_in(barn, 3).
food_in(pasture, 5).
food_in(forest, 1).

Notez que white_cow et pasture, etc. ne sont pas écrits en majuscules. Ce ne sont pas des variables, ce sont des atomes.

Enfin, vous faites une requête et demandez ce qui va se passer.

?- moves_to(white_cow, Destination).
No.
?- moves_to(black_cow, Destination).
Destination = pasture
?- moves_to(Cow, Destination).
Cow = black_cow, Destination = pasture
Cow = angry_bull, Destination = barn
Cow = angry_bull, Destination = pasture

La première requête demande où la vache blanche se déplacera. Compte tenu des règles et des faits ci-dessus, la réponse est non. Cela peut être interprété comme "je ne sais pas" ou "ça ne bouge pas" selon ce que vous voulez.

La deuxième requête demande où la vache noire se déplace. Il se déplace au pâturage pour manger.

La dernière requête demande où se déplacent toutes les vaches. En conséquence, vous obtenez tout le possible (vache, destination) qui a du sens. Dans ce cas, le taureau noir se déplace vers le pâturage comme prévu. Cependant, le taureau en colère a deux choix qui satisfont aux règles, il peut se déplacer vers le pâturage ou la grange.

Remarque: Cela fait des années que j'ai écrit Prolog pour la dernière fois, tous les exemples peuvent ne pas être syntaxiquement valides, mais l'idée devrait être correcte.

73
exDM69

S'attaquer au problème si web , vous pouvez créer un moteur de règles où chaque règle spécifique est codée indépendamment. Un autre raffinement serait de créer un langage spécifique au domaine (DSL) pour créer les règles, mais un DSL seul ne déplace le problème que d'une base de code (principale) à une autre (DSL). Sans structure, la DSL ne s'en sortira pas mieux que le langage natif (Java, C # etc.), nous y reviendrons donc après avoir trouvé une approche structurelle améliorée.

Le problème fondamental est que vous rencontrez un problème de modélisation. Chaque fois que vous rencontrez des situations combinatoires comme celle-ci, c'est un signe clair que l'abstraction de votre modèle qui décrit la situation est trop grossière. Vous combinez très probablement des éléments qui devraient appartenir à différents modèles dans une seule entité.

Si vous continuez à décomposer votre modèle, vous finirez par dissoudre complètement cet effet combinatoire. Cependant, en prenant ce chemin, il est facile de se perdre dans votre conception, créant un gâchis encore plus grand, le perfectionnisme ici n'est pas nécessairement votre ami.

Les machines à états finis et les moteurs de règles ne sont qu'un exemple de la façon dont ce problème peut être décomposé et rendu plus gérable. L'idée principale ici est qu'un bon moyen de se débarrasser d'un problème combinatoire tel que celui-ci consiste souvent à créer un design et le répéter ad nauseam dans des niveaux d'abstraction imbriqués jusqu'à ce que votre système fonctionne de manière satisfaisante. Similaire à la façon dont les fractales sont utilisées pour créer des motifs complexes. Les règles restent les mêmes, que vous regardiez votre système au microscope ou à vol d'oiseau.

Exemple d'application de ceci à votre domaine.

Vous essayez de modéliser la façon dont les vaches se déplacent sur un terrain. Bien que votre question manque de détails, je suppose que votre grande quantité d'if comprend un fragment de décision tel que if cow.isStanding then cow.canRun = true mais vous vous enlisez en ajoutant des détails sur le terrain par exemple. Donc, pour chaque action que vous souhaitez entreprendre, vous devez vérifier tous les aspects auxquels vous pouvez penser et répéter ces vérifications pour la prochaine action possible.

Nous avons d'abord besoin de notre conception reproductible, qui dans ce cas sera un FSM pour modéliser les états changeants de la simulation. Donc, la première chose que je ferais serait d'implémenter un FSM de référence, définissant une interface d'état , une transition interface, et peut-être un contexte de transition qui peut contenir des informations partagées à mettre à la disposition des deux autres. Une implémentation FSM de base passera d'une transition à une autre quel que soit le contexte, c'est là qu'intervient un moteur de règles. Le moteur de règles encapsule proprement les conditions qui doivent être remplies pour que la transition ait lieu. Un moteur de règles ici peut être aussi simple qu'une liste de règles ayant chacune une fonction d'évaluation renvoyant un booléen. Pour vérifier si une transition doit avoir lieu, nous itérons la liste des règles et si l'une d'elles est évaluée comme fausse, la transition n'a pas lieu. La transition elle-même contiendra le code comportemental pour modifier l'état actuel du FSM (et d'autres tâches possibles).

Maintenant, si je commence à implémenter la simulation comme un seul grand FSM au niveau DIEU, je me retrouve avec BEAUCOUP d'états possibles, de transitions, etc. maintenant une règle qui effectue un test par rapport à une information spécifique du contexte (qui à ce stade contient presque tout) et chaque corps IF est quelque part dans le code de transition.

Entrez la répartition des fractales: la première étape serait de créer un FSM pour chaque vache où les états sont les propres états internes de la vache (debout, courir, marcher, brouter, etc.) et les transitions entre elles seraient affectées par l'environnement. Il est possible que le graphique ne soit pas complet, par exemple le pâturage n'est accessible qu'à partir de l'état stationnaire, toute autre transition est dissoute car simplement absente du modèle. Ici, vous séparez efficacement les données dans deux modèles différents, la vache et le terrain. Chacun avec ses propres propriétés définies. Cette panne vous permettra de simplifier la conception globale de votre moteur. Maintenant, au lieu d'avoir un seul moteur de règles qui décide de tout ce que vous avez, plusieurs moteurs de règles plus simples (un pour chaque transition) décident de détails très spécifiques. De nombreuses sociétés de jeux utilisent des machines à états finis comme celle-ci pour décider de ces aspects.

Parce que je réutilise le même code pour le FSM, il s'agit essentiellement d'une configuration du FSM. Rappelez-vous quand nous avons mentionné les DSL plus tôt? C'est là que la DSL peut faire beaucoup de bien si vous avez beaucoup de règles et de transitions à écrire.

Aller plus loin

Maintenant, DIEU n'a plus à gérer toute la complexité de la gestion des états internes de la vache, mais nous pouvons pousser plus loin. La gestion du terrain reste par exemple très complexe. C'est là que vous décidez où la ventilation est suffisante. Si par exemple dans votre DIEU vous finissez par gérer la dynamique du terrain (herbe longue, boue, boue sèche, herbe courte, etc.), nous pouvons répéter le même schéma. Rien ne vous empêche d'incorporer une telle logique dans le terrain lui-même en extrayant tous les états du terrain (herbe longue, herbe courte, boueux, sec, etc.) dans un nouveau FSM de terrain avec des transitions entre les états et peut-être des règles simples. Par exemple, pour arriver à l'état boueux, le moteur de règles doit vérifier le contexte pour trouver des liquides, sinon ce n'est pas possible. Maintenant, DIEU est devenu encore plus simple.

Vous pouvez compléter le système de FSM en les rendant autonomes et en leur donnant chacun un fil. Cette dernière étape n'est pas nécessaire, mais elle vous permet de modifier dynamiquement l'interaction du système en ajustant la façon dont vous déléguez votre prise de décision (lancement d'un FSM spécialisé ou simplement retour d'un état prédéterminé).

Rappelez-vous comment nous avons mentionné que les transitions pouvaient également faire "d'autres tâches possibles"? Explorons cela en ajoutant la possibilité pour différents modèles (FSM) de communiquer entre eux. Vous pouvez définir un ensemble d'événements et permettre à chaque FSM d'enregistrer l'écouteur à ces événements. Ainsi, si, par exemple, une vache entre dans un hexagone de terrain, l'hexagone peut enregistrer des écouteurs pour les changements de transition. Ici, cela devient un peu délicat car chaque FSM est implémenté à un niveau très élevé sans aucune connaissance du domaine spécifique qu'il héberge. Cependant, vous pouvez y parvenir en demandant à la vache de publier une liste d'événements et la cellule peut s'enregistrer si elle voit des événements auxquels elle peut réagir. Une bonne hiérarchie de la famille d'événements ici est un bon investissement. Ainsi, si la vache commence à brouter, la parcelle de terrain peut enregistrer le temps de pâturage et après un certain temps peut passer de l'herbe longue à l'herbe courte, signalant ainsi à la vache qu'il n'y a plus rien à manger ici.

Vous pouvez pousser plus loin encore en modélisant les niveaux de nutriments et le cycle de croissance de l'herbe, avec ... vous l'avez deviné ... un FSM d'herbe intégré dans le propre modèle de la parcelle de terrain.

Si vous poussez l'idée assez loin, DIEU n'a que très peu à faire car tous les aspects sont à peu près autogérés, libérant du temps à consacrer à des choses plus divines.

Résumer

Comme indiqué ci-dessus, le FSM n'est pas la solution, juste un moyen d'illustrer que la solution à un tel problème ne se trouve pas dans le code, mais comment vous modélisez votre problème. Il existe très probablement d'autres solutions possibles et probablement bien meilleures que ma proposition FSM. Cependant l'approche "fractales" reste un bon moyen de gérer cette difficulté. Si cela est fait correctement, vous pouvez allouer dynamiquement des niveaux plus profonds là où cela compte, tout en donnant des modèles plus simples là où cela importe moins. Vous pouvez mettre en file d'attente les modifications et les appliquer lorsque les ressources deviennent plus disponibles. Dans une séquence d'actions, il peut ne pas être très important de calculer le transfert de nutriments de la vache à l'herbe. Vous pouvez cependant enregistrer ces transitions et appliquer les modifications à une date ultérieure ou tout simplement approximer avec une supposition éclairée en remplaçant simplement les moteurs de règles ou peut-être en remplaçant complètement l'implémentation FSM par une version naïve plus simple pour les éléments qui ne sont pas dans le domaine direct de intérêt (cette vache à l'autre bout du champ) pour permettre des interactions plus détaillées pour obtenir le focus et une plus grande part des ressources. Tout cela sans jamais revoir le système dans son ensemble; chaque pièce étant bien isolée, il devient plus facile de créer un remplacement de remplacement limitant ou prolongeant la profondeur de votre modèle. En utilisant une conception standard, vous pouvez tirer parti de cela et maximiser les investissements réalisés dans des outils ad hoc tels qu'une DSL pour définir des règles ou un vocabulaire standard pour les événements, en commençant à nouveau à un niveau très élevé et en ajoutant des améliorations au besoin.

Je fournirais un exemple de code mais c'est tout ce que je peux me permettre de faire en ce moment.

140
Newtopian

Il semble que toutes ces instructions conditionnelles dont vous parlez devraient vraiment être des données qui configurent votre programme plutôt qu'une partie de votre programme lui-même. Si vous pouvez les traiter de cette façon, vous serez libre de modifier le fonctionnement de votre programme en changeant simplement sa configuration au lieu d'avoir à modifier votre code et à recompiler chaque fois que vous souhaitez améliorer votre modèle.

Il existe de nombreuses façons de modéliser le monde réel, selon la nature de votre problème. Vos différentes conditions peuvent devenir des règles ou des contraintes appliquées à la simulation. Au lieu d'avoir un code qui ressemble à:

if (sunLevel > 0.75) {
   foreach(cow in cows) {
       cow.desireForShade += 0.5;
   }
}
if (precipitation > 0.2) {
   foreach(cow in cows) {
       cow.desireForShelter += 0.8;
   }
}

vous pouvez à la place avoir un code qui ressemble à ceci:

foreach(rule in rules) {
   foreach (cow in cows) {
      cow.apply(rule);
   }
}

Ou, si vous pouvez développer un programme linéaire qui modélise le comportement de la vache en fonction d'un certain nombre d'entrées, chaque contrainte peut devenir une ligne dans un système d'équations. Vous pouvez ensuite transformer cela en un modèle de Markov que vous pouvez répéter.

Il est difficile de dire quelle est la bonne approche pour votre situation, mais je pense que vous aurez beaucoup plus de facilité si vous considérez vos contraintes comme des entrées dans votre programme et non du code.

90
Caleb

Personne ne l'a mentionné, j'ai donc pensé le dire explicitement:

Des milliers de règles "Si .. Alors .. Sinon" est le signe d'une application mal conçue.

Bien que la représentation des données spécifiques au domaine puisse ressembler à ces règles, êtes-vous absolument certain que votre implémentation devrait ressembler à la représentation spécifique au domaine?

45
blueberryfields

Veuillez utiliser des logiciels/langages informatiques adaptés à la tâche. Matlab est très souvent utilisé pour modéliser des systèmes complexes, où vous pouvez en effet avoir littéralement des milliers de conditions. Ne pas utiliser les clauses if/then/else, mais par analyse numérique. R est un langage informatique open source rempli d'outils et de packages pour faire de même. Mais cela signifie que vous devez également reformuler votre modèle en termes plus mathématiques, afin que vous puissiez inclure à la fois les principales influences et les interactions entre les influences dans les modèles.

Si vous ne l'avez pas déjà fait, veuillez suivre un cours sur la modélisation et la simulation. La dernière chose que vous devriez faire, c'est d'envisager d'écrire un modèle comme celui-ci en termes de si - alors - d'autre. Nous avons des chaînes de Markov Monte Carlo, des machines à vecteurs de support, des réseaux de neurones, des analyses de variables latentes, ... Veuillez ne pas vous jeter 100 ans en arrière en ignorant la richesse des outils de modélisation dont vous disposez.

17
Joris Meys

Les moteurs de règles peuvent aider, car s'il y a tellement de règles if/then, il peut être utile de les mettre toutes en un seul endroit en dehors du programme où les utilisateurs peuvent les modifier sans avoir besoin de connaître un langage de programmation. De plus, des outils de visualisation peuvent être disponibles.

Vous pouvez également consulter des solutions de programmation logique (comme Prolog). Vous pouvez rapidement modifier la liste des instructions if/then et lui faire faire des choses comme regarder si une combinaison d'entrées conduirait à certains résultats, etc. code orienté objet).

13
psr

Il m'est soudainement apparu:

Vous devez utiliser un Arbre d'apprentissage décisionnel (Algorithme ID3).

Il est fort probable que quelqu'un l'ait implémenté dans votre langue. Sinon, vous pouvez porter une bibliothèque existante

11
Darknight

Il s'agit plus d'une réponse wiki communautaire, agrégeant les différents outils de modélisation suggérés par d'autres réponses, je viens d'ajouter des liens supplémentaires vers des ressources.

Je ne pense pas qu'il soit nécessaire de réaffirmer que vous devriez utiliser une approche différente pour des milliers d'instructions if/else codées en dur.

11
ocodo

Chaque grande application contient des milliers de if-then-else, sans compter les autres contrôles de flux, et ces applications sont toujours déboguées et maintenues, malgré leur complexité.

De plus, le nombre d'instructions ne rend pas le flux imprévisible . La programmation asynchrone le fait. Si vous utilisez des algorithmes déterministes de manière synchrone, vous aurez à chaque fois un comportement 100% prévisible.

Vous devriez probablement mieux expliquer ce que vous essayez de faire sur Stack Overflow ou Revue de code afin que les utilisateurs puissent vous suggérer les techniques de refactorisation précises à utiliser. Vous pouvez également souhaiter poser des questions plus précises, comme "Comment éviter d'imbriquer trop de déclarations if <avec un morceau de code>".

9
Arseni Mourzenko

Je vous suggère d'utiliser un moteur de règles. Dans le cas de Java, jBPM ou Oracle BPM peuvent être utiles. Les moteurs de règles vous permettent essentiellement de configurer l'application via XML.

2
Sid

Le problème n'est pas bien résolu par les "règles", qu'elles soient décrites par le code procédural "si-alors" ou par les nombreuses solutions de règles conçues pour les applications métier. L'apprentissage automatique fournit un certain nombre de mécanismes pour modéliser de tels scénarios.

Fondamentalement, il faut formuler un schéma de représentation discrète des facteurs (par exemple, le soleil, le vent, la source de nourriture, les événements soudains, etc.) qui influencent le "système" (c'est-à-dire les vaches dans un pâturage). Malgré la croyance erronée selon laquelle on peut créer une représentation fonctionnelle à valeur réelle, par opposition à discrète, aucun ordinateur dans le monde réel (y compris le système nerveux humain) n'est basé sur des valeurs réelles ou des calculs basés sur des valeurs réelles.

Une fois que vous avez votre représentation numérique des facteurs pertinents, vous pouvez construire n'importe lequel de plusieurs modèles mathématiques. Je suggérerais un graphique bipartite où un ensemble de nœuds représente les vaches et l'autre une zone unitaire de pâturage. Une vache à tout moment occupe une zone unitaire de pâturage. Pour chaque vache, il existe alors une valeur d'utilité associée au courant et à toutes les autres unités de pâturage. Si le modèle présuppose que la vache cherche à optimiser (quel que soit le moyen pour la vache) la valeur d'utilité de son unité de pâturage, alors les vaches se déplaceront d'une unité à l'unité dans un effort d'optimisation.

Un automate cellulaire fonctionne bien pour exécuter le modèle. Les mathématiques sous-jacentes dans le monde mathématique à valeur réelle motivant le déplacement des vaches sont un modèle de gradient de champ. Les vaches passent de positions de valeur d'utilité perçue plus faible à des positions de valeur d'utilité perçue plus élevée.

Si l'on injecte des changements environnementaux dans le système, il ne passera pas à une solution stable de positionnement des vaches. Il deviendra également un modèle auquel des aspects de la théorie des jeux pourraient être appliqués; pas que cela ajouterait nécessairement beaucoup à ce cas.

L'avantage ici est l'abattage des vaches ou l'acquisition de nouvelles vaches peut être facilement gérée en soustrayant et en ajoutant des cellules "vache" au graphique bipartite, pendant que le modèle fonctionne.

2
charles

Rendez votre application gérable en la concevant bien. Concevez votre application en divisant les différentes logiques métier en classes/modules séparés. Écrivez des tests unitaires qui testent individuellement chacune de ces classes/modules. Ceci est crucial et vous aidera à vous assurer que la logique métier est mise en œuvre comme prévu.

2
Bernard

Il n'y aura probablement pas une seule façon de résoudre votre problème, mais vous pouvez gérer la complexité de celui-ci pièce par pièce si vous essayez de séparer les différents domaines où vous vous retrouvez en train d'écrire de grands blocs d'instructions if et d'appliquer des solutions à chacun de ces petits problèmes.

Regardez des techniques comme les règles dont il est question dans Refactoring pour trouver des moyens de diviser de grandes conditions en morceaux gérables - plusieurs classes avec une interface commune peuvent remplacer une instruction case, par exemple.

Quitter tôt est également d'une grande aide. Si vous avez des conditions d'erreur, éliminez-les au début de la fonction en lançant une exception ou en revenant au lieu de les laisser s'emboîter.

Si vous divisez vos conditions en fonctions de prédicat, il peut être plus facile de les suivre. De plus, si vous pouvez les obtenir sous une forme standard, il pourrait être possible de les obtenir dans une structure de données qui est construite dynamiquement, au lieu d'une codée en dur.

2
Dan Monego

Je ne pense pas que vous devriez définir autant de déclarations if-else. De mon point de vue, votre problème a plusieurs composants:

  • Il doit être asynchrone ou multithread, car vous avez plusieurs vaches avec des personnalités différentes, une configuration différente. Chaque vache se demande dans quelle direction aller avant son prochain mouvement. À mon avis, un code de synchronisation est un mauvais outil pour ce problème.

  • La configuration de l'arbre de décision change constamment. Cela dépend de la position de la vache réelle, du temps, du temps, du terrain, etc ... Au lieu de construire un arbre if-else complexe, je pense que nous devrions réduire le problème à un rose des vents = ou une fonction direction - poids: figure 1  figure 1 - direction - fonctions de pondération pour certaines règles

    La vache doit toujours aller dans la direction qui a le plus grand poids total. Ainsi, au lieu de construire un grand arbre de décision, vous pouvez ajouter un ensemble de règles (avec différentes directions - fonctions de poids) à chaque vache, et simplement traiter le résultat à chaque fois que vous demandez la direction. Vous pouvez reconfigurer ces règles par chaque changement de position, ou en passant le temps, ou vous pouvez ajouter ces détails en tant que paramètres, chaque règle devrait obtenir. Il s'agit d'une décision de mise en œuvre. La manière la plus simple d'obtenir une direction, d'ajouter une simple boucle de 0 ° à 360 ° avec pas de 1 °. Après cela, vous pouvez compter le poids total de chaque direction 360 et exécuter une fonction max () pour obtenir la bonne direction.

  • Vous n'avez pas nécessairement besoin d'un réseau de neurones pour cela, juste une classe pour chaque règle, une classe pour les vaches, peut-être pour le terrain, etc ... et une classe pour le scénario (par exemple 3 vaches avec des règles différentes & 1 terrain spécifique). figure2  figure 2 - nœuds de décision et connexions asynchrones de l'application cow

    • rouge pour la direction de la messagerie - carte de pondération à travers les règles
    • bleu pour les mises à jour d'orientation et de position après la prise de décision
    • vert pour les mises à jour d'entrée après la mise à jour de l'orientation et de la position
    • noir pour obtenir des entrées

    note: vous aurez probablement besoin d'un framework de messagerie pour implémenter quelque chose comme ça

    Donc, si faire des vaches d'apprentissage ne fait pas partie de votre problème, vous n'avez pas besoin d'un réseau neuronal ou d'algorithmes génétiques. Je ne suis pas un expert de l'IA, mais je suppose que si vous voulez adapter vos vaches aux vraies, alors vous pouvez le faire simplement avec un algorithme génétique et le bon ensemble de règles. Si je comprends bien, vous avez besoin d'une population de vaches avec des paramètres de règles aléatoires. Après cela, vous pouvez comparer le comportement des vaches réelles au comportement de votre population modèle et garder 10% qui marchent le plus près des vrais. Après cela, vous pouvez ajouter de nouvelles contraintes de configuration de règles à votre usine de vaches en fonction des 10% que vous avez conservés, et ajouter de nouvelles vaches aléatoires à la population, et ainsi de suite, jusqu'à ce que vous obteniez une vache modèle qui se comporte exactement comme les vraies ...

1
inf3rno

J'ajouterais que cela pourrait être le cas si vous avez vraiment des milliers de SI ... ALORS des règles que vous pourriez sur-spécifier. Pour ce que cela vaut, les discussions sur la modélisation des réseaux neuronaux auxquelles j'ai assisté commencent souvent par indiquer comment, avec "un simple ensemble de règles", elles peuvent générer un comportement assez complexe et raisonnablement adapté à la réalité (dans ces cas, de vrais neurones en action). Alors, êtes-vous sûr vous avez besoin de milliers de conditions? Je veux dire, en plus de 4-5 aspects de la météo, de l'emplacement des sources de nourriture, des événements soudains, de l'élevage et du terrain, allez-vous vraiment avoir beaucoup plus de variables? Bien sûr, si vous essayez de faire toutes les permutations possibles de la combinaison de ces conditions, vous pouvez facilement avoir plusieurs milliers de règles, mais ce n'est pas la bonne approche. Peut-être qu'une approche de style logique floue dans laquelle les divers facteurs introduisent un biais sur l'emplacement de chaque vache qui se combinent à une décision globale vous permettrait de le faire en beaucoup moins de règles.

Je suis également d'accord avec tout le monde pour dire que l'ensemble de règles doit être distinct du flux général de code, afin que vous puissiez facilement le modifier sans changer le programme. Vous pouvez même proposer des ensembles de règles concurrentes et voir comment ils se comportent par rapport aux données réelles sur les mouvements des vaches. Ça a l'air amusant.

0
Chelonian

Des systèmes experts ont été mentionnés, qui sont un domaine de l'IA. Pour en savoir un peu plus, lire Moteurs d'inférence peut vous aider. Une recherche Google pourrait être plus utile - écrire la DSL est la partie facile, vous pouvez le faire trivialement avec un analyseur comme Gold Parser. La partie difficile vient de la construction de votre arbre de décisions et de leur exécution efficace.

De nombreux systèmes médicaux utilisent déjà ces moteurs, par exemple le Royaume-Uni site Web NHS Direct .

Si vous êtes un .NET'er alors Infer.NET pourrait vous être utile.

0
Chris S

Depuis que vous regardez le mouvement de la vache, ils sont coincés dans une direction à 360 degrés (les vaches ne peuvent pas voler.) Vous avez également un taux de déplacement. Cela peut être défini comme un vecteur.

Maintenant, comment gérez-vous des choses comme la position du soleil, la pente de la colline, le bruit fort?

Chacun des degrés serait une variable signifiant le désir d'aller dans cette direction. Dites a twig s'accroche à droite de la vache à 90 degrés (en supposant que la vache fait face à 0 degrés). Le désir d'aller à droite descendra et le désir d'aller à 270 (gauche)) passer à travers tous les stimuli en ajoutant ou en soustrayant leur influence sur le désir des vaches d'aller dans une direction.Une fois tous les stimuli appliqués, la vache ira dans la direction du désir le plus élevé.

Vous pouvez également appliquer des gradients afin que les stimuli n'aient pas à être binaires. Par exemple, une colline n'est pas droite dans une direction. Peut-être que la vache est dans une vallée ou sur une route sur une colline si son plat était droit devant, à 45 * légère montée vers le haut à 90 * légère descente. À 180 * pente raide.

Vous pouvez ensuite ajuster le poids d'un événement et sa direction d'influence. Plutôt alors une liste de if thens, vous avez un test à la recherche du max. De plus, lorsque vous souhaitez ajouter un stimuli, vous pouvez simplement l'appliquer avant le test et vous n'avez pas à vous soucier d'ajouter de plus en plus de complexité.

Plutôt que de dire que la vache ira dans n'importe quelle direction à 360 degrés, il suffit de la décomposer en 36 directions. Chacun étant de 10 degrés

Plutôt que de dire que la vache ira dans n'importe quelle direction à 360 degrés, il suffit de la décomposer en 36 directions. Chacun étant de 10 degrés. Selon le degré de spécificité dont vous avez besoin.

0
Zero