I am trying to use Microsoft Solver Foundation to solve our family Christmas draw (similar to a "secret santa" or "kris kringle").
I have some complex constraints (e.g can't buy for your siblings), which I have already used to prune the domains for each participant.
The solver works, except that it doesn't have a constraint that a person should only receive one present (i.e. Alice buying for Bob implies that no-one else is buying for Bob).
I tried adding a "AllDifferent" constraint, but am getting an Argument Exception-
"Inputs Alice and Bob have different symbol domains."
I also tried adding the constraint as a OML expression, but ran into the same error.
- Is it possible to apply any constraints between decisions with different domains?
- If not, and I need to use the same domain for all decisions, is there a "contains" constraint? (I tried to use "ElementOf" but was unable to get it to work.)
Sample program-
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();
}
}
}