Ich denke darüber nach, eine Anwendung zu erstellen, die im Kern aus Tausenden von if ... then ... else-Anweisungen bestehen würde. Der Zweck der Anwendung ist es, vorhersagen zu können, wie sich Kühe in einer Landschaft bewegen. Sie sind von Dingen wie Sonne, Wind, Nahrungsquelle, plötzlichen Ereignissen usw. betroffen.
Wie kann eine solche Anwendung verwaltet werden? Ich stelle mir vor, dass es nach ein paar hundert IF-Anweisungen so gut wie unvorhersehbar wäre, wie das Programm reagieren würde, und ein Debuggen, was zu einer bestimmten Reaktion führen würde, würde bedeuten, dass man jedes Mal den gesamten IF-Anweisungsbaum durchlaufen müsste.
Ich habe ein bisschen über Regel-Engines gelesen, aber ich sehe nicht, wie sie diese Komplexität umgehen würden.
Antworten:
Die logische Programmiersprache Prolog könnte das sein, wonach Sie suchen. Ihre Problemstellung ist für mich nicht spezifisch genug, um beurteilen zu können, ob sie gut passt, sie ähnelt jedoch eher Ihrer Aussage.
Ein Prolog-Programm besteht aus Fakten und Regeln, die angewendet werden. Hier ist eine einfache Beispielregel, die besagt: "Eine Kuh zieht an einen Ort, wenn die Kuh Hunger hat und am neuen Ort mehr Futter vorhanden ist als am alten Ort."
Alle Dinge in Großbuchstaben sind Variablen, Dinge, deren Wert Sie nicht kennen. Prolog versucht, Werte für diese Variablen zu finden, die alle Bedingungen erfüllen. Dieser Prozess wird mit einem leistungsstarken Algorithmus namens Unification durchgeführt, der das Herz von Prolog und ähnlichen logischen Programmierumgebungen bildet.
Zusätzlich zu den Regeln wird eine Datenbank mit Fakten bereitgestellt. Ein einfaches Beispiel, das mit den obigen Regeln funktioniert, könnte etwa so aussehen:
Beachten Sie, dass white_cow und pasture usw. nicht in Großbuchstaben geschrieben sind. Sie sind keine Variablen, sie sind Atome.
Schließlich stellen Sie eine Abfrage und fragen, was passieren wird.
Bei der ersten Abfrage wird gefragt, wohin sich die weiße Kuh bewegen soll. In Anbetracht der obigen Regeln und Fakten lautet die Antwort Nein. Dies kann je nach Wunsch als "Ich weiß nicht" oder "Es bewegt sich nicht" interpretiert werden.
Die zweite Abfrage fragt, wohin sich die schwarze Kuh bewegt. Es bewegt sich auf die Weide, um zu essen.
In der letzten Abfrage wird gefragt, wohin sich alle Kühe bewegen. Als Ergebnis erhalten Sie alles Mögliche (Kuh, Ziel), das Sinn ergibt. In diesem Fall bewegt sich der schwarze Bulle erwartungsgemäß auf die Weide. Der wütende Bulle hat jedoch zwei Möglichkeiten, die den Regeln entsprechen. Er kann entweder auf die Weide oder in die Scheune ziehen.
Hinweis: Es ist Jahre her, dass ich Prolog das letzte Mal geschrieben habe. Möglicherweise sind alle Beispiele syntaktisch nicht gültig, aber die Idee sollte stimmen.
quelle
Zur Behebung des if-Web- Problems können Sie eine Regelengine erstellen, in der jede einzelne Regel unabhängig codiert wird. Eine weitere Verfeinerung hierfür wäre das Erstellen einer domänenspezifischen Sprache (DSL), um die Regeln zu erstellen. Ein DSL allein verschiebt das Problem jedoch nur von einer Codebasis (Haupt) zu einer anderen (DSL). Ohne Struktur wird das DSL nicht besser abschneiden als die Muttersprache (Java, C # usw.), daher werden wir darauf zurückkommen, nachdem wir einen verbesserten strukturellen Ansatz gefunden haben.
Das grundlegende Problem ist, dass Sie ein Modellierungsproblem haben. Wann immer Sie auf solche kombinatorischen Situationen stoßen, ist dies ein klares Zeichen dafür, dass Ihre Modellabstraktion, die die Situation beschreibt, zu grob ist. Sie kombinieren höchstwahrscheinlich Elemente, die zu verschiedenen Modellen gehören sollen, in einer einzigen Entität.
Wenn Sie Ihr Modell immer wieder auflösen, wird sich dieser kombinatorische Effekt möglicherweise vollständig auflösen. Auf diesem Weg kann es jedoch leicht passieren, dass Sie sich in Ihrem Design verlieren und ein noch größeres Durcheinander schaffen. Perfektionismus ist hier nicht unbedingt Ihr Freund.
Finite State Machines und Rule Engines sind nur ein Beispiel dafür, wie dieses Problem aufgeschlüsselt und besser beherrschbar gemacht werden kann. Die Hauptidee dabei ist, dass ein kombinatorisches Problem wie dieses häufig vermieden werden kann, indem ein Entwurf erstellt und in verschachtelten Abstraktionsebenen ad-nauseam wiederholt wird, bis die Leistung Ihres Systems zufriedenstellend ist. Ähnlich wie Fraktale verwendet werden, um komplizierte Muster zu erstellen. Die Regeln bleiben gleich, egal ob Sie Ihr System mit einem Mikroskop oder aus der Vogelperspektive betrachten.
Beispiel für die Anwendung auf Ihre Domain.
Sie versuchen zu modellieren, wie sich Kühe durch ein Gelände bewegen. Obwohl es Ihrer Frage an Details mangelt, würde ich vermuten, dass Ihre große Menge an Ifs Entscheidungsfragmente wie enthält,
if cow.isStanding then cow.canRun = true
aber Sie geraten ins Stocken, wenn Sie beispielsweise Geländedetails hinzufügen. Für jede Aktion, die Sie durchführen möchten, müssen Sie alle Aspekte überprüfen, die Ihnen einfallen, und diese Überprüfungen für die nächste mögliche Aktion wiederholen.Zuerst benötigen wir unser wiederholbares Design, das in diesem Fall ein FSM ist, um die sich ändernden Zustände der Simulation zu modellieren. Das erste , was ich tun würde , ist eine Referenz FSM zu implementieren, einen prägenden Zustand Schnittstelle, eine Übergangsschnittstelle und vielleicht einen Übergang KontextDies kann gemeinsame Informationen enthalten, die den beiden anderen zur Verfügung gestellt werden sollen. Eine grundlegende FSM-Implementierung wechselt unabhängig vom Kontext von einem Übergang zu einem anderen. Hier kommt eine Regelengine ins Spiel. Die Regelengine kapselt die Bedingungen, die erfüllt sein müssen, damit der Übergang stattfinden kann. Eine Regel-Engine kann hier so einfach sein wie eine Liste von Regeln, von denen jede eine Auswertungsfunktion hat, die einen Booleschen Wert zurückgibt. Um zu überprüfen, ob ein Übergang stattfinden soll, iterieren Sie die Liste der Regeln, und wenn eine davon als falsch bewertet wird, findet der Übergang nicht statt. Der Übergang selbst enthält den Verhaltenscode zum Ändern des aktuellen Status des FSM (und anderer möglicher Aufgaben).
Wenn ich jetzt beginne, die Simulation als eine einzelne große FSM auf GOD-Ebene zu implementieren, habe ich am Ende VIELE mögliche Zustände, Übergänge usw. Das If-else-Durcheinander sieht aus, als wäre es behoben, aber es ist eigentlich nur verteilt: Jedes IF ist Jetzt eine Regel, die einen Test mit einer bestimmten Information des Kontexts durchführt (die zu diesem Zeitpunkt so ziemlich alles enthält) und jeder WENN-Körper sich irgendwo im Übergangscode befindet.
Geben Sie die Aufschlüsselung der Fraktale ein: Der erste Schritt wäre, eine FSM für jede Kuh zu erstellen, bei der die Zustände die internen Zustände der Kuh sind (Stehen, Laufen, Gehen, Weiden usw.) und die Übergänge zwischen ihnen von der Umgebung beeinflusst würden. Es ist möglich, dass das Diagramm nicht vollständig ist, zum Beispiel, dass die Beweidung nur im stehenden Zustand zugänglich ist, und dass jeder andere Übergang nicht zulässig ist, weil er einfach nicht im Modell vorhanden ist. Hier trennen Sie die Daten effektiv in zwei verschiedene Modelle, die Kuh und das Gelände. Jedes mit eigenen Eigenschaften. Mit dieser Aufschlüsselung können Sie Ihr gesamtes Motordesign vereinfachen. Anstelle einer einzigen Regelengine, die über alles entscheidet, stehen jetzt mehrere einfachere Regelengines (eine für jeden Übergang) zur Verfügung, die über ganz bestimmte Details entscheiden.
Da ich denselben Code für die FSM wiederverwende, handelt es sich im Grunde genommen um eine Konfiguration der FSM. Erinnerst du dich, als wir DSL's erwähnt haben? Hier kann DSL viel Gutes bewirken, wenn Sie viele Regeln und Übergänge schreiben müssen.
Tiefer gehen
Jetzt muss GOTT nicht mehr mit der ganzen Komplexität im Umgang mit den inneren Zuständen der Kuh fertig werden, sondern wir können sie weiter vorantreiben. Zum Beispiel ist die Verwaltung des Geländes immer noch sehr komplex. Hier entscheiden Sie, wo die Aufteilung ausreicht. Wenn Sie beispielsweise in Ihrem GOTT die Geländedynamik (langes Gras, Schlamm, trockener Schlamm, kurzes Gras usw.) verwalten, können wir dasselbe Muster wiederholen. Nichts hindert Sie daran, eine solche Logik in das Gelände selbst einzubetten, indem Sie alle Geländezustände (langes Gras, kurzes Gras, matschig, trocken usw.) in ein neues Gelände-FSM mit Übergängen zwischen den Zuständen und möglicherweise einfachen Regeln extrahieren. Um zum Beispiel in den schlammigen Zustand zu gelangen, sollte die Regel-Engine den Kontext prüfen, um Flüssigkeiten zu finden, andernfalls ist dies nicht möglich. Jetzt wurde GOTT noch einfacher.
Sie können das FSM-System vervollständigen, indem Sie sie autonom machen und ihnen jeweils einen Thread zuweisen. Dieser letzte Schritt ist nicht erforderlich, ermöglicht es Ihnen jedoch, die Interaktion des Systems dynamisch zu ändern, indem Sie die Art und Weise anpassen, in der Sie Ihre Entscheidungen delegieren (einen speziellen FSM starten oder einfach einen festgelegten Status zurückgeben).
Erinnern Sie sich, wie wir erwähnt haben, dass Übergänge auch "andere mögliche Aufgaben" erfüllen können? Lassen Sie uns das untersuchen, indem wir die Möglichkeit hinzufügen, dass verschiedene Modelle (FSM) miteinander kommunizieren. Sie können eine Reihe von Ereignissen definieren und jedem FSM erlauben, Listener für diese Ereignisse zu registrieren. Betritt beispielsweise eine Kuh ein Geländefeld, kann das Feld Listener für Übergangsänderungen registrieren. Hier wird es etwas knifflig, da jeder FSM auf sehr hohem Niveau implementiert wird, ohne die spezifische Domäne zu kennen, die er besitzt. Sie können dies jedoch erreichen, indem die Kuh eine Liste von Ereignissen veröffentlicht und die Zelle registriert, wenn sie Ereignisse sieht, auf die sie reagieren kann. Eine gute Hierarchie der Veranstaltungsfamilie ist hier eine gute Investition.
Sie können noch tiefer gehen, indem Sie den Nährstoffgehalt und den Wachstumszyklus von Gras modellieren. Mit ... Sie haben es erraten ... einem Gras-FSM, das in das Modell des Terrain Patch eingebettet ist.
Wenn Sie die Idee weit genug treiben, hat GOTT sehr wenig zu tun, da alle Aspekte so gut wie selbst verwaltet werden und Zeit für göttlichere Dinge frei wird.
Rekapitulieren
Wie oben erwähnt, ist der FSM hier nicht die Lösung, sondern nur ein Mittel, um zu veranschaulichen, dass die Lösung für ein solches Problem nicht im Code per say zu finden ist, sondern wie Sie Ihr Problem modellieren. Es gibt höchstwahrscheinlich andere Lösungen, die möglich und höchstwahrscheinlich viel besser sind als mein FSM-Vorschlag. Der "Fraktal" -Ansatz bleibt jedoch ein guter Weg, um diese Schwierigkeit zu bewältigen. Bei korrekter Ausführung können Sie tiefere Ebenen dynamisch zuweisen, wenn es darauf ankommt, und einfachere Modelle angeben, wenn es darauf ankommt. Sie können Änderungen in die Warteschlange stellen und anwenden, wenn Ressourcen verfügbarer werden. In einer Aktionssequenz ist es möglicherweise nicht so wichtig, die Nährstoffübertragung von der Kuh auf die Rasenfläche zu berechnen. Sie können diese Übergänge jedoch aufzeichnen und die Änderungen zu einem späteren Zeitpunkt anwenden oder sie mit einer fundierten Vermutung nur annähern, indem Sie einfach die Regelengines ersetzen oder die FSM-Implementierung insgesamt durch eine einfachere, naive Version für die Elemente ersetzen, die sich nicht im direkten Bereich von befinden Interesse (diese Kuh am anderen Ende des Feldes), damit detailliertere Interaktionen den Fokus und einen größeren Anteil an Ressourcen erhalten. All dies, ohne jemals das System als Ganzes zu überdenken; Da jedes Teil gut isoliert ist, ist es einfacher, ein Drop-In-Ersatzelement zu erstellen, das die Tiefe Ihres Modells begrenzt oder erweitert. Durch die Verwendung eines Standarddesigns können Sie darauf aufbauen und die Investitionen in Ad-hoc-Tools wie DSL maximieren, um Regeln oder ein Standardvokabular für Ereignisse zu definieren. Beginnen Sie dabei erneut auf sehr hohem Niveau und erweitern Sie diese nach Bedarf. Da jedes Teil gut isoliert ist, ist es einfacher, ein Drop-In-Ersatzelement zu erstellen, das die Tiefe Ihres Modells begrenzt oder erweitert. Durch die Verwendung eines Standarddesigns können Sie darauf aufbauen und die Investitionen in Ad-hoc-Tools wie DSL maximieren, um Regeln oder ein Standardvokabular für Ereignisse zu definieren. Beginnen Sie dabei erneut auf sehr hohem Niveau und erweitern Sie diese nach Bedarf. Da jedes Teil gut isoliert ist, ist es einfacher, ein Drop-In-Ersatzelement zu erstellen, das die Tiefe Ihres Modells begrenzt oder erweitert. Durch die Verwendung eines Standarddesigns können Sie darauf aufbauen und die Investitionen in Ad-hoc-Tools wie DSL maximieren, um Regeln oder ein Standardvokabular für Ereignisse zu definieren. Beginnen Sie dabei erneut auf sehr hohem Niveau und erweitern Sie diese nach Bedarf.
Ich würde ein Codebeispiel angeben, aber das ist alles, was ich mir leisten kann, um es jetzt zu tun.
quelle
Es hört sich so an, als ob all diese bedingten Anweisungen, von denen Sie sprechen, Daten sein sollten, die Ihr Programm konfigurieren, und nicht Teil Ihres Programms. Wenn Sie sie so behandeln können, können Sie die Funktionsweise Ihres Programms ändern, indem Sie einfach die Konfiguration ändern, anstatt den Code jedes Mal ändern und neu kompilieren zu müssen, wenn Sie Ihr Modell verbessern möchten.
Abhängig von der Art Ihres Problems gibt es viele verschiedene Möglichkeiten, die reale Welt zu modellieren. Ihre verschiedenen Bedingungen können zu Regeln oder Einschränkungen werden, die auf die Simulation angewendet werden. Anstatt Code zu haben, der so aussieht:
Sie können stattdessen Code haben, der wie folgt aussieht:
Wenn Sie ein lineares Programm entwickeln können, das das Verhalten von Kühen bei einer Reihe von Eingaben modelliert, wird jede Einschränkung möglicherweise zu einer Linie in einem Gleichungssystem. Sie können das dann in ein Markov-Modell umwandeln, das Sie iterieren können.
Es ist schwer zu sagen, was der richtige Ansatz für Ihre Situation ist, aber ich denke, Sie werden es viel einfacher haben, wenn Sie Ihre Einschränkungen als Eingaben in Ihr Programm und nicht als Code betrachten.
quelle
Niemand hat das erwähnt, also dachte ich, ich würde es explizit sagen:
Tausende von "If .. Then .. Else" -Regeln sind ein Zeichen für eine schlecht gestaltete Anwendung.
Obwohl die domänenspezifische Datendarstellung wie diese Regeln aussehen könnte, sind Sie sich absolut sicher, dass Ihre Implementierung der domänenspezifischen Darstellung ähneln sollte?
quelle
Bitte verwenden Sie Software / Computersprachen, die für die Aufgabe geeignet sind. Matlab wird sehr oft verwendet, um komplexe Systeme zu modellieren, bei denen tatsächlich Tausende von Bedingungen vorliegen können. Nicht if / then / else-Klauseln verwenden, sondern durch numerische Analyse. R ist eine Open-Source-Computersprache, die mit Tools und Paketen gefüllt ist, um dasselbe zu tun. Das bedeutet aber auch, dass Sie Ihr Modell mathematischer umformulieren müssen, damit Sie sowohl die Haupteinflüsse als auch die Wechselwirkungen zwischen Einflüssen in Modelle einbeziehen können.
Wenn Sie dies noch nicht getan haben, besuchen Sie bitte einen Kurs über Modellierung und Simulation. Das Letzte, was Sie tun sollten, ist zu überlegen, ein solches Modell zu schreiben, wenn - dann - anders. Wir haben Monte-Carlo-Markov-Ketten, Support-Vektor-Maschinen, neuronale Netze, latente Variablenanalyse, ... Bitte werfen Sie sich nicht 100 Jahre zurück, indem Sie den Reichtum an verfügbaren Modellierungswerkzeugen ignorieren.
quelle
Regel-Engines könnten hilfreich sein, da es bei so vielen if / then-Regeln hilfreich sein könnte, sie alle an einem Ort außerhalb des Programms abzulegen, wo Benutzer sie bearbeiten können, ohne dass sie eine Programmiersprache benötigen. Möglicherweise sind auch Visualisierungstools verfügbar.
Sie können sich auch logische Programmierlösungen (wie Prolog) ansehen. Sie können die Liste der if / then-Anweisungen schnell ändern und z. B. prüfen lassen, ob eine Kombination von Eingaben zu bestimmten Ergebnissen führen würde usw. Es kann auch vorkommen, dass die Prädikatenlogik erster Ordnung sauberer ist als Prozedurcode (oder als objektorientierter Code).
quelle
Mir ist plötzlich aufgefallen:
Sie müssen einen Entscheidungslernbaum (ID3-Algorithmus) verwenden.
Es ist sehr wahrscheinlich, dass jemand es in Ihrer Sprache implementiert hat. Wenn nicht, könnten Sie eine vorhandene Bibliothek portieren
quelle
Dies ist eher eine Community-Wiki-Antwort, in der die verschiedenen Modellierungswerkzeuge zusammengefasst sind, die von anderen Antworten vorgeschlagen wurden. Ich habe gerade zusätzliche Links zu Ressourcen hinzugefügt.
Ich glaube nicht, dass Sie noch einmal betonen müssen, dass Sie einen anderen Ansatz für Tausende von hartcodierten if / else-Anweisungen verwenden sollten.
quelle
Jede große Anwendung enthält Tausende von
if-then-else
Anweisungen, andere Ablaufsteuerungen nicht eingerechnet, und diese Anwendungen werden trotz ihrer Komplexität weiterhin getestet und gewartet.Auch die Anzahl der Anweisungen macht den Fluss nicht unvorhersehbar . Asynchrone Programmierung. Wenn Sie deterministische Algorithmen synchron verwenden, ist das Verhalten jedes Mal zu 100% vorhersehbar.
Sie sollten wahrscheinlich besser erklären, was Sie mit Stack Overflow oder Code Review tun möchten, damit die Leute Ihnen die genauen Refactoring-Techniken vorschlagen können . Möglicherweise möchten Sie auch genauere Fragen stellen, z. B. "Wie vermeide ich das Verschachteln von zu vielen
if
Anweisungen <mit einem bestimmten Code>".quelle
if
Anweisungen werden bestenfalls schnell unhandlich, sodass ein besserer Ansatz erforderlich ist.Machen Sie Ihre Anwendung übersichtlich, indem Sie sie gut gestalten. Entwerfen Sie Ihre Anwendung, indem Sie die verschiedenen Geschäftslogiken in separate Klassen / Module aufteilen. Schreiben Sie Komponententests, die jede dieser Klassen / Module einzeln testen. Dies ist von entscheidender Bedeutung und hilft Ihnen dabei, sicherzustellen, dass die Geschäftslogik wie erwartet implementiert wird.
quelle
Es wird wahrscheinlich keinen einzigen Weg geben, um Ihr Problem zu lösen, aber Sie können die Komplexität Stück für Stück bewältigen, wenn Sie versuchen, verschiedene Bereiche zu trennen, in denen Sie große Blöcke von if-Anweisungen schreiben und Lösungen anwenden zu jedem dieser kleineren Probleme.
Sehen Sie sich Techniken wie die in Refactoring beschriebenen an, um herauszufinden, wie Sie große Bedingungen in überschaubare Teile aufteilen können. Beispielsweise können mehrere Klassen mit einer gemeinsamen Schnittstelle eine case-Anweisung ersetzen.
Ein früher Ausstieg ist auch eine große Hilfe. Wenn Sie Fehlerbedingungen haben, beseitigen Sie diese am Anfang der Funktion, indem Sie eine Ausnahme auslösen oder zurückkehren, anstatt sie verschachteln zu lassen.
Wenn Sie Ihre Bedingungen in Prädikatfunktionen aufteilen, ist es möglicherweise einfacher, den Überblick zu behalten. Wenn Sie sie in ein Standardformular einbinden können, können Sie sie möglicherweise auch in eine dynamisch erstellte Datenstruktur einbinden, anstatt in eine fest codierte.
quelle
Ich würde vorschlagen, dass Sie eine Regel-Engine verwenden. Im Falle von Java kann jBPM oder Oracle BPM nützlich sein. Mit Rules Engines können Sie die Anwendung grundsätzlich über XML konfigurieren.
quelle
Das Problem ist nicht gut durch "Regeln" gelöst, sei es durch "Wenn-Dann" -Prozedurcode oder durch die zahlreichen Regeln, die für Geschäftsanwendungen entwickelt wurden. Maschinelles Lernen bietet eine Reihe von Mechanismen zur Modellierung solcher Szenarien.
Grundsätzlich muss man ein Schema für die diskrete Darstellung der Faktoren (z. B. Sonne, Wind, Nahrungsquelle, plötzliche Ereignisse usw.) formulieren, die das "System" beeinflussen (dh Kühe auf einer Weide). Ungeachtet der fehlgeleiteten Überzeugung, dass man eine echte funktionale Repräsentation erstellen kann, ist kein Computer in der realen Welt (einschließlich des menschlichen Nervensystems) echtwertbasiert oder berechnet basierend auf echten Werten.
Sobald Sie Ihre numerische Darstellung für die relevanten Faktoren haben, können Sie eines von mehreren mathematischen Modellen konstruieren. Ich würde einen zweigliedrigen Graphen vorschlagen, bei dem eine Gruppe von Knoten Kühe und die andere eine Einheitsweidefläche darstellt. Eine Kuh nimmt in jedem Fall eine bestimmte Weidefläche ein. Für jede Kuh existiert dann ein Nutzwert, der der aktuellen und allen anderen Weideeinheiten zugeordnet ist. Wenn das Modell voraussetzt, dass die Kuh versucht, den Nutzwert ihrer Weideeinheit zu optimieren (was auch immer dies für die Kuh bedeutet), bewegen sich die Kühe von Einheit zu Einheit, um eine Optimierung zu erreichen.
Ein zellularer Automat eignet sich gut zum Ausführen des Modells. Die zugrunde liegende Mathematik in der real geschätzten mathematischen Welt, die die Kuhbewegung motiviert, ist ein Feldgradientenmodell. Kühe bewegen sich von Positionen mit einem wahrgenommenen niedrigeren Nutzwert zu Positionen mit einem wahrgenommenen höheren Nutzwert.
Wenn man Umweltveränderungen in das System einspeist, bewegt es sich nicht zu einer stationären Lösung der Kuhpositionierung. Es wird auch ein Modell werden, auf das Aspekte der Spieltheorie angewendet werden könnten; nicht, dass dies diesem Fall notwendigerweise viel hinzufügen würde.
Der Vorteil hierbei ist, dass Schlachtkühe oder die Gewinnung neuer Kühe problemlos verwaltet werden können, indem "Kuh" -Zellen vom zweigliedrigen Graphen abgezogen und hinzugefügt werden, während das Modell ausgeführt wird.
quelle
Ich denke nicht, dass Sie so viele if-else-Anweisungen definieren sollten. Aus meiner Sicht hat Ihr Problem mehrere Komponenten:
Es sollte asynchron oder multithreaded sein, da Sie mehrere Kühe mit unterschiedlichen Persönlichkeiten und unterschiedlicher Konfiguration haben. Jede Kuh fragt sich, in welche Richtung sie gehen soll, bevor sie weitergeht. Meiner Meinung nach ist ein Synchronisierungscode ein schlechtes Werkzeug für dieses Problem.
Die Konfiguration des Entscheidungsbaums ändert sich ständig. Es hängt von der Position der tatsächlichen Kuh, dem Wetter, der Zeit, dem Gelände usw. ab. Anstatt einen komplexen If-else-Baum zu bauen, sollten wir das Problem meiner Meinung nach auf eine Windrose oder eine Richtungsgewichtsfunktion reduzieren : Abbildung 1 - Richtungsgewichtungsfunktionen für einige Regeln
Die Kuh sollte immer in die Richtung gehen, die das größte Summengewicht hat. Anstatt also einen großen Entscheidungsbaum zu erstellen, können Sie jeder Kuh ein Regelwerk (mit unterschiedlichen Richtungs- und Gewichtsfunktionen) hinzufügen und das Ergebnis bei jeder Richtungsanfrage einfach verarbeiten. Sie können diese Regeln durch jede Positionsänderung oder durch Verstreichen der Zeit neu konfigurieren oder diese Details als Parameter hinzufügen, die jede Regel erhalten sollte. Es ist eine Umsetzungsentscheidung. Der einfachste Weg, eine Richtung zu bestimmen, ist das Hinzufügen einer einfachen Schleife von 0 ° bis 360 ° mit 1 ° -Schritt. Danach können Sie das Summengewicht jeder 360-Richtung zählen und eine max () -Funktion durchlaufen, um die richtige Richtung zu ermitteln.
Sie brauchen dazu nicht unbedingt ein neuronales Netz, nur eine Klasse für jede Regel, eine Klasse für die Kühe, vielleicht für das Gelände usw. und eine Klasse für das Szenario (zum Beispiel 3 Kühe mit unterschiedlichen Regeln & 1 bestimmtes Gelände). Abbildung 2 - Asynchrone Entscheidungsknoten und -verbindungen der Cow App
Hinweis: Sie benötigen wahrscheinlich ein Messaging-Framework, um so etwas zu implementieren
Wenn das Bilden von Lernkühen nicht zu Ihrem Problem gehört, benötigen Sie weder ein neuronales Netzwerk noch genetische Algorithmen. Ich bin kein Experte für KI, aber wenn Sie Ihre Kühe an die realen anpassen möchten, können Sie dies einfach mit einem genetischen Algorithmus und den richtigen Regeln tun. Wenn ich es richtig verstehe, brauchen Sie eine Population von Kühen mit zufälligen Regeleinstellungen. Danach können Sie das Verhalten echter Kühe mit dem Verhalten Ihrer Modellpopulation vergleichen und 10% beibehalten, die dem tatsächlichen Verhalten am nächsten kommen. Danach können Sie Ihrer Kuhfabrik neue Regelkonfigurationsbeschränkungen hinzufügen, basierend auf den 10%, die Sie behalten haben, und der Population neue zufällige Kühe hinzufügen, usw., bis Sie eine Modellkuh erhalten, die sich genau wie die echten verhält ...
quelle
Ich würde hinzufügen, dass es der Fall sein könnte, wenn Sie wirklich Tausende von WENN ... DANN-Regeln haben, könnten Sie eine Überspezifikation haben. Für das, was es wert ist, beginnen Gespräche über die Modellierung neuronaler Netze, an denen ich oft teilgenommen habe, mit der Feststellung, wie sie mit "einfachen Regeln" ein ziemlich komplexes und einigermaßen realitätsnahes Verhalten (von in Aktion befindlichen echten Neuronen) erzeugen können. Also, bist du dir sicher?Sie brauchen Tausende von Bedingungen? Ich meine, abgesehen von 4-5 Aspekten des Wetters, der Lage der Nahrungsquellen, plötzlichen Ereignissen, Hüten und des Geländes, werden Sie wirklich viel mehr Variablen haben? Sicher, wenn Sie versuchen würden, alle möglichen Kombinationen dieser Bedingungen zu erstellen, könnten Sie leicht viele tausend Regeln haben, aber das ist nicht der richtige Ansatz. Vielleicht würde ein Ansatz im Fuzzy-Logik-Stil, bei dem die verschiedenen Faktoren eine Verzerrung des Standorts jeder Kuh bewirken und zu einer Gesamtentscheidung führen, es Ihnen ermöglichen, dies mit weitaus weniger Regeln zu tun.
Ich stimme auch allen anderen zu, dass der Regelsatz vom allgemeinen Code-Fluss getrennt sein sollte, damit Sie ihn leicht optimieren können, ohne das Programm zu ändern. Sie könnten sogar mit konkurrierenden Regelsätzen aufwarten und sehen, wie diese sich auf die tatsächlichen Bewegungsdaten der Kuh auswirken. Klingt lustig.
quelle
Expertensysteme wurden erwähnt, die einen Bereich der KI darstellen. Wenn Sie diese näher erläutern möchten, hilft Ihnen möglicherweise das Nachlesen von Inference Engines . Eine Google-Suche könnte nützlicher sein - das Schreiben der DSL ist der einfache Teil, Sie könnten dies trivial mit einem Parser wie Gold Parser tun. Der schwierige Teil besteht darin, Ihren Entscheidungsbaum aufzubauen und effizient durchzuarbeiten.
Viele medizinische Systeme verwenden diese Motoren bereits, zum Beispiel die britische NHS Direct-Website .
Wenn Sie ein .NET'er sind, könnte Infer.NET für Sie nützlich sein.
quelle
Da Sie die Bewegung der Kuh betrachten, stecken sie in 360-Grad-Richtung fest (Kühe können nicht fliegen.) Sie haben auch eine Rate, mit der Sie reisen. Dies kann als Vektor definiert werden.
Wie geht man nun mit Dingen wie Sonnenstand, Hanglage, lautem Lärm um?
Jeder der Grade wäre eine Variable, die den Wunsch anzeigt, in diese Richtung zu gehen. Angenommen, ein Zweig schnappt bei 90 Grad rechts von der Kuh (vorausgesetzt, die Kuh steht vor 0 Grad). Der Wunsch, nach rechts zu gehen, wird sinken und der Wunsch, nach 270 (links) zu gehen, wird steigen. Gehen Sie alle Reize durch, indem Sie ihren Einfluss auf den Wunsch der Kühe, in eine Richtung zu gehen, addieren oder abziehen. Sobald alle Reize angewendet sind, geht die Kuh in die Richtung des höchsten Verlangens.
Sie können auch Farbverläufe anwenden, damit die Stimuli nicht binär sein müssen. Zum Beispiel ist ein Hügel nicht gerade in eine Richtung. Vielleicht ist die Kuh in einem Tal oder auf einer Straße auf einem Hügel, wo sie gerade aus ist, bei 45 * leicht bergauf bei 90 * leicht bergab. Bei 180 * steil bergauf.
Sie können dann das Gewicht eines Ereignisses und seine Einflussrichtung anpassen. Anstelle einer Liste von if thens haben Sie einen Test, der nach der max. Auch wenn Sie einen Stimulus hinzufügen möchten, können Sie ihn einfach vor dem Test anwenden und müssen sich nicht mit dem Hinzufügen von immer mehr Komplexität befassen.
Anstatt zu sagen, dass die Kuh in eine beliebige 360-Richtung geht, teilen wir sie einfach in 36 Richtungen auf. Jeweils 10 Grad
Anstatt zu sagen, dass die Kuh in eine beliebige 360-Richtung geht, teilen wir sie einfach in 36 Richtungen auf. Jeweils 10 Grad. Je nachdem, wie spezifisch Sie sein müssen.
quelle
Verwenden Sie OOP. Wie wäre es, wenn Sie eine Reihe von Klassen erstellen, die mit den Basisbedingungen umgehen und zufällige Methoden ausführen, um zu simulieren, was Sie tun.
Bitten Sie einen Programmierer um Hilfe.
quelle
COW_METHODS
scheint nichts weiter zu sein als eine Sammlung lose verwandter Methoden. Wo ist die Trennung der Anliegen? In Bezug auf die Frage, wie hilft dies dem Fragesteller?