如何使用 Solver Foundation 简化决策矩阵

发布于 2024-11-24 01:33:49 字数 2999 浏览 1 评论 0原文

已经挣扎了一段时间,希望在这里寻求一些建议。 首先,决策矩阵是这样的:

条件 1 ->条件2->决策

 Yes           Yes          Go ahead
 Yes            No          Go ahead
  No           Yes          Go ahead
  No            No          Give up

假设: 1. 我们只考虑上面的顺序(“->”)。 2.条件1和条件1中的所有可能选项2只是“是”和“否”。

简化的标准是,如果从最后一个条件开始,在所有可能的选项下都做出相同的决定,那么在相同的last-1条件下,可以省略最后一个条件。即,

对于决策“继续”*,

条件1->条件2->决策

 Yes        Yes =>  X       Go ahead
 Yes        Yes =>  X       Go ahead
  No           Yes          Go ahead

我最初的想法是在这部分(*)中应用求解器基础,而其他部分则通过传统编程来处理,例如for循环和递归。在这种情况下,最终答案应该是

条件1 ->条件2-> Decision

 Yes             X          Go ahead
  No           Yes          Go ahead
  No            No          Give up

我陷入的困境是以下逻辑的实现:

Decision &目标: 从集合*中,选择最小的索引i(即选择代表要简化的关键的情况)。

约束: 选择条件 1 等于已判定案例的条件 1 的案例,然后检查所有可能的选项是否都出现在所有挑选的案例中的条件 2 中。

一旦我们得到决策(即 0),我们就知道条件 1 为“是”的情况可以省略条件 2。

看看谁能帮忙。谢谢。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SolverFoundation.Common;
using Microsoft.SolverFoundation.Services;
using Microsoft.SolverFoundation.Solvers;

namespace ConsoleApplication5
{
 class Program
 {
  static void Main(string[] args)
  {
   SolverContext context = SolverContext.GetContext();
   Model model = context.CreateModel();

   Segment[] segmentData = new Segment[] { 
    new Segment { id = 0, col1 = 0, col2 = 0 },
    new Segment { id = 1, col1 = 0, col2 = 1 },//answer = 0, since this row's col1 and col2 = row 0's, thus can be omitted (simplified).
    new Segment { id = 2, col1 = 1, col2 = 0 } //answer = 0, since this row's col1 not = row 0's, thus remain unchanged.
   };

   //set
   Set items = new Set(Domain.Integer, "items");

   //decision
   Decision i = new Decision(Domain.IntegerRange(0,1), "index");
   model.AddDecisions(i);

   //parameter
   Parameter col1 = new Parameter(Domain.Integer, "col1", items);
   col1.SetBinding(segmentData, "col1", "id");
   Parameter col2 = new Parameter(Domain.Integer, "col2", items);
   col2.SetBinding(segmentData, "col2", "id");
   model.AddParameters(col1, col2);

   //constraint
   //sum of all possible col2 should be 0 + 1 = 1
   model.AddConstraint("cases", 
    1 == Model.Sum(
     Model.ForEachWhere(
      items,
      s => col2[s],
      s => col1[s] == i
     )
    )
   );

   model.AddGoal("goal", GoalKind.Minimize, i);

   //problem: no suitable directive found.
   HybridLocalSearchDirective directive = new HybridLocalSearchDirective();
   directive.TimeLimit = 10000;
   Solution solution = context.Solve(directive);

   Report report = solution.GetReport();
   Console.WriteLine("{0}", i);
   Console.Write("{0}", report);
   Console.ReadLine();
  }
 }

 class Segment
 {
  public int id { get; set; }
  public int col1 { get; set; }
  public int col2 { get; set; }
 }
}

Have been struggling a while, seek for some suggestion here hopefully.
First the decision matrix is something like this:

Condition 1 -> Condition 2 -> Decision

 Yes           Yes          Go ahead
 Yes            No          Go ahead
  No           Yes          Go ahead
  No            No          Give up

Assumption:
1. We only consider in above sequence ("->").
2. All possible options from condition 1 & 2 are merely "Yes" and "No".

The criteria of simplification is that if the same decision is made under all possible options from the last condition, then the last condition can be omitted under the same last-1 condition. i.e.

For decision "Go ahead" *,

Condition 1 -> Condition 2 -> Decision

 Yes        Yes =>  X       Go ahead
 Yes        Yes =>  X       Go ahead
  No           Yes          Go ahead

My initial idea is to apply solver foundation in this part(*), whereas other parts are handle by traditional programming, like for loop and recursive. In this case the final answer should be

Condition 1 -> Condition 2 -> Decision

 Yes             X          Go ahead
  No           Yes          Go ahead
  No            No          Give up

What I am stuck in is the implementation of the following logic:

Decision & Goal:
From the set *, pick the smallest index i (i.e. pick a case which represent the key to simplify).

Constraint:
Pick cases whose condition 1 is equal to the decided case's condition 1 and then check if all possible options appear in condition 2 in all the cases picked.

Once we get the decision, which is 0, we knows the cases where condition 1 is "Yes" can have the condition 2 omitted.

See anyone can help. Thanks.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SolverFoundation.Common;
using Microsoft.SolverFoundation.Services;
using Microsoft.SolverFoundation.Solvers;

namespace ConsoleApplication5
{
 class Program
 {
  static void Main(string[] args)
  {
   SolverContext context = SolverContext.GetContext();
   Model model = context.CreateModel();

   Segment[] segmentData = new Segment[] { 
    new Segment { id = 0, col1 = 0, col2 = 0 },
    new Segment { id = 1, col1 = 0, col2 = 1 },//answer = 0, since this row's col1 and col2 = row 0's, thus can be omitted (simplified).
    new Segment { id = 2, col1 = 1, col2 = 0 } //answer = 0, since this row's col1 not = row 0's, thus remain unchanged.
   };

   //set
   Set items = new Set(Domain.Integer, "items");

   //decision
   Decision i = new Decision(Domain.IntegerRange(0,1), "index");
   model.AddDecisions(i);

   //parameter
   Parameter col1 = new Parameter(Domain.Integer, "col1", items);
   col1.SetBinding(segmentData, "col1", "id");
   Parameter col2 = new Parameter(Domain.Integer, "col2", items);
   col2.SetBinding(segmentData, "col2", "id");
   model.AddParameters(col1, col2);

   //constraint
   //sum of all possible col2 should be 0 + 1 = 1
   model.AddConstraint("cases", 
    1 == Model.Sum(
     Model.ForEachWhere(
      items,
      s => col2[s],
      s => col1[s] == i
     )
    )
   );

   model.AddGoal("goal", GoalKind.Minimize, i);

   //problem: no suitable directive found.
   HybridLocalSearchDirective directive = new HybridLocalSearchDirective();
   directive.TimeLimit = 10000;
   Solution solution = context.Solve(directive);

   Report report = solution.GetReport();
   Console.WriteLine("{0}", i);
   Console.Write("{0}", report);
   Console.ReadLine();
  }
 }

 class Segment
 {
  public int id { get; set; }
  public int col1 { get; set; }
  public int col2 { get; set; }
 }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

时光瘦了 2024-12-01 01:33:49

是否可以使用这样的 if 命令

if (Condition_One || Condition_Two)
{
 //Go ahead command
}
else
{
//Give up code
}

如果您可以提供示例代码来帮助其他人回答,

...谢谢

is it possible to use if command like this

if (Condition_One || Condition_Two)
{
 //Go ahead command
}
else
{
//Give up code
}

if you can provide a sample code which will help others to answer...

thanks

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文