Как можно управлять тысячами правил IF… THEN… ELSE?

214

Я рассматриваю возможность создания приложения, которое по своей сути будет состоять из тысяч операторов if ... then ... else. Цель приложения - уметь предсказывать, как коровы передвигаются в любом ландшафте. На них влияют такие вещи, как солнце, ветер, источник пищи, внезапные события и т. Д.

Как можно управлять таким приложением? Я полагаю, что после нескольких сотен IF-операторов было бы так же непредсказуемо, как отреагирует программа, а отладка того, что привело к определенной реакции, означала бы, что каждый раз придется обходить все дерево IF-операторов.

Я читал немного о правилах двигателей, но я не вижу, как они обойдут эту сложность.

David
источник
22
Вам нужно взглянуть на программирование DSL: en.wikipedia.org/wiki/Domain-specific_language Далее вы также можете создать движок метаданных, управляемый данными. Например, вы можете генерировать модели из данных (например, интеллектуальный анализ данных KDD)
Darknight
14
Google для "экспертной системы" и "сеть"; удачи.
Стивен А. Лоу
9
Переместите жестко запрограммированные операторы if / then из исходного кода во внешние данные, которые управляют имитацией.
Квеббл
6
Я поместил бы некоторые значения в текстовый файл и использовал бы цикл, чтобы пройти через HashMap, содержащий имена.
Джеймс П.
2
Дэвид - на вопросы программистов преобразуются в CW, когда размещено более 15 ответов. Мы не можем контролировать, кто публикует 16-й ответ.
ChrisF

Ответы:

73

Язык логического программирования Prolog может быть тем, что вы ищете. Ваше заявление о проблеме не достаточно конкретное, чтобы я мог оценить, подходит ли оно вам, но оно скорее похоже на то, что вы говорите.

Программа Prolog состоит из применяемых фактов и правил. Вот простое примерное правило, которое гласит: «Корова переезжает в другое место, если она голодна и в новом месте больше еды, чем в старом»:

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

Все, что написано заглавными буквами, - это переменные, вещи, о которых вы не знаете. Пролог пытается найти значения для этих переменных, которые удовлетворяют всем условиям. Этот процесс выполняется с помощью мощного алгоритма, называемого унификацией, который является сердцем Prolog и подобных логических сред программирования.

В дополнение к правилам предоставляется база данных фактов. Простой пример, который работает с правилами выше, может быть что-то вроде:

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).

Обратите внимание, что white_cow, пастбище и т. Д. Не написаны заглавными буквами. Они не переменные, они атомы.

Наконец, вы делаете запрос и спрашиваете, что произойдет.

?- 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

Первый запрос спрашивает, куда двинется белая корова. Учитывая приведенные выше правила и факты, ответ - нет. Это можно интерпретировать как «я не знаю» или «оно не двигается» в зависимости от того, что вы хотите.

Второй запрос спрашивает, куда движется черная корова. Он движется на пастбище, чтобы поесть.

Последний запрос спрашивает, куда движутся все коровы. В результате вы получаете все возможные варианты (Корова, Назначение), которые имеют смысл. В этом случае черный бык движется на пастбище, как и ожидалось. Однако у злого быка есть два варианта, которые удовлетворяют правилам: он может либо перебраться на пастбище, либо в сарай.

Примечание. Прошло много лет с тех пор, как я в последний раз писал Пролог, все примеры могут быть синтаксически недействительными, но идея должна быть правильной.

оборота exDM69
источник
10
-1: Я не думаю, что Пролог может когда-нибудь быть правильным ответом. Да, может быть легко получить правила if-else в Прологе. Но, безусловно, вам придется сделать что-то еще. И независимо от того, что это (IO; GUI, веб-разработка, ...), это будет проблемой с Прологом.
Мартин Тома
4
Проверьте learnprolognow.com. А встраивание пролога в другой язык намного проще, чем раньше
Захари К
@ZacharyK: ссылка не работает.
RenniePet
@MartinThoma: можешь ли ты объяснить свой комментарий? Основными проблемами с Прологом ИМХО являются отсутствие: 1. декларативного способа управления поиском и 2. набора текста. Но если ваше приложение не сильно зависит от этих двух, то я априори не вижу проблемы с использованием Пролога здесь
SN
139

