2014-04-02 5 views
0

Microsoft Solver Foundation을 사용하여 우리 가족의 크리스마스 그리기를 해결하려고합니다 ("secret santa" or "kris kringle"과 유사).MS Solver Foundation CSP 오류 - 입력에 다른 기호 도메인이 있습니다.

저는 이미 각 참가자의 도메인을 정리하는 데 사용했던 몇 가지 복잡한 제약 조건 (예 : 형제 자매는 구입할 수 없음)이 있습니다.

솔버가 작동한다는 것은 단 하나의 현재 (즉, Bob의 앨리스 구매는 아무도 Bob을 사지 않는다는 것을 의미 함) 만 수신해야한다는 제약 조건을 제외하고는 작동합니다.

나는 "AllDifferent"제약 조건을 추가하는 시도하지만, 인수 예외 중

은 무엇입니까

"입력 앨리스와 밥은 서로 다른 기호 도메인이 있습니다."

또한 제약 조건을 OML 식으로 추가하려고 시도했지만 동일한 오류가 발생했습니다.

  • 다른 도메인의 의사 결정간에 제약 조건을 적용 할 수 있습니까?
  • 그렇지 않은 경우 모든 결정에 동일한 도메인을 사용해야 할 때 "포함"제약 조건이 있습니까? (I는 "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(); 

     } 
입니다