2014-04-02 28 views
0

我正在嘗試使用Microsoft Solver Foundation來解決我們的家庭聖誕節平局(類似於"secret santa" or "kris kringle")。MS Solver Foundation CSP錯誤 - 輸入具有不同的符號域

我有一些複雜的約束(例如,不能爲你的兄弟姐妹購買),我已經用它來修剪每個參與者的域。

解算器的工作原理除了它沒有一個約束條件,即一個人只能接收一個禮物(即Alice的Bob購買意味着沒有其他人購買Bob)。

我嘗試添加一個 「AllDifferent屬性」 的約束,但我得到一個參數Exception-

「輸入Alice和Bob有不同的符號領域。」

我也嘗試添加約束作爲OML表達式,但遇到了同樣的錯誤。

  • 是否可以在不同域名的決策之間應用任何約束?
  • 如果不是,並且我需要對所有決策使用相同的域,那麼是否存在「包含」約束? (我試圖用「ElementOf」,但無法得到它的工作。)

樣品計劃專

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Microsoft.SolverFoundation.Services; 

namespace XmasDrawCSP 
{ 
    public class Class1 
    { 
     public static void Main(string[] args) 
     { 

      SolverContext context = SolverContext.GetContext(); 
      Model model = context.CreateModel(); 

      Dictionary<string, string[]> PossiblyBuysFor = new Dictionary<string, string[]>(); 

      //Alice and Carol are sisters 
      //Bob and David are brothers 

      //Can't buy for siblings or yourself 
      PossiblyBuysFor["Alice"] = new string[] { "Bob", "David", "Eve", }; 
      PossiblyBuysFor["Bob"] = new string[] { "Alice", "Carol", "Eve", }; 
      PossiblyBuysFor["Carol"] = new string[] { "Bob", "David", "Eve", }; 
      PossiblyBuysFor["David"] = new string[] { "Alice", "Carol", "Eve", }; 
      PossiblyBuysFor["Eve"] = new string[] { "Alice", "Bob", "Carol", "David", }; 

      foreach (var giver in PossiblyBuysFor.Keys) 
      { 
       Decision d = new Decision(Domain.Enum(PossiblyBuysFor[giver]), giver); 
       model.AddDecision(d); 
      } 

      //Error thrown here- "Inputs Alice and Bob have different symbol domains." 
      model.AddConstraint("one_present_each", Model.AllDifferent(model.Decisions.ToArray())); 

      Solution solution = context.Solve(new ConstraintProgrammingDirective()); 

      int i = 0; 
      while (solution.Quality != SolverQuality.Infeasible && i < 10) 
      { 
       Console.WriteLine(i); 

       foreach (var d in solution.Decisions) 
       { 
        Console.WriteLine(string.Format("{0} buys for {1}", d.Name, d.ToString())); 
       } 

       Console.ReadLine(); 
       solution.GetNext(); 
       i++; 
      } 

      Console.ReadLine(); 
     } 
    } 
} 

回答

-1

我已經找到了解決辦法。我對所有決策使用相同的域,然後將受限制的域作爲約束添加。

我讓決策名稱與解決方案的值相同讓我感到困惑。

這是一個有點亂,但這裏是工作解決方案 -

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Microsoft.SolverFoundation.Services; 

namespace XmasDrawCSP 
{ 
    public class Class1 
    { 

     public static void Main(string[] args) 
     { 

      var Names = new string[] { 
       "Alice", "Bob", "Carol", "David", "Eve", 
      }; 

      Domain Recipients = Domain.Enum(Names); 

      SolverContext context = SolverContext.GetContext(); 
      Model model = context.CreateModel(); 

      Dictionary<string, string[]> PossiblyBuysFor = new Dictionary<string, string[]>(); 

      //Alice and Carol are sisters 
      //Bob and David are brothers 

      //Can't buy for siblings or yourself 
      PossiblyBuysFor["Alice"] = new string[] { "Bob", "David", "Eve", }; 
      PossiblyBuysFor["Bob"] = new string[] { "Alice", "Carol", "Eve", }; 
      PossiblyBuysFor["Carol"] = new string[] { "Bob", "David", "Eve", }; 
      PossiblyBuysFor["David"] = new string[] { "Alice", "Carol", "Eve", }; 
      PossiblyBuysFor["Eve"] = new string[] { "Alice", "Bob", "Carol", "David", }; 

      foreach (var giver in PossiblyBuysFor.Keys) 
      { 
       Decision d = new Decision(Recipients, giver.ToLower()); 
       model.AddDecision(d); 
      } 

      foreach (var giver in PossiblyBuysFor.Keys) 
      { 
       string term = "1 == 0 "; 
       foreach (var valid in PossiblyBuysFor[giver]) 
       { 
        term += string.Format(" | {0} == \"{1}\"", giver.ToLower(), valid); 
       } 

       model.AddConstraint("domain_restriction_" + giver, term); 
      } 

      model.AddConstraint("one_present_each", Model.AllDifferent(model.Decisions.ToArray())); 

      Solution solution = context.Solve(new ConstraintProgrammingDirective()); 



      int i = 0; 
      while (solution.Quality != SolverQuality.Infeasible && i < 10) 
      { 
       Console.WriteLine(i); 

       foreach (var d in solution.Decisions) 
       { 

        Console.WriteLine(string.Format("{0} buys for {1}", d.Name, d.ToString())); 
       } 

       Console.ReadKey(); 
       solution.GetNext(); 
       i++; 
      } 
      Console.WriteLine("The end"); 
      Console.ReadKey(); 

     } 
相關問題