Решая проблему if web, вы можете создать механизм правил, где каждое конкретное правило кодируется независимо. Дополнительным уточнением для этого было бы создание предметно-ориентированного языка (DSL) для создания правил, однако один только DSL перемещает проблему только из одной базы кода (основной) в другую (DSL). Без структуры DSL не будет лучше, чем родной язык (Java, C # и т. Д.), Поэтому мы вернемся к нему после того, как найдем улучшенный структурный подход.

Основная проблема заключается в том, что у вас есть проблема с моделированием. Всякий раз, когда вы сталкиваетесь с комбинаторными ситуациями, подобными этой, это явный признак того, что ваша абстракция модели, которая описывает ситуацию, является слишком грубой. Скорее всего, вы объединяете элементы, которые должны принадлежать разным моделям, в одну сущность.

Если вы продолжаете ломать свою модель, вы в конечном итоге полностью утратите этот комбинаторный эффект. Однако, выбирая этот путь, легко потеряться в своем дизайне, создавая еще большую неразбериху, перфекционизм здесь не обязательно ваш друг.

Конечные автоматы и механизмы правил являются лишь примером того, как эту проблему можно решить и сделать более управляемой. Основная идея здесь заключается в том, что хороший способ избавиться от такой комбинаторной проблемы, как эта, часто состоит в том, чтобы создать дизайн и повторять его ad-nauseam на вложенных уровнях абстракции до тех пор, пока ваша система не будет работать удовлетворительно. Сродни тому, как фракталы используются для создания сложных паттернов. Правила остаются неизменными, независимо от того, смотрите ли вы на свою систему под микроскопом или с высоты птичьего полета.

Пример применения этого в вашем домене.

Вы пытаетесь смоделировать, как коровы движутся по местности. Хотя в вашем вопросе нет подробностей, я бы предположил, что большое количество ifs включает фрагмент решения, например, if cow.isStanding then cow.canRun = trueно вы застряли, когда добавляете детали местности, например. Поэтому для каждого действия, которое вы хотите предпринять, вы должны проверить все возможные аспекты и повторить эти проверки для следующего возможного действия.

Сначала нам нужен наш повторяемый дизайн, который в этом случае будет FSM для моделирования изменяющихся состояний симуляции. Поэтому первое, что я хотел бы сделать, это реализовать эталонный FSM, определив интерфейс состояния, интерфейс перехода и, возможно, контекст переходакоторый может содержать общую информацию, которая будет доступна другим двум. Базовая реализация FSM будет переключаться с одного перехода на другой независимо от контекста, вот где появляется механизм правил. Механизм правил четко инкапсулирует условия, которые должны быть выполнены, если переход должен состояться. Механизм правил здесь может быть простым списком правил, каждое из которых имеет функцию оценки, возвращающую логическое значение. Чтобы проверить, должен ли переход произойти, мы выполняем итерацию списка правил, и если какое-либо из них оценивается как ложное, переход не происходит. Сам переход будет содержать поведенческий код для изменения текущего состояния FSM (и других возможных задач).

Теперь, если я начну реализовывать симуляцию как один большой FSM на уровне GOD, я получу МНОГО возможных состояний, переходов и т. Д. Беспорядок if-else выглядит так, как будто он исправлен, но на самом деле он просто распространяется: каждый IF Теперь правило, которое выполняет проверку на предмет конкретной информации контекста (которая на данный момент в значительной степени содержит все), и каждое тело IF находится где-то в коде перехода.

Введите разбивку по фракталам: первым шагом будет создание FSM для каждой коровы, где состояния - это собственные внутренние состояния коровы (стоя, бег, ходьба, выпас и т. Д.), И переходы между ними будут зависеть от окружающей среды. Возможно, что график неполон, например, выпас доступен только из стоячего состояния, любой другой переход запрещен, потому что просто отсутствует в модели. Здесь вы эффективно разделяете данные в двух разных моделях: корова и рельеф. У каждого свои свойства. Эта разбивка позволит вам упростить общую конструкцию двигателя. Теперь вместо единого механизма правил, который решает все, у вас есть несколько более простых механизмов правил (по одному для каждого перехода), которые определяют очень конкретные детали.

Поскольку я повторно использую тот же код для FSM, это в основном конфигурация FSM. Помните, когда мы упоминали о DSL раньше? Именно здесь DSL может принести много пользы, если у вас есть множество правил и переходов для написания.

Идти глубже

Теперь БОГУ больше не приходится сталкиваться со всей сложностью управления внутренними состояниями коровы, но мы можем продвинуть это дальше. Например, в управлении ландшафтом все еще много сложностей. Здесь вы решаете, где достаточно разбивки. Если, например, в вашем БОГе вы в конечном итоге управляете динамикой местности (длинная трава, грязь, сухая грязь, короткая трава и т. Д.), Мы можем повторить ту же схему. Ничто не мешает вам внедрить такую ​​логику в сам ландшафт, выделяя все состояния ландшафта (длинная трава, короткая трава, грязная, сухая и т. Д.) В новый FSM ландшафта с переходами между состояниями и, возможно, простыми правилами. Например, чтобы попасть в мутное состояние, механизм правил должен проверить контекст, чтобы найти жидкости, иначе это невозможно. Теперь БОГ стал еще проще.

Вы можете завершить систему FSM, сделав их автономными и дать каждому поток. Этот последний шаг не обязателен, но он позволяет вам динамически изменять взаимодействие системы, регулируя то, как вы делегируете свое решение (запуск специализированного FSM или просто возвращение предварительно определенного состояния).

Помните, как мы упоминали, что переходы могут также выполнять «другие возможные задачи»? Давайте рассмотрим это, добавив возможность взаимодействия различных моделей (FSM) друг с другом. Вы можете определить набор событий и позволить каждому FSM зарегистрировать прослушиватель этих событий. Таким образом, если, например, корова входит в гекс местности, гекс может зарегистрировать слушателей для изменений перехода. Здесь это становится немного сложнее, потому что каждый FSM реализован на очень высоком уровне без каких-либо знаний о конкретной области, которую он скрывает. Однако вы можете добиться этого, если бы корова опубликовала список событий, и ячейка может зарегистрироваться, если увидит события, на которые она может реагировать. Хорошая иерархия семейства событий - это хорошая инвестиция.

Вы можете продвинуться еще глубже, смоделировав уровни питательных веществ и цикл роста травы, с ... как вы уже догадались ... FSM травы, встроенной в собственную модель участка местности.

Если вы продвигаете идею достаточно далеко, БОГу мало что нужно сделать, поскольку все аспекты в значительной степени управляются самостоятельно, освобождая время, чтобы тратить на более благочестивые вещи.

резюмировать

Как указано выше, FSM здесь не является решением, а просто средством для иллюстрации того, что решение такой проблемы не в коде, а в том, как вы моделируете свою проблему. Есть, скорее всего, другие решения, которые возможны и, скорее всего, намного лучше, чем мое предложение FSM. Однако подход «фракталы» остается хорошим способом справиться с этой трудностью. Если все сделано правильно, вы можете динамически распределять более глубокие уровни там, где это имеет значение, а также предлагать более простые модели, где это имеет значение. Вы можете ставить в очередь изменения и применять их, когда ресурсы становятся более доступными. В последовательности действий, возможно, не так важно рассчитывать перенос питательных веществ от коровы к травяному пятну. Однако вы можете записать эти переходы и применить изменения позднее или просто приблизить их с помощью обоснованного предположения, просто заменив механизмы правил или, возможно, заменив реализацию FSM вместе с более простой наивной версией для элементов, которые не находятся в прямой области интерес (эта корова на другом конце поля), чтобы позволить более подробные взаимодействия, чтобы получить фокус и большую долю ресурсов. Все это, не пересматривая систему в целом; Так как каждая деталь хорошо изолирована, становится проще создать замену, ограничивающую или расширяющую глубину вашей модели. Используя стандартный дизайн, вы можете опираться на это и максимизировать инвестиции, сделанные в специальные инструменты, такие как DSL, для определения правил или стандартного словаря для событий, снова начиная с очень высокого уровня и добавляя уточнения по мере необходимости. Так как каждая деталь хорошо изолирована, становится проще создать замену, ограничивающую или расширяющую глубину вашей модели. Используя стандартный дизайн, вы можете опираться на это и максимизировать инвестиции, сделанные в специальные инструменты, такие как DSL, для определения правил или стандартного словаря для событий, снова начиная с очень высокого уровня и добавляя уточнения по мере необходимости. Так как каждая деталь хорошо изолирована, становится проще создать замену, ограничивающую или расширяющую глубину вашей модели. Используя стандартный дизайн, вы можете опираться на это и максимизировать инвестиции, сделанные в специальные инструменты, такие как DSL, для определения правил или стандартного словаря для событий, снова начиная с очень высокого уровня и добавляя уточнения по мере необходимости.

Я хотел бы привести пример кода, но это все, что я могу позволить себе сделать прямо сейчас.

Newtopian
источник
1
Я принял этот ответ, потому что он объясняет решение на порядок лучше, чем другие. Однако я мог бы изменить принятый ответ, если появится лучший. Ваше решение также кажется достаточно радикальным, чтобы изменить ситуацию. Однако у меня все еще есть проблемы с пониманием того, как определить правила взаимодействия различных моделей. Не могли бы вы привести пример?
Дэвид
-1 Я не понимаю, почему это не может быть просто решено с помощью дерева решений? (в сочетании с DSL, который берет модель и превращает ее в работоспособный код)?
Темная ночь
14
БОГ против ФСМ?
Джон Кромарти
1
Деревья решений и механизмы правил используются именно в тех случаях, когда нет никакой внутренней ценности для моделирования имеющихся аспектов, поскольку они являются всего лишь средством для завершения расчетов. Вы видите это в программном обеспечении здравоохранения все время. При этом, если вы пытаетесь смоделировать реальное поведение, вы должны попытаться это сделать. Есть множество случаев, когда единственная логика, которая может быть найдена в проблеме, является результатом тысяч, если это, то это до бесконечности. И это действительно так, поэтому у нас есть инструменты для борьбы с этим.
delete_user
1
Это оказалось очень успешным в мире программирования игр; гораздо быстрее и проще изменить правило или свойство и позволить появиться поведению, а затем исследовать значение, чтобы решить, как действовать на него.
Бен Легжеро
89

Похоже, что все эти условные операторы, о которых вы говорите, должны быть данными, которые настраивают вашу программу, а не частью самой вашей программы. Если вы можете обращаться с ними таким образом, то вы сможете изменить способ работы вашей программы, просто изменив ее конфигурацию вместо того, чтобы изменять код и перекомпилировать каждый раз, когда вы хотите улучшить свою модель.

Существует множество различных способов моделирования реального мира в зависимости от характера вашей проблемы. Ваши различные условия могут стать правилами или ограничениями, которые применяются к симуляции. Вместо того, чтобы иметь код, который выглядит так:

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

вместо этого вы можете иметь код, который выглядит следующим образом:

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

Или, если вы можете разработать линейную программу, которая моделирует поведение коровы с учетом количества входных данных, каждое ограничение может стать линией в системе уравнений. Затем вы можете превратить это в марковскую модель, которую вы можете повторить.

Трудно сказать, каков правильный подход для вашей ситуации, но я думаю, что вам будет намного легче, если вы считаете, что ваши ограничения являются входными данными для вашей программы, а не для кода.

Caleb
источник
4
Пожалуйста, опишите, как "cow.apply (rule);" работает с файлами конфигурации?
Кромстер
8
@ Кром, трудно сказать в конкретных терминах, не зная, о какой системе мы на самом деле говорим. Моя точка зрения выше состоит в том, чтобы рассматривать тысячи условий как входные данные для программы, чтобы вам не приходилось писать код для каждого из них, и вы можете изменять условия без изменения программы. Но да, если условия можно рассматривать как данные, вы бы хранили их отдельно от программы в каком-то документе или файле конфигурации.
Калеб
2
@Krom - просто. Вы должны прочитать правило, а затем применить его к данной корове.
Ramhound
5
Перемещение кода в конфигурационные файлы не всегда хороший подход. Магию сложно отлаживать.
Рики Кларксон
44

Никто не упомянул об этом, поэтому я подумал, что скажу это прямо:

Тысячи правил «Если .. Тогда .. Остальное» - признак плохо разработанного приложения.

В то время как доменное представление данных может выглядеть как эти правила, вы абсолютно уверены, что ваша реализация должна напоминать доменное представление?

полей
источник
18
Не обязательно правда. Есть проблемы, которые можно решить только с помощью огромных деревьев решений. Но, конечно, решение для тех, кто состоит из буквального дерева if-then-else, является плохо спроектированным. Существуют гораздо более гибкие и поддерживаемые способы сделать это.
SF.
43
Я думал, что это был вопрос. У ОП есть проблема, специфичная для его домена, которая в наивной реализации потребовала бы тысяч если ... то ... еще. У него была интуиция, что это должно быть неприятно, и он спросил это сообщество о лучших способах сделать это. Сам факт того, что вопрос был задан, - это хорошая песня о том, что это уже понято, но ваш ответ, хотя и правильный, никоим образом не помогает вопросу.
Ньютопия
@Newtopian Опытный пользователь или программист поймет это и воспримет это как очевидное. Наивный пользователь или программист, возможно, не осознают этого. Я сознательно изложил то, что большинство людей здесь считают очевидным - я подтвердил, что ФП прав в своем предположении, что это будет проблематично, и определенно не должно идти с немедленной или наивной реализацией.
черничные
Я согласен, вы можете заменить, если еще полиморфизм, а также DI. если у вас есть миллионы если, еще ваш дизайн плохо.
DarthVader
17

Пожалуйста, используйте программное обеспечение / компьютерные языки, которые подходят для этой задачи. Matlab очень часто используется для моделирования сложных систем, где вы можете иметь буквально тысячи условий. Не используя предложения if / then / else, но путем численного анализа. R - это компьютерный язык с открытым исходным кодом, который наполнен инструментами и пакетами для того же. Но это означает, что вам также необходимо пересмотреть свою модель в более математических терминах, чтобы вы могли включить в модели как основные влияния, так и взаимодействия между ними.

Если вы еще этого не сделали, пожалуйста, пройдите курс о моделировании и симуляции. Последнее, что вы должны сделать, это подумать о написании такой модели с точки зрения «если - то - еще». У нас есть цепочки Монте-Карло Маркова, машины опорных векторов, нейронные сети, анализ скрытых переменных, ... Пожалуйста, не забрасывайте себя на 100 лет назад, игнорируя богатство доступных инструментов моделирования.

Йорис Мейс
источник
Я удивлен, как этот вопрос привлек так мало внимания. Числовой анализ и моделирование в своей основе - машина «если-то еще». Тем не менее, он страдает от ложных срабатываний, которые не могут быть допущены, если приложение требует строгого соблюдения правил. (Думаю, банковское дело)
Арун Хосе
13

Механизмы правил могут помочь, потому что, если существует так много правил if / then, может быть полезно получить их все в одном месте вне программы, где пользователи могут редактировать их без необходимости знания языка программирования. Также могут быть доступны инструменты визуализации.

Вы также можете посмотреть на решения логического программирования (например, Prolog). Вы можете быстро изменить список операторов if / then и заставить его выполнять такие вещи, как поиск, приведет ли любая комбинация входных данных к определенным результатам и т. Д. Кроме того, в логике предикатов первого порядка может быть чище, чем в процедурном коде (или чем в объектно-ориентированный код).

PSR
источник
11

Меня вдруг осенило:

Вам необходимо использовать дерево обучения принятию решений (алгоритм ID3).

Весьма вероятно, что кто-то реализовал это на вашем языке. Если нет, вы можете портировать существующую библиотеку

Темная ночь
источник
Придерживайтесь идеи DSL, приведенной выше. Попытайтесь выяснить, как абстрагировать проблему до некоторой формы символической алгебры, а затем реализовать это.
Захари К
11

Это скорее вики-ответ сообщества, объединяющий различные инструменты моделирования, предложенные другими ответами. Я только добавил дополнительные ссылки на ресурсы.

Я не думаю, что есть необходимость повторять, что вы должны использовать другой подход к тысячам жестко закодированных операторов if / else.

ocodo
источник
9

Каждое большое приложение содержит тысячи if-then-else операторов, не считая других элементов управления потоками, и эти приложения по-прежнему отлажены и поддерживаются, несмотря на их сложность.

Кроме того, количество операторов не делает поток непредсказуемым . Асинхронное программирование делает. Если вы используете детерминированные алгоритмы синхронно, вы будете иметь 100% предсказуемое поведение, каждый раз.

Вероятно, вам следует лучше объяснить, что вы пытаетесь сделать в Stack Overflow или Code Review, чтобы люди могли предложить вам точные методы рефакторинга . Вы также можете задать более точные вопросы, например, «Как мне избежать вложения слишком большого количества ifутверждений <учитывая фрагмент кода>».

оборота Арсений Мурзенко
источник
1
Большинство приложений имеют 2-3 уровня вложенности и однострочные условия. Как насчет проблемы, которая требует, чтобы дерево решений располагалось на 50 уровней ниже, а многие условия представляли собой логические соединения из 30 или более переменных в каждом?
SF.
Хотя «Каждое большое приложение ...», безусловно, верно, довольно ясно, что ОП говорит о длинных последовательностях условных выражений, которые по существу формируют правила в модели. Огромные вложенные группы ifутверждений быстро становятся в лучшем случае громоздкими, поэтому требуется лучший подход.
Калеб
@Caleb: ты прав, теперь все ясно , с точным примером в начале вопроса. Это было до того, как вопрос был отредактирован, когда я написал свой ответ. Это объясняет фактическую непоследовательность моих и двух других ответов, опубликованных одновременно.
Арсений Мурзенко
2

Сделайте ваше приложение управляемым, разработав его хорошо. Создайте свое приложение, разделив различную бизнес-логику на отдельные классы / модули. Напишите модульные тесты, которые тестируют каждый из этих классов / модулей в отдельности. Это очень важно и поможет вам обеспечить реализацию бизнес-логики, как ожидается.

Бернард
источник
2

Вероятно, не будет единого способа спроектировать выход из вашей проблемы, но вы можете управлять сложностью этого по частям, если вы попытаетесь выделить различные области, где вы обнаружите, что пишете большие блоки операторов if и применяете решения к каждой из этих небольших проблем.

Посмотрите на методы, как правила, о которых говорили в рефакторинге для способов разбить большие условные выражения на управляемые куски - например, несколько операторов с общим интерфейсом могут заменить оператор case.

Ранний выход тоже очень помогает. Если у вас есть условия ошибки, уберите их в начале функции, выдав исключение или вернув вместо того, чтобы позволить им вложиться.

Если вы разбиваете свои условия на функции предикатов, может быть легче отслеживать их. Кроме того, если вы можете получить их в стандартной форме, может быть возможно получить их в структуре данных, которая создается динамически, а не жестко закодированной.

оборота Дан Монего
источник
2

Я бы предложил вам использовать механизм правил. В случае Java может быть полезен jBPM или Oracle BPM. Механизмы правил в основном позволяют настраивать приложение через XML.

Sid
источник
+1 Я использовал Drools в последнее время вместе с Mvel в качестве языка для выражения правил, и это именно то, что вы ищете. Несмотря на то, что это очень быстро.
Джалайн
Слюни хороший выбор. Я лично использую Oracle BPM прямо сейчас. Там же Фейго. Доступно множество инструментов с открытым исходным кодом и проприетарных.
Сид
2

Проблема не решается с помощью «правил», описанных процедурным кодом «если-то» или многочисленными решениями правил, разработанными для бизнес-приложений. Машинное обучение предоставляет ряд механизмов для моделирования таких сценариев.

По сути, необходимо сформулировать некую схему для конкретного представления факторов (например, солнца, ветра, источника пищи, внезапных событий и т. Д.), Влияющих на «систему» ​​(т. Е. Коров на пастбище). Несмотря на ошибочное мнение о том, что можно создать реально ценное функциональное представление, в отличие от дискретного, ни один компьютер в реальном мире (включая нервную систему человека) не основан на реальной стоимости или не вычисляет на основе реальных ценностей.

Если у вас есть числовое представление для соответствующих факторов, вы можете построить любую из нескольких математических моделей. Я бы предложил двудольный график, где один набор узлов представляет коров, а другой - единицу площади пастбищ. Корова в любом случае занимает некоторую единицу площади пастбища. Тогда для каждой коровы существует полезное значение, связанное с текущим и всеми другими единицами пастбища. Если модель предполагает, что корова стремится оптимизировать (что бы это ни значило для коровы) полезную ценность своей единицы пастбища, тогда коровы будут переходить от единицы к единице в попытке оптимизировать.

Клеточный автомат работает хорошо для выполнения модели. Основная математика в реальном мире математики, мотивирующая движение коровы, - это модель градиента поля. Коровы переходят из позиций воспринимаемой более низкой полезности в позиции воспринимаемой более высокой полезности.

Если кто-то вносит изменения в окружающую среду в систему, он не переходит к устойчивому решению положения коров. Это также станет моделью, к которой могут быть применены аспекты теории игр; не то, чтобы такое обязательно добавило бы много к этому случаю.

Преимущество здесь в том, что забой коров или приобретение новых коров можно легко контролировать, вычитая и добавляя «коровьи» клетки к двудольному графику во время работы модели.

Чарльз
источник
1

Я не думаю, что вы должны определять так много утверждений if-else. С моей точки зрения, ваша проблема состоит из нескольких компонентов:

  • Он должен быть асинхронным или многопоточным, потому что у вас есть несколько коров с разными личностями, разной конфигурации. Каждая корова спрашивает себя, в каком направлении идти перед следующим ходом. На мой взгляд, код синхронизации - плохой инструмент для решения этой проблемы.

  • Конфигурация дерева решений постоянно меняется. Это зависит от положения фактической коровы, погоды, времени, рельефа местности и т. Д. Вместо того, чтобы строить сложное, если-либо, дерево, я думаю, что мы должны свести проблему к розе ветров или направлению - функции веса : фигура 1 рисунок 1 - направление - весовые функции по некоторым правилам

    Корова всегда должна идти в направлении, которое имеет наибольшую суммарную массу. Таким образом, вместо построения большого дерева решений вы можете добавить набор правил (с разным направлением - функциями веса) для каждой коровы и просто обрабатывать результат каждый раз, когда вы спрашиваете направление. Вы можете перенастроить эти правила при каждом изменении позиции, или по прошествии времени, или вы можете добавить эти детали в качестве параметров, которые должно получить каждое правило. Это решение о реализации. Самый простой способ получить направление, добавить простой цикл от 0 ° до 360 ° с шагом 1 °. После этого вы можете посчитать суммарный вес каждого направления 360 и выполнить функцию max (), чтобы получить правильное направление.

  • Для этого не обязательно нужна нейронная сеть, только один класс для каждого правила, один класс для коров, может быть, для местности и т. Д. И один класс для сценария (например, 3 коровы с разными правилами и 1 конкретная местность). фигура 2 Рисунок 2 - корова приложения асинхронных узлов и соединений

    • красный для направления сообщений - вес карты через правила
    • синий для обновления ориентации и положения после принятия решения
    • зеленый для обновлений ввода после ориентации и обновления положения
    • черный для получения входов

    примечание: вам, вероятно, понадобится система обмена сообщениями для реализации чего-то подобного

    Таким образом, если создание коров не является частью вашей проблемы, вам не нужна нейронная сеть или генетические алгоритмы. Я не эксперт по ИИ, но, думаю, если вы хотите адаптировать своих коров к реальным, то вы можете сделать это просто с помощью генетического алгоритма и соответствующего набора правил. Если я хорошо понимаю, вам нужна популяция коров со случайными настройками правил. После этого вы можете сравнить поведение реальных коров с поведением вашей модели популяции и сохранить 10%, которые идут ближе всего к реальным. После этого вы можете добавить новые ограничения конфигурации правил для вашей фабрики коров, основываясь на 10%, которые вы сохранили, и добавить новых случайных коров в популяцию и т. Д., Пока не получите модель коровы, которая ведет себя так же, как настоящие ...

оборота инф3рно
источник
0

Я бы добавил, что может быть так, что если у вас действительно есть тысячи ЕСЛИ ... ТОГДА правил, вы можете быть слишком точными. Что бы это ни стоило, разговоры о моделировании нейронной сети, которые я посещал, часто начинаются с заявления о том, как с помощью «простого набора правил» они могут генерировать довольно сложное и разумно соответствующее поведению поведение (в этих случаях реальных нейронов в действии). Итак, вы уверены, вам нужны тысячи условий? Я имею в виду, помимо 4-5 аспектов погоды, местоположения источников пищи, внезапных событий, стада и рельефа, у вас действительно будет много других переменных? Конечно, если бы вы попытались сделать все возможные комбинации сочетания этих условий, то вы могли бы легко иметь много тысяч правил, но это не правильный подход. Возможно, подход в стиле нечеткой логики, в котором различные факторы вносят смещение в положение каждой коровы, которое в сочетании с общим решением, позволит вам сделать это в гораздо меньшем количестве правил.

Я также согласен со всеми остальными, что набор правил должен быть отделен от общего потока кода, чтобы вы могли легко настроить его без изменения программы. Вы даже можете придумать конкурирующие наборы правил и посмотреть, как они справляются с реальными данными о движении коров. Звучит весело.

Chelonian
источник
0

Экспертные системы были упомянуты, которые являются областью ИИ. Чтобы немного подробнее остановиться на этом, ознакомление с механизмами вывода может помочь вам в этом. Поиск Google мог бы быть более полезным - написание DSL является простой частью, вы могли бы сделать это тривиально с парсером, таким как Gold Parser. Трудная часть состоит в том, чтобы создать дерево решений и эффективно выполнять их.

Многие медицинские системы уже используют эти двигатели, например британский веб-сайт NHS Direct .

Если вы являетесь .NET'er, то Infer.NET может быть полезен для вас.

Крис С
источник
0

Поскольку вы смотрите на движение коровы, они застряли в направлении 360 градусов (коровы не могут летать.) У вас также есть скорость, с которой вы путешествуете. Это может быть определено как вектор.

Теперь, как вы справляетесь с такими вещами, как положение солнца, склон холма, громкий шум?

Каждая из степеней будет переменной, обозначающей желание идти в этом направлении. Скажем, что ветка щелкает справа от коровы под углом 90 градусов (при условии, что корова смотрит на 0 градусов). Желание идти направо будет падать, а желание идти 270 (слева) будет возрастать. Пройдите через все стимулы, добавляя или вычитая их влияние на желание коров идти в направлении. Как только все стимулы будут применены, корова пойдет в направлении наивысшего желания.

Вы также можете применять градиенты, чтобы стимулы не были бинарными. Например, холм не прямо вверх в одном направлении. Может быть, корова находится в долине или на дороге на холме, где ее плоскость была прямо впереди, на 45 * немного выше, на 90 * немного вниз. На 180 * крутой подъем в гору.

Затем вы можете отрегулировать вес события и направление его влияния. Вместо списка «если тогда», у вас есть один тест, ищущий макс. Кроме того, когда вы хотите добавить стимулы, вы можете просто применить их перед тестом, и вам не нужно иметь дело с добавлением все большей и большей сложности.

Вместо того, чтобы сказать, что корова пойдет в любом направлении 360, давайте просто разбить ее на 36 направлений. Каждое существо 10 градусов

Вместо того, чтобы сказать, что корова пойдет в любом направлении 360, давайте просто разбить ее на 36 направлений. Каждое существо 10 градусов. В зависимости от того, насколько конкретно вам нужно быть.

Нуль
источник
-2

Используйте ООП. Как насчет создания группы классов, которые обрабатывают базовые условия и запускают случайные методы для имитации того, что вы делаете.

Получить программиста, чтобы помочь.

class COW_METHODS {

    Function = array('Action1','Action2',....'ActionX');

    function doAction() {
       execute(Function[random(1,5000]);
    }

    function execute(DynamicFunction) {
        exec(DynamicFunction());
    }

    Function Action1() {
        turnRight();
        eatGrass();
    }
    /*  keep adding functions for COW Methods ...  etc  */
    /*  and add classes for conditions inherit them as needed  */
    /*  keep an object to define conditions =  Singleton etc.  */
}
Dylan Rosario
источник
Почему это последний ответ. Дело доходит до того, что тысячи операторов if else теперь просто способ разработки программы.
wfbarksdale
1
Потому что рекомендация « Использовать ООП. Обратитесь за помощью к программисту » стоит того же, что и рекомендация « Делать больше телефонных звонков! » На вопрос « Как я могу увеличить продажи в четыре раза? ». Это не совсем неправильно, но это тоже не сильно помогает.
JensG
2
Я отказался, потому что это плохой ответ. Технически; Ваш ответ имеет мало общего с ООП. COW_METHODSКажется, что вызываемый класс является не чем иным, как набором слабо связанных методов. Где разделение интересов? Связанный с вопросом, как это помогает спрашивающему?
30.01.15