Example #1
0
        public void TestExpressionInteger()
        {
            var expr = new ExpressionInteger(0, true);

            Assert.True(expr.id == 0);
            Assert.True(expr.positive);
        }
Example #2
0
        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);
            }
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        private Bounds <int> EvaluateBounds(ExpressionInteger left, ExpressionInteger right)
        {
            var elements = Elements();

            return(new Bounds <int>(elements.Min(), elements.Max()));
        }
Example #6
0
 private int Evaluate(ExpressionInteger left, ExpressionInteger right)
 {
     return(this[Index.Value]);
 }
Example #7
0
        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 { }
                }
            });
        }
Example #8
0
 public void AddConstraint(ExpressionInteger constr)
 {
     Constraints.Add(constr);
 }
Example #9
0
 public ExpressionInteger Not(ExpressionInteger a)
 {
     return(!a);
 }
Example #10
0
 public ExpressionInteger Or(ExpressionInteger a, ExpressionInteger b)
 {
     return(a | b);
 }
Example #11
0
 public ExpressionInteger And(ExpressionInteger a, ExpressionInteger b)
 {
     return(a & b);
 }