Вопрос

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

QuestionID, затем я формирую кучу правил И примерно так

<rule id="1">
<true>
 <question ID=123>
 <question ID=124>
</true>
<false>
 <question ID=127>
 <question ID=128>
</false>
</rule>
<rule id="2"><true>
 <question ID=123>
 <question ID=125>
</true>
<false>
 <question ID=127>
</false>
</rule>

это правило 1 гласит, что если на вопросы 123 и 124 даны верные ответы, а 127, 128 - ложные, они проходят.ИЛИ (правило 2), если 123 и 125 являются истинными, а 127 - ложными, они также проходят.Это становится утомительным, если существует много комбинаций, поэтому я хочу реализовать OR в логике, я просто не уверен, какой наилучший подход подходит для этой проблемы.

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

Спасибо!

-- не специализируюсь в compsci.

Это было полезно?

Решение

Это не должно быть сложно:вы уже проделали большую часть пути, поскольку ваши элементы and эффективно реализуют правило AND-type.Я бы ввел элемент, который может содержать элементы and.

В вашей власти, вы могли бы:

  • Класс на основе правил с методом "public abstract bool Evaluate()"
  • Классы TrueRule, FalseRule и OrRule, которые содержат списки объектов базы правил
  • Класс QuestionRule, который ссылается на конкретный вопрос

Вы бы реализовали метод Evaluate для каждого из них следующим образом:

  • Истинное правило: возвращает true только в том случае, если все содержащиеся правила возвращают true из Evaluate
  • Фальсерула: возвращает true только в том случае, если все содержащиеся правила возвращают false из Evaluate
  • Или править: возвращает true, если хотя бы одно из содержащихся правил возвращает true из Evaluate
  • Правило вопроса: возвращает ответ на исходный вопрос

Эта иерархия классов реализует простое абстрактное синтаксическое дерево (AST).LINQ в форме System.Выражения.Класс Expression выполняет практически то же самое, но полезно написать свой собственный, если не очевидно, как все сочетается друг с другом.

Другие советы

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

Взгляните на http://www.flexrule.com который представляет собой гибкий, расширяемый механизм создания правил, поддерживающий три типа правил.Правила процедуры, вывода и потока правил могут быть выведены извне из вашего приложения и выполняться с использованием этой платформы.

Я не уверен, что полностью понимаю проблему, которую вы пытаетесь решить, но вы могли бы использовать простой XPath, чтобы получить идентификатор:

Это дало бы вам все "истинные" идентификаторы, где идентификатор правила = 1:/правило[@id="1"]/истинно//@ID

То же, что и выше, только это дает вам ложные идентификаторы:/правило[@id="1"]/ложное//@ID

Наконец, ссылка на введение в XPath в .NET http://www.developer.com/xml/article.php/3383961

Удачи

Я бы предложил помещать ответы на вопросы, а не использовать true и false чтобы сгруппировать вопросы.Я думаю, что это облегчает чтение XML, что является спорным.Что не подлежит обсуждению, так это то, что это позволяет оценить question элемент независимо, т.е.без какого-либо знания контекста, в котором вы пытаетесь это оценить.Это упрощает код.

Я бы также взял страницу из XML Schema и реализовал вашу логику OR как choice элемент.A choice элемент является истинным, если какой-либо из его дочерних элементов является истинным.Вы можете, конечно, вложить их в гнездо:

<rule id="1">
   <question id="123" answer="true" />
   <question id="124" answer="false" />
   <choice id="1">
      <question id="125" answer='true' />
      <choice id="2">
         <question id="126" answer='false' />
         <question id="127" answer='false' />
      </choice>
   </choice>
</rule>

Это оставляет вам четыре довольно простых метода для реализации, каждый из которых используется предыдущим:

  • bool GetProvidedAnswer(int questionID)
  • bool IsQuestionCorrect(XmlElement question)
  • bool IsChoiceCorrect(XmlElement choice)
  • bool IsRuleSatisfied(XmlElement rule)

Структура XML делает эти методы довольно простыми в реализации:

 bool IsRuleSatisfied(XmlElement rule)
 {
    bool satisfied = true;
    foreach (XmlElement child in rule.SelectNodes("*"))
    {
       if (child.Name == "question")
       {
          satisfied = satisfied && IsQuestionCorrect(child);
       }
       if (child.Name == "choice")
       {
          satisfed = satisfied && IsChoiceCorrect(child);
       }
       if (!satisfied)
       {
          return false;
       }
   }
   return true;
}

Возможно, стоило бы добавить List<XmlElement> к параметрам IsFooCorrect методы.(Если механизм правил находится в классе, вы могли бы сделать его полем класса.) Make `все методы добавляют текущий элемент в список, когда ответ неправильный.Затем вы можете изучить содержимое этого списка, чтобы точно узнать, почему правило не сработало.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top