public static CspModel PhoneFeatureModel() { var model = new CspModel(); var phone = model.AddVariable("phone", Domain.Binary); var calls = model.AddVariable("calls", Domain.Binary); var screen = model.AddVariable("screen", Domain.Binary); var screenBw = model.AddVariable("b/w", Domain.Binary); var screenColor = model.AddVariable("color", Domain.Binary); var screenHd = model.AddVariable("hd", Domain.Binary); var gps = model.AddVariable("gps", Domain.Binary); var media = model.AddVariable("media", Domain.Binary); var camera = model.AddVariable("camera", Domain.Binary); var mp3 = model.AddVariable("mp3", Domain.Binary); var test = model.AddVariable("internet", Domain.Range(0, 10)); model.AddConstraint(phone == 1); model.AddConstraint(calls == 1); model.AddConstraint(screen == 1); model.AddConstraint(media >= mp3); model.AddConstraint(media >= camera); model.AddConstraint(screenColor >= camera); model.AddConstraint(test <= 5); model.AddConstraint(screenBw + screenColor + screenHd == screen); model.AddConstraint(camera == 1); model.AddConstraint(test >= screenColor); model.AddConstraint(test <= screenColor); return model; }
private static Graph CreateGraphLayout(CspModel model) { var graph = new Graph(); graph.Directed = false; graph.Attr.LayerDirection = LayerDirection.LR; var createdEdges = new List <string>(); foreach (var variable in model.Variables) { var n = graph.AddNode($"{variable.Name}={variable.Value}"); if (variable.Value == -1) { n.Attr.FillColor = Microsoft.Msagl.Drawing.Color.Yellow; } n.Attr.Shape = Microsoft.Msagl.Drawing.Shape.Box; foreach (var constraint in model.Constraints.Where(c => c.GetVariables().Any(v => v.Name == variable.Name))) { graph.AddNode(constraint.ToString()); //graph.AddEdge(variable.ToString(), constraint.ToString()); foreach (var target in constraint.GetVariables()) { if (!createdEdges.Contains(constraint.ToString() + "->" + target.Name)) { graph.AddNode(target.Name + "=" + target.Value); graph.AddEdge(constraint.ToString(), target.Name + "=" + target.Value).Attr.ArrowheadAtTarget = ArrowStyle.None; createdEdges.Add(constraint.ToString() + "->" + target.Name); } } } } return(graph); }
public static CspModel AustralianMapColoringModel() { var model = new CspModel(); int colors = 3; var wa = model.AddVariable("wa", Domain.Range(0, colors)); var nt = model.AddVariable("nt", Domain.Range(0, colors)); var sa = model.AddVariable("sa", Domain.Range(0, colors)); var qu = model.AddVariable("ql", Domain.Range(0, colors)); var nsw = model.AddVariable("nsw", Domain.Range(0, colors)); var vi = model.AddVariable("vi", Domain.Range(0, colors)); var ta = model.AddVariable("ta", Domain.Range(0, colors)); model.AddConstraint(wa != nt); model.AddConstraint(wa != sa); model.AddConstraint(nt != sa); model.AddConstraint(nt != qu); model.AddConstraint(sa != nsw); model.AddConstraint(sa != vi); model.AddConstraint(sa != qu); model.AddConstraint(nsw != vi); model.AddConstraint(qu != nsw); return model; }
public static void PrintModel(CspModel model) { foreach (var variable in model.Variables) { Console.WriteLine($"{variable.Name} {{{string.Join(", ", variable.Domain.Values)}}}" + $" = {variable.Value} (Set: {variable.IsSet})"); } }
public CspModel Resolve(CspModel model) { foreach (var constraint in model.Constraints) { var variables = constraint.GetVariables(); if (variables.Count() == 1) { if (constraint.Left is VariableNode var && constraint.Right is NumericNode val) { var variable = var.Variable; var value = val.Evaluate(); if (constraint is EqualityConstraint equality) { variable.Domain = variable.Domain.Where(d => d == value); } else if (constraint is InequalityConstraint inequality) { variable.Domain = variable.Domain.Where(d => d != value); } else if (constraint is LessThanConstraint lessThan) { variable.Domain = variable.Domain.Where(d => d < value); } else if (constraint is LessThanOrEqualConstraint lessThanEq) { variable.Domain = variable.Domain.Where(d => d <= value); } else if (constraint is GreaterThanConstraint greaterThan) { variable.Domain = variable.Domain.Where(d => d > value); } else if (constraint is GreaterThanOrEqualConstraint greaterThanEq) { variable.Domain = variable.Domain.Where(d => d >= value); } if (variable.Domain.Count() == 0) { throw new EmptyDomainException($"Variable {variable.Name} has an empty domain, solution infeasible."); } else if (variable.Domain.Count() == 1) { // Assign the variable as early as possible so that the most constraints will come // into scope. This results in earlier backtracking! variable.Value = variable.Domain.First(); } } } } return(model); }
internal Csp( IDictionary <string, IEnumerable <T> > domains, IDictionary <string, IEnumerable <string> > relations, IEnumerable <Func <string, T, string, T, bool> > constraints ) { var variables = domains.Select(d => new Variable <T>(d.Key)).ToList(); _model = new CspModel <T>( variables, domains.Select(d => new Domain <T>(d.Key, d.Value)).ToList(), relations.Select(d => new Relations <T>(d.Key, variables.Where(v => d.Value.Contains(v.Key)))).ToList(), constraints.Select(d => new Constraint <T>(d)).ToList() ); }
public static void PrintBoard(CspModel model) { var sb = new StringBuilder(); for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { char c = model.Variables[9 * i + j].Value.ToString()[0]; sb.Append(c == '0' ? '.' : c); } sb.AppendLine(); } Console.WriteLine(sb.ToString()); }
public static CspModel SudokuSmallModel() { var model = new CspModel(); var variables = new List<Variable>(); for (int i = 0; i < 16; i++) { var variable = model.AddVariable($"x{i}", Domain.Range(1, 5)); variables.Add(variable); } for (int i = 0; i < 16; i++) { int row = i / 4; int col = i % 4; for (int j = row; j < row + 4; j++) { if (i != j) { Console.WriteLine($"{i}!={j}"); model.AddConstraint(variables[i] != variables[j]); } } for (int j = col; j < 16; j += 4) { if (i != j) { model.AddConstraint(variables[i] != variables[j]); } } // TODO: Add diagonal constraints. } //model.AddConstraint(variables[0] != variables[1] != variables[4] != variables[5]); => AllDiff(x0, x1, x2, x3) // also => AllEqual(1,2,3,4) model.AddConstraint(variables[0] == 1); model.AddConstraint(variables[1] == 2); model.AddConstraint(variables[2] == 3); model.AddConstraint(variables[3] == 4); return model; }
public ModelTest() { var dummyDomain = new[] { "R", "B", "G" }; var proto = new Dictionary <string, IEnumerable <DummyCspValue> > { ["SA"] = dummyDomain.Select(c => new DummyCspValue(c)), ["WA"] = dummyDomain.Select(c => new DummyCspValue(c)), ["NT"] = dummyDomain.Select(c => new DummyCspValue(c)), ["Q"] = dummyDomain.Select(c => new DummyCspValue(c)), ["NSW"] = dummyDomain.Select(c => new DummyCspValue(c)), ["V"] = dummyDomain.Select(c => new DummyCspValue(c)), ["T"] = dummyDomain.Select(c => new DummyCspValue(c)) }; var relationsProto = new Dictionary <string, IEnumerable <string> > { ["SA"] = new[] { "WA", "NT", "Q", "NSW", "V" }, ["WA"] = new[] { "SA", "NT" }, ["NT"] = new[] { "WA", "Q", "SA" }, ["Q"] = new[] { "NSW", "NT", "SA" }, ["NSW"] = new[] { "Q", "V", "SA" }, ["V"] = new[] { "NSW", "SA" } }; var variables = proto.Select(d => new Variable <DummyCspValue>(d.Key)).ToList(); _model = new CspModel <DummyCspValue>( variables, proto.Select(v => new Domain <DummyCspValue>(v.Key, v.Value)).ToList(), relationsProto.Select(d => new Relations <DummyCspValue>(d.Key, variables.Where(v => d.Value.Contains(v.Key)))).ToList(), new[] { new Constraint <DummyCspValue>(Eval) } ); }
public BacktrackSolver(CspModel model) { Model = model; }