public void TestExpressionInteger() { var expr = new ExpressionInteger(0, true); Assert.True(expr.id == 0); Assert.True(expr.positive); }
public void TextExpressionOrFlatten() { var expr = GenerateTestOr(); var flatten = expr.Flatten(); Assert.Equal(4, flatten.children.Count); for (int i = 0; i < flatten.children.Count; i++) { CheckType <ExpressionInteger> (flatten.children[i]); ExpressionInteger subexpr = (ExpressionInteger)flatten.children[i]; Assert.Equal(i, subexpr.id); } }
private ConstraintOperationResult Propagator(ExpressionInteger left, ExpressionInteger right, Bounds <int> enforce) { var result = ConstraintOperationResult.Undecided; SortedList <int, int> sortedElements; try { //TODO Handle the issue here with repeated array values sortedElements = SortedElements(); } catch (Exception) { return(result); } if (enforce.UpperBound < sortedElements.First().Key || enforce.LowerBound > sortedElements.Last().Key) { return(ConstraintOperationResult.Violated); } var remove = sortedElements. TakeWhile(v => v.Key < enforce.LowerBound). Select(v => v.Value). Concat(sortedElements. Reverse(). TakeWhile(v => v.Key > enforce.UpperBound). Select(v => v.Value)). ToList(); if (remove.Any()) { result = ConstraintOperationResult.Propagated; var domainOperation = default(DomainOperationResult); foreach (var value in remove) { Index.Domain.Remove(value, out domainOperation); if (domainOperation == DomainOperationResult.EmptyDomain) { return(ConstraintOperationResult.Violated); } } left.Bounds = EvaluateBounds(left, null); } return(result); }
private ConstraintOperationResult Propagator(ExpressionInteger left, ExpressionInteger right, Bounds <int> enforce) { var result = ConstraintOperationResult.Undecided; var sortedElements = SortedElements(); if (enforce.UpperBound < sortedElements.First().Key || enforce.LowerBound > sortedElements.Last().Key) { return(ConstraintOperationResult.Violated); } var remove = sortedElements. TakeWhile(v => v.Key < enforce.LowerBound). Select(v => v.Value). Concat(sortedElements. Reverse(). TakeWhile(v => v.Key > enforce.UpperBound). Select(v => v.Value)). SelectMany(i => i.ToList()). ToList(); if (remove.Any()) { result = ConstraintOperationResult.Propagated; foreach (var value in remove) { ((IVariable <int>)Index).Remove(value, out DomainOperationResult domainOperation); if (domainOperation == DomainOperationResult.EmptyDomain) { return(ConstraintOperationResult.Violated); } } left.Bounds = EvaluateBounds(left, null); } return(result); }
private Bounds <int> EvaluateBounds(ExpressionInteger left, ExpressionInteger right) { var elements = Elements(); return(new Bounds <int>(elements.Min(), elements.Max())); }
private int Evaluate(ExpressionInteger left, ExpressionInteger right) { return(this[Index.Value]); }
public async Task Solve() { await Task.Run(() => { crewCount = names.Count; flightsCount = crewRequirements.Count; VariableInteger[,] flightsToPersons = new VariableInteger[flightsCount, crewCount]; for (int i = 0; i < flightsCount; i++) { for (int j = 0; j < crewCount; j++) { flightsToPersons[i, j] = new VariableInteger("crew" + i.ToString() + j.ToString(), 0, 1); } } var variables = flightsToPersons.Cast <VariableInteger>().ToList(); // Constraints var constraints = new List <ConstraintInteger>(); // create constraints for each flight for (int f = 0; f < flightsCount; f++) { // size of crew for each flight must be equal to input value var crewForFlight = new ExpressionInteger[crewCount]; for (int p = 0; p < crewCount; p++) { crewForFlight[p] = flightsToPersons[f, p]; } var flightCrewCount = crewForFlight.Aggregate((a, b) => a + b); var crewSizesEqual = (flightCrewCount == crewRequirements[f][0]); constraints.Add(new ConstraintInteger(crewSizesEqual)); // person attributes (is steward, is hostess, speaks french, speaks spanish, speaks german) // sum of persons with each attribute must be greater than or equal to input value for (int a = 0; a < 5; a++) { crewForFlight = new ExpressionInteger[crewCount]; for (int p = 0; p < crewCount; p++) { crewForFlight[p] = (flightsToPersons[f, p] * personsAttributes[p][a]); } var sum = crewForFlight.Aggregate((x, y) => x + y); var attributesGreaterOrEqual = sum >= crewRequirements[f][a + 1]; constraints.Add(new ConstraintInteger(attributesGreaterOrEqual)); } } // crew member needs to have 2 flights break after his flight for (int f = 0; f < flightsCount - 2; f++) { for (int i = 0; i < crewCount; i++) { var cs = ((flightsToPersons[f, i] + flightsToPersons[f + 1, i] + flightsToPersons[f + 2, i]) <= 1); constraints.Add(new ConstraintInteger(cs)); } } // search for solution IVariable <int> optimiser = new VariableInteger("optimiser", 1, 100); IState <int> state = new StateInteger(variables, constraints); state.StartSearch(out StateOperationResult searchResult, optimiser, out IDictionary <string, IVariable <int> > solution, 10); if (searchResult == StateOperationResult.Unsatisfiable || searchResult == StateOperationResult.TimedOut) { MessageBox.Show("The result is timed out or unsatisfiable", "Crew Allocation Problem", MessageBoxButton.OK, MessageBoxImage.Error); } flightsToNames = new string[flightsCount, maxCrewSize]; for (int i = 0; i < flightsCount; i++) { try { int count = 0; for (int j = 0; j < crewCount; j++) { if (flightsToPersons[i, j].Value == 1) { flightsToNames[i, count] = names[j]; count++; } } } catch { } } }); }
public void AddConstraint(ExpressionInteger constr) { Constraints.Add(constr); }
public ExpressionInteger Not(ExpressionInteger a) { return(!a); }
public ExpressionInteger Or(ExpressionInteger a, ExpressionInteger b) { return(a | b); }
public ExpressionInteger And(ExpressionInteger a, ExpressionInteger b) { return(a & b); }