Я буду использовать систему библиотеки университета для объяснения моего варианта использования. Студенты регистрируются в системе библиотеки и обеспечивают свой профиль: пол, возраст, отдел, ранее завершил курсы, в настоящее время регистрируемые курсы, книги, уже одолженные, и т.д. Каждая книга в системе библиотеки определит некоторые правила заимствования на основе профиля студентов, например, учебник для компьютерного алгоритма может только быть одолжен студентами, в настоящее время регистрируемыми в том классе; другой учебник может только быть одолжен студентами в математическом отделе; могли также быть правила, таким образом, что студенты могут только одолжить 2 книги компьютерных сетей самое большее. В результате правил заимствования, когда студент ищет/просматривает в системе библиотеки, он будет только видеть книги, которые могут быть одолжены им. Так, требование действительно сводится к строке эффективной генерации списка книг, которые студент имеет право одолжить.
Вот то, как я, видение, использование дизайна Пускает слюни - каждая книга, будет иметь правило с несколькими полевыми ограничениями на студенческий профиль как LHS, RHS книжного правила просто, добавляю книжный идентификатор к глобальному списку результата, тогда все книжные правила загружаются в RuleBase. Когда студенческие поиски/браузеры система библиотеки, сессия не сохраняющая состояние создается из RuleBase, и профиль студента утверждается как факт, тогда каждая книга, которую может одолжить студент, запустит свое книжное правило, и Вы получаете полный список книг, которые студенты могут одолжить в глобальном списке результата.
Несколько предположений: библиотека обработает миллионы книг; я не ожидаю книжного правила, которое будет слишком сложным, 3 простых полевых ограничения для каждого правила в среднем самое большее; число студентов, которых должна обработать система, находится в диапазоне 100K, таким образом, нагрузка является довольно большой. Мои вопросы: сколько память будет Пускать слюни взять, если загружено миллионом книжных правил? Как быстро это будет для весь тех миллион правил стрелять? Если бы Пускает слюни, правильное соответствие, я хотел бы услышать некоторые лучшие практики в разработке такой системы от Вас опытные пользователи. Спасибо.
Схему environment.plist на Mac я нахожу довольно уродливой, поэтому я использую следующий фрагмент, который предполагает, что вы хотите, чтобы Emacs использовал тот же ПУТЬ, который вы видите в вашем Terminal.app:
(defun set-exec-path-from-shell-PATH () (let ((path-from-shell (shell-command-to-string «$ SHELL -i -c 'echo $ PATH'»))) (setenv «PATH» путь-от-оболочки) (setq exec-path (разделитель пути из оболочки с разделением строк))))
(Это работает для меня в Emacs 23; не пробовали его в других версиях, но я бы ожидал, что он сработает.)
-121--2684955- Да, std:: vector < T >:: push _ back ()
создает копию аргумента и сохраняет ее в векторе. Если требуется сохранить указатели на объекты в векторе, создайте std:: vector < что угодно * >
вместо std:: vector < что угодно >
.
Однако необходимо убедиться, что объекты, на которые ссылаются указатели, остаются действительными, в то время как вектор содержит ссылку на них (интеллектуальные указатели, использующие идиом RII, решают проблему).
-121--677537-Мой опыт работы с Drools (или движком правил в целом) это хорошо подходит, если важна видимость правил пользователем, или если важны быстрые изменения правил, не делая их проектом кодирования, или если набор правил очень велик, что затрудняет управление, размышление и анализ в коде (чтобы у вас были деловые люди, прося технических сотрудников пойти прочитать код и сказать им, что происходит в ситуации X).
При этом механизмы правил могут быть узким местом. Они не запускают ничего близкого к производительности кода, поэтому вам нужно управлять этим с помощью архитектуры. В этом конкретном случае за этим, безусловно, стоит база данных, и можно добавить к проблемам производительности, что база данных вернет запрос намного быстрее, чем вы можете проанализировать полный набор в коде.
Я бы абсолютно не реализовал это, создав миллион объектов правил, а сделал бы тип книги, которой можно назначить несколько книг, и выполнил бы правила по типам книг, а затем показал бы только книги, которые находятся в разрешенном типе. Таким образом можно загрузить типы, передать их через механизм правил, а затем переместить разрешенные типы в запрос на конце базы данных, который извлекает список книг в разрешенных типах.
Типы немного усложняются тем фактом, что на практике книга может быть двух типов (разрешено, если вы проходите определенный курс, или вообще, если вы входите в состав отдела), но подход все равно должен держаться.
Я бы побеспокоился о том, чтобы количество правил зависело от количества учеников - это могло бы действительно усложнить задачу (это звучит как самая большая проблема).
Во-первых, не создавайте правила для каждой книги. Создавайте правила для ограничений - ограничений определено гораздо меньше, чем книг. Это окажет огромное влияние на время работы и использование памяти.
Прогонять тонну книг через механизм правил будет дорого. Тем более что вы не будете показывать пользователю все результаты: только 10-50 на страницу. Одна идея, которая приходит на ум, - использовать механизм правил для создания набора критериев запроса. (На самом деле я не стал бы этого делать - см. ниже)
Вот что я придумал:
rule "Only two books for networking"
when
Student($checkedOutBooks : checkedOutBooks),
Book(subjects contains "networking", $book1 : id) from $checkedOutBooks,
Book(subjects contains "networking", id != $book1) from $checkedOutBooks
then
criteria.add("subject is not 'networking'", PRIORITY.LOW);
end
rule "Books allowed for course"
when
$course : Course($textbooks : textbooks),
Student(enrolledCourses contains $course)
Book($book : id) from $textbooks,
then
criteria.add("book_id = " + $book, PRIORITY.HIGH);
end
Но на самом деле я не стал бы этого делать!
Вот как я бы изменил проблему: Не показывать книги пользователю - это плохой опыт. Пользователь может захотеть просмотреть книги, чтобы понять, какие книги стоит взять в следующий раз. Покажите книги, но запретите выписывать книги с ограниченным доступом. Таким образом, у вас будет только 1-50 книг, которые нужно прогнать через правила одновременно для каждого пользователя. Это будет довольно быстро. Приведенные выше правила станут:
rule "Allowed for course"
activation-group "Only one rule is fired"
salience 10000
when
// This book is about to be displayed on the page, hence inserted into working memory
$book : Book(),
$course : Course(textbooks contains $book),
Student(enrolledCourses contains $course),
then
//Do nothing, allow the book
end
rule "Only two books for networking"
activation-group "Only one rule is fired"
salience 100
when
Student($checkedOutBooks : checkedOutBooks),
Book(subjects contains "networking", $book1 : id) from $checkedOutBooks,
Book(subjects contains "networking", id != $book1) from $checkedOutBooks,
// This book is about to be displayed on the page, hence inserted into working memory.
$book : Book(subjects contains "networking")
then
disallowedForCheckout.put($book, "Cannot have more than two networking books");
end
Где я использую activation-group, чтобы убедиться, что срабатывает только одно правило, и salience, чтобы убедиться, что они срабатывают в нужном мне порядке.
Наконец, храните правила в кэше. Drools позволяет и предлагает загружать правила только один раз в базу знаний, а затем создавать сессии на ее основе. Базы знаний дороги, а сессии дешевы.
У меня вопросы: сколько памяти будет Слюни берут, если загружены миллионом книжные правила? Как быстро это будет для запустить все эти миллионы правил?
Насколько быстро работает ваш компьютер и сколько у вас памяти? В каком-то смысле вы можете узнать это, только создав доказательство концепции и заполнив его нужным количеством (случайно сгенерированных) тестовых данных. Мой опыт показывает, что Drools работает быстрее, чем вы ожидаете, и что вы должны очень хорошо знать, что находится под капотом, чтобы быть в состоянии предсказать, что сделает его медленным.
Обратите внимание, что вы говорите о миллионе фактов сеанса правил (т. е. объектах Book), а не о миллионе правил. Есть только несколько правил, которые не заставят себя долго ждать. Потенциально медленной частью является вставка миллиона объектов, потому что Drools должен решить, какие правила добавить в Agenda для каждого нового факта.
Жаль, что ни у кого из нас нет ответа на какую-то конкретную установку с миллионом фактов.
Что касается реализации, мой подход заключается в том, чтобы вставить объект Book для каждой книги, которую учащийся хочет проверить, удалить те, которые не разрешены, и запросить оставшиеся (разрешенные) объекты Book, и другой запрос, чтобы получить список причин.В качестве альтернативы используйте объекты RequestedBook с дополнительными свойствами boolean Allowed
и String ReasonDisallowed
, которые вы можете установить в своих правилах.