0

Microsoft Solver Foundation を使用して、家族のクリスマス抽選 ( 「シークレット サンタ」や「クリス クリングル」に似ています) を解決しようとしています。

いくつかの複雑な制約があります (たとえば、兄弟のために購入できないなど)。これは、各参加者のドメインを整理するために既に使用しています。

ソルバーは機能しますが、人がプレゼントを 1 つだけ受け取る必要があるという制約がないことを除きます (つまり、アリスがボブのために購入するということは、他の誰もボブのために購入していないことを意味します)。

「AllDifferent」制約を追加しようとしましたが、引数例外が発生しています-

「入力アリスとボブは異なるシンボル ドメインを持っています。」

また、制約を 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();
        }
    }   
}
4

1 に答える 1