예제 #1
0
        public IVariable Calculate(IMilpManager milpManager, OperationType type, params IVariable[] arguments)
        {
            if (!SupportsOperation(type, arguments)) throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
            if (arguments.All(a => a.IsConstant()))
            {
                var constantResult = (int) arguments[0].ConstantValue.Value%(int) arguments[1].ConstantValue.Value;
                return milpManager.FromConstant((int)constantResult);
            }
            IVariable numerator = arguments[0];
            IVariable denominator = arguments[1];

            var one = milpManager.FromConstant(1);
            var any = milpManager.CreateAnonymous(Domain.PositiveOrZeroInteger);
            any.Operation(OperationType.Multiplication, denominator).Set(ConstraintType.LessOrEqual, numerator);
            any.Operation(OperationType.Addition, one)
                .Operation(OperationType.Multiplication, denominator)
                .Set(ConstraintType.GreaterOrEqual, numerator.Operation(OperationType.Addition, one));

            IVariable result = milpManager.CreateAnonymous(Domain.PositiveOrZeroInteger);
            result.Set(ConstraintType.LessOrEqual, denominator);
            result.Set(ConstraintType.Equal,
                numerator.Operation(OperationType.Subtraction,
                    denominator.Operation(OperationType.Multiplication, any)));

            result.ConstantValue = numerator.ConstantValue%denominator.ConstantValue;
            result.Expression = $"{numerator.FullExpression()} % {denominator.FullExpression()}";
            return result;
        }
예제 #2
0
        public IVariable Calculate(IMilpManager milpManager, OperationType type, params IVariable[] arguments)
        {
            if (!SupportsOperation(type, arguments))
            {
                throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
            }
            if (arguments.All(a => a.IsConstant()))
            {
                var constantResult = (int)arguments[0].ConstantValue.Value % (int)arguments[1].ConstantValue.Value;
                return(milpManager.FromConstant((int)constantResult));
            }
            IVariable numerator   = arguments[0];
            IVariable denominator = arguments[1];

            var one = milpManager.FromConstant(1);
            var any = milpManager.CreateAnonymous(Domain.PositiveOrZeroInteger);

            any.Operation(OperationType.Multiplication, denominator).Set(ConstraintType.LessOrEqual, numerator);
            any.Operation(OperationType.Addition, one)
            .Operation(OperationType.Multiplication, denominator)
            .Set(ConstraintType.GreaterOrEqual, numerator.Operation(OperationType.Addition, one));

            IVariable result = milpManager.CreateAnonymous(Domain.PositiveOrZeroInteger);

            result.Set(ConstraintType.LessOrEqual, denominator);
            result.Set(ConstraintType.Equal,
                       numerator.Operation(OperationType.Subtraction,
                                           denominator.Operation(OperationType.Multiplication, any)));

            result.ConstantValue = numerator.ConstantValue % denominator.ConstantValue;
            result.Expression    = $"{numerator.FullExpression()} % {denominator.FullExpression()}";
            return(result);
        }
예제 #3
0
        public IVariable Calculate(IMilpManager milpManager, OperationType type, params IVariable[] arguments)
        {
            if(!SupportsOperation(type,arguments)) throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
            if (arguments.All(x => x.IsConstant()))
            {
                if (arguments[0].IsInteger())
                {
                    return milpManager.FromConstant(Math.Abs((int)arguments[0].ConstantValue.Value));
                }
                return milpManager.FromConstant(Math.Abs(arguments[0].ConstantValue.Value));
            }

            var number = arguments[0];
            var numberNegated = number.Operation(OperationType.Negation);
            var result = milpManager.CreateAnonymous(number.IsInteger() ? Domain.PositiveOrZeroInteger : Domain.PositiveOrZeroReal);

            result.Set(ConstraintType.GreaterOrEqual, number)
                .Set(ConstraintType.GreaterOrEqual, numberNegated);

            milpManager.Operation(OperationType.Addition,
                    result.Operation(OperationType.IsEqual, number),
                    result.Operation(OperationType.IsEqual, numberNegated))
                .Set(ConstraintType.GreaterOrEqual, milpManager.FromConstant(1));

            result.ConstantValue = number.ConstantValue.HasValue ? Math.Abs(number.ConstantValue.Value) : number.ConstantValue;
            result.Expression = $"|{number.FullExpression()}|";
            return result;
        }
예제 #4
0
        public IEnumerable<IVariable> Calculate(IMilpManager milpManager, CompositeOperationType type, ICompositeOperationParameters parameters,
            params IVariable[] arguments)
        {
            if (!SupportsOperation(type, parameters, arguments)) throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, parameters, arguments));
            var typedParameters = (ArrayGetParameters) parameters;
            if (typedParameters.Index.IsConstant())
            {
                return new[] { arguments[(int) typedParameters.Index.ConstantValue.Value] };
            }

            var index = typedParameters.Index;
            var result = milpManager.CreateAnonymous(arguments.Skip(1)
                    .Aggregate(arguments[0].Domain, (domain, next) => domain.LowestEncompassingDomain(next.Domain)));

            for (int i = 0; i < arguments.Length; ++i)
            {
                milpManager.FromConstant(i).Operation(OperationType.IsEqual, index)
                    .Operation(OperationType.MaterialImplication, result.Operation(OperationType.IsEqual, arguments[i]))
                    .MakeTrue();
            }

            result.ConstantValue = index.ConstantValue.HasValue ? arguments[(int)index.ConstantValue.Value].ConstantValue : null;
            result.Expression = $"arrayGet(index: {index.FullExpression()}, {string.Join(", ", arguments.Select(a => a.FullExpression()).ToArray())})";

            return new[] {result};
        }
예제 #5
0
        public IVariable Calculate(IMilpManager milpManager, OperationType type, params IVariable[] arguments)
        {
            if (!SupportsOperation(type, arguments))
            {
                throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
            }
            if (arguments.All(x => x.IsConstant()))
            {
                if (arguments[0].IsInteger())
                {
                    return(milpManager.FromConstant(Math.Abs((int)arguments[0].ConstantValue.Value)));
                }
                return(milpManager.FromConstant(Math.Abs(arguments[0].ConstantValue.Value)));
            }

            var number        = arguments[0];
            var numberNegated = number.Operation(OperationType.Negation);
            var result        = milpManager.CreateAnonymous(number.IsInteger() ? Domain.PositiveOrZeroInteger : Domain.PositiveOrZeroReal);

            result.Set(ConstraintType.GreaterOrEqual, number)
            .Set(ConstraintType.GreaterOrEqual, numberNegated);

            milpManager.Operation(OperationType.Addition,
                                  result.Operation(OperationType.IsEqual, number),
                                  result.Operation(OperationType.IsEqual, numberNegated))
            .Set(ConstraintType.GreaterOrEqual, milpManager.FromConstant(1));

            result.ConstantValue = number.ConstantValue.HasValue ? Math.Abs(number.ConstantValue.Value) : number.ConstantValue;
            result.Expression    = $"|{number.FullExpression()}|";
            return(result);
        }
        public IEnumerable <IVariable> Calculate(IMilpManager milpManager, CompositeOperationType type, ICompositeOperationParameters parameters,
                                                 params IVariable[] arguments)
        {
            if (!SupportsOperation(type, parameters, arguments))
            {
                throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, parameters, arguments));
            }
            var typedParameters = parameters as ApproximateParameters;
            var x = arguments.First();

            if (arguments.All(i => i.IsConstant()))
            {
                return(new [] { milpManager.FromConstant(typedParameters.Function(x.ConstantValue.Value)) });
            }

            var one       = milpManager.FromConstant(1);
            var points    = typedParameters.Arguments.Select(a => Tuple.Create(milpManager.FromConstant(a), milpManager.FromConstant(typedParameters.Function(a)))).ToArray();
            var variables = points.Select(p => milpManager.CreateAnonymous(typedParameters.ArgumentMustBeOnAGrid ? Domain.BinaryInteger : Domain.PositiveOrZeroReal).Set(ConstraintType.LessOrEqual, one)).ToArray();

            x.Set(ConstraintType.Equal, milpManager.Operation(OperationType.Addition, points.Select((point, index) => variables[index].Operation(OperationType.Multiplication, point.Item1)).ToArray()));
            var y = milpManager.Operation(OperationType.Addition, points.Select((point, index) => variables[index].Operation(OperationType.Multiplication, point.Item2)).ToArray());

            milpManager.Operation(OperationType.Addition, variables).Set(ConstraintType.Equal, one);
            milpManager.Set(CompositeConstraintType.SpecialOrderedSetType2, variables.First(), variables.Skip(1).ToArray());

            y.ConstantValue = x.IsConstant() ? typedParameters.Function(x.ConstantValue.Value) : (double?)null;
            y.Expression    = $"approximation({typedParameters.FunctionDescription})";

            return(new[] { y });
        }
예제 #7
0
        private static IEnumerable <IVariable> CalculateForVariable(IMilpManager milpManager, IVariable[] arguments, uint decompositionBase)
        {
            List <Tuple <IVariable, int> > variables =
                Enumerable.Range(0, GetDigitsCount(milpManager, decompositionBase))
                .Select(i =>
            {
                var baseRaised = (int)Math.Pow(decompositionBase, i);
                var variable   = milpManager.CreateAnonymous(decompositionBase == 2 ? Domain.BinaryInteger : Domain.PositiveOrZeroInteger);
                if (decompositionBase > 2)
                {
                    variable = variable.Set(ConstraintType.LessOrEqual, milpManager.FromConstant((int)decompositionBase - 1));
                }
                return(Tuple.Create(variable, baseRaised));
            })
                .ToList();

            milpManager.Operation(OperationType.Addition,
                                  variables.Select(v => v.Item1.Operation(OperationType.Multiplication, milpManager.FromConstant(v.Item2)))
                                  .ToArray()).Set(ConstraintType.Equal, arguments[0]);

            return(variables.Select((v, index) => {
                var result = v.Item1;
                result.Expression = $"decomposition(digit: {index}, base: {decompositionBase}, {arguments[0].FullExpression()})";
                return result;
            }));
        }
예제 #8
0
        public IEnumerable <IVariable> Calculate(IMilpManager milpManager, CompositeOperationType type, ICompositeOperationParameters parameters,
                                                 params IVariable[] arguments)
        {
            if (!SupportsOperation(type, parameters, arguments))
            {
                throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, parameters, arguments));
            }
            var typedParameters = (ArrayGetParameters)parameters;

            if (typedParameters.Index.IsConstant())
            {
                return(new[] { arguments[(int)typedParameters.Index.ConstantValue.Value] });
            }

            var index  = typedParameters.Index;
            var result = milpManager.CreateAnonymous(arguments.Skip(1)
                                                     .Aggregate(arguments[0].Domain, (domain, next) => domain.LowestEncompassingDomain(next.Domain)));

            for (int i = 0; i < arguments.Length; ++i)
            {
                milpManager.FromConstant(i).Operation(OperationType.IsEqual, index)
                .Operation(OperationType.MaterialImplication, result.Operation(OperationType.IsEqual, arguments[i]))
                .MakeTrue();
            }

            result.ConstantValue = index.ConstantValue.HasValue ? arguments[(int)index.ConstantValue.Value].ConstantValue : null;
            result.Expression    = $"arrayGet(index: {index.FullExpression()}, {string.Join(", ", arguments.Select(a => a.FullExpression()).ToArray())})";

            return(new[] { result });
        }
예제 #9
0
        public IVariable Set(IMilpManager milpManager, CompositeConstraintType type, ICompositeConstraintParameters parameters,
                             IVariable leftVariable, params IVariable[] rightVariable)
        {
            var maximumIntegerValue = milpManager.FromConstant(milpManager.MaximumIntegerValue);
            var one = milpManager.FromConstant(1);

            var allVariables = new[] { leftVariable }.Concat(rightVariable).ToArray();
            var boundaryVariables = allVariables.Select(v => milpManager.CreateAnonymous(Domain.BinaryInteger)).ToArray();

            milpManager.Operation(OperationType.Addition, boundaryVariables).Set(ConstraintType.LessOrEqual, one);

            for (int i = 0; i < allVariables.Length; ++i)
            {
                IVariable sum = boundaryVariables[i];
                if (i < allVariables.Length - 1)
                {
                    sum = sum.Operation(OperationType.Addition, boundaryVariables[i + 1]);
                }
                allVariables[i]
                .Set(ConstraintType.LessOrEqual, sum.Operation(OperationType.Multiplication, maximumIntegerValue))
                .Set(ConstraintType.GreaterOrEqual, sum.Operation(OperationType.Multiplication, maximumIntegerValue).Operation(OperationType.Negation));
            }

            return(leftVariable);
        }
        public IVariable Calculate(IMilpManager milpManager, OperationType type, params IVariable[] arguments)
        {
            if (!SupportsOperation(type, arguments))
            {
                throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
            }
            if (arguments.All(a => a.IsConstant()))
            {
                return(milpManager.FromConstant(arguments[0].ConstantValue.Value > arguments[1].ConstantValue.Value ? 1 : 0));
            }
            var result = milpManager.CreateAnonymous(Domain.BinaryInteger);

            var first  = arguments[0];
            var second = arguments[1];

            second.Operation(OperationType.Subtraction, first)
            .Operation(OperationType.Addition,
                       result.Operation(OperationType.Multiplication, milpManager.FromConstant(milpManager.IntegerInfinity)))
            .Set(ConstraintType.GreaterOrEqual, milpManager.FromConstant(0))
            .Set(ConstraintType.LessOrEqual, milpManager.FromConstant(milpManager.IntegerInfinity - (arguments.Any(a => a.IsReal()) ? milpManager.Epsilon : 1)));

            result.ConstantValue = arguments.All(a => a.ConstantValue.HasValue)
                ? arguments[0].ConstantValue > arguments[1].ConstantValue ? 1 : 0
                : (double?)null;
            result.Expression = $"{arguments[0].FullExpression()} ?> {arguments[1].FullExpression()}";
            return(result);
        }
예제 #11
0
        private static IEnumerable<IVariable> CalculateForVariable(IMilpManager milpManager, IVariable[] arguments, uint decompositionBase)
        {
            List<Tuple<IVariable, int>> variables =
                Enumerable.Range(0, GetDigitsCount(milpManager, decompositionBase))
                    .Select(i =>
                    {
                        var baseRaised = (int)Math.Pow(decompositionBase, i);
                        var variable = milpManager.CreateAnonymous(decompositionBase == 2 ? Domain.BinaryInteger : Domain.PositiveOrZeroInteger);
                        if (decompositionBase > 2)
                        {
                            variable = variable.Set(ConstraintType.LessOrEqual,milpManager.FromConstant((int) decompositionBase - 1));
                        }
                        return Tuple.Create(variable, baseRaised);
                    })
                    .ToList();

            milpManager.Operation(OperationType.Addition,
                variables.Select(v => v.Item1.Operation(OperationType.Multiplication, milpManager.FromConstant(v.Item2)))
                    .ToArray()).Set(ConstraintType.Equal, arguments[0]);

            return variables.Select((v, index) => {
                var result = v.Item1;
                result.Expression = $"decomposition(digit: {index}, base: {decompositionBase}, {arguments[0].FullExpression()})";
                return result;
            });
        }
예제 #12
0
        public IVariable Set(IMilpManager milpManager, ConstraintType type, IVariable leftVariable, IVariable rightVariable)
        {
            IVariable any = milpManager.CreateAnonymous(Domain.AnyInteger);
            leftVariable.Set(ConstraintType.Equal,any.Operation(OperationType.Multiplication, rightVariable));

            return leftVariable;
        }
예제 #13
0
        public IVariable Set(IMilpManager milpManager, ConstraintType type, IVariable leftVariable, IVariable rightVariable)
        {
            IVariable any = milpManager.CreateAnonymous(Domain.AnyInteger);

            leftVariable.Set(ConstraintType.Equal, any.Operation(OperationType.Multiplication, rightVariable));

            return(leftVariable);
        }
예제 #14
0
        private static IVariable CalculateInternal(IMilpManager milpManager, params IVariable[] arguments)
        {
            var a = arguments[0];
            var b = arguments[1];
            var gcd = milpManager.CreateAnonymous(Domain.PositiveOrZeroInteger);
            var x = milpManager.CreateAnonymous(Domain.PositiveOrZeroInteger);
            var y = milpManager.CreateAnonymous(Domain.PositiveOrZeroInteger);
            var m = milpManager.CreateAnonymous(Domain.AnyInteger);
            var n = milpManager.CreateAnonymous(Domain.AnyInteger);

            gcd.Set(ConstraintType.GreaterOrEqual, milpManager.FromConstant(1));
            a.Set(ConstraintType.Equal, x.Operation(OperationType.Multiplication, gcd));
            b.Set(ConstraintType.Equal, y.Operation(OperationType.Multiplication, gcd));
            gcd.Set(ConstraintType.Equal, m.Operation(OperationType.Multiplication, a).Operation(OperationType.Addition, n.Operation(OperationType.Multiplication, b)));

            gcd.ConstantValue = a.ConstantValue.HasValue && b.ConstantValue.HasValue
                ? Gcd((int) a.ConstantValue.Value, (int) b.ConstantValue.Value)
                : (double?) null;
            gcd.Expression = $"gcd({a.FullExpression()}, {b.FullExpression()})";
            return gcd;
        }
예제 #15
0
        private static IVariable CalculateInternal(IMilpManager milpManager, params IVariable[] arguments)
        {
            var a   = arguments[0];
            var b   = arguments[1];
            var gcd = milpManager.CreateAnonymous(Domain.PositiveOrZeroInteger);
            var x   = milpManager.CreateAnonymous(Domain.PositiveOrZeroInteger);
            var y   = milpManager.CreateAnonymous(Domain.PositiveOrZeroInteger);
            var m   = milpManager.CreateAnonymous(Domain.AnyInteger);
            var n   = milpManager.CreateAnonymous(Domain.AnyInteger);

            gcd.Set(ConstraintType.GreaterOrEqual, milpManager.FromConstant(1));
            a.Set(ConstraintType.Equal, x.Operation(OperationType.Multiplication, gcd));
            b.Set(ConstraintType.Equal, y.Operation(OperationType.Multiplication, gcd));
            gcd.Set(ConstraintType.Equal, m.Operation(OperationType.Multiplication, a).Operation(OperationType.Addition, n.Operation(OperationType.Multiplication, b)));

            gcd.ConstantValue = a.ConstantValue.HasValue && b.ConstantValue.HasValue
                ? Gcd((int)a.ConstantValue.Value, (int)b.ConstantValue.Value)
                : (double?)null;
            gcd.Expression = $"gcd({a.FullExpression()}, {b.FullExpression()})";
            return(gcd);
        }
예제 #16
0
        private static IVariable CalculateForTwoVariables(IMilpManager milpManager, OperationType type, IVariable[] arguments)
        {
            if (arguments.All(a => a.IsConstant()))
            {
                var values = arguments.Select(a => a.ConstantValue.Value);
                var result = type == OperationType.Maximum ? values.Max() : values.Min();
                if (arguments.All(a => a.IsInteger()))
                {
                    return(milpManager.FromConstant((int)result));
                }
                else
                {
                    return(milpManager.FromConstant(result));
                }
            }
            var first  = arguments[0];
            var second = arguments[1];

            IVariable max = milpManager.CreateAnonymous(CalculateDomain(arguments));
            IVariable min = milpManager.CreateAnonymous(CalculateDomain(arguments));

            max.Set(ConstraintType.GreaterOrEqual, first);
            max.Set(ConstraintType.GreaterOrEqual, second);
            min.Set(ConstraintType.LessOrEqual, first);
            min.Set(ConstraintType.LessOrEqual, second);

            max.Operation(OperationType.Subtraction, min)
            .Set(ConstraintType.Equal,
                 first.Operation(OperationType.Subtraction, second).Operation(OperationType.AbsoluteValue));

            max.ConstantValue = arguments.All(a => a.ConstantValue.HasValue)
                ? Math.Max(arguments[0].ConstantValue.Value, arguments[1].ConstantValue.Value)
                : (double?)null;
            min.ConstantValue = arguments.All(a => a.ConstantValue.HasValue)
                ? Math.Min(arguments[0].ConstantValue.Value, arguments[1].ConstantValue.Value)
                : (double?)null;
            max.Expression = $"max({arguments[0].FullExpression()}, {arguments[1].FullExpression()}";
            min.Expression = $"min({arguments[0].FullExpression()}, {arguments[1].FullExpression()}";
            return(type == OperationType.Maximum ? max : min);
        }
예제 #17
0
        private static IVariable CalculateForTwoVariables(IMilpManager milpManager, OperationType type, IVariable[] arguments)
        {
            if (arguments.All(a => a.IsConstant()))
            {
                var values = arguments.Select(a => a.ConstantValue.Value);
                var result = type == OperationType.Maximum ? values.Max() : values.Min();
                if (arguments.All(a => a.IsInteger()))
                {
                    return milpManager.FromConstant((int) result);
                }
                else
                {
                    return milpManager.FromConstant(result);
                }
            }
            var first = arguments[0];
            var second = arguments[1];

            IVariable max = milpManager.CreateAnonymous(CalculateDomain(arguments));
            IVariable min = milpManager.CreateAnonymous(CalculateDomain(arguments));

            max.Set(ConstraintType.GreaterOrEqual, first);
            max.Set(ConstraintType.GreaterOrEqual, second);
            min.Set(ConstraintType.LessOrEqual, first);
            min.Set(ConstraintType.LessOrEqual, second);

            max.Operation(OperationType.Subtraction, min)
                .Set(ConstraintType.Equal,
                    first.Operation(OperationType.Subtraction, second).Operation(OperationType.AbsoluteValue));

            max.ConstantValue = arguments.All(a => a.ConstantValue.HasValue)
                ? Math.Max(arguments[0].ConstantValue.Value, arguments[1].ConstantValue.Value)
                : (double?)null;
            min.ConstantValue = arguments.All(a => a.ConstantValue.HasValue)
                ? Math.Min(arguments[0].ConstantValue.Value, arguments[1].ConstantValue.Value)
                : (double?)null;
            max.Expression = $"max({arguments[0].FullExpression()}, {arguments[1].FullExpression()}";
            min.Expression = $"min({arguments[0].FullExpression()}, {arguments[1].FullExpression()}";
            return type == OperationType.Maximum ? max : min;
        }
예제 #18
0
        public IVariable Calculate(IMilpManager milpManager, GoalType type, params IVariable[] arguments)
        {
            if (!SupportsOperation(type, arguments)) throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
            if (arguments.All(a => a.IsConstant()))
            {
                return milpManager.Operation(OperationType.Maximum, arguments);
            }

            var result = milpManager.CreateAnonymous(arguments.Any(a => a.IsReal()) ? Domain.AnyReal : Domain.AnyInteger);
            arguments.Aggregate(milpManager.FromConstant(0),(existing, next) => existing.Operation(OperationType.Disjunction, result.Operation(OperationType.IsEqual, next)))
                .Set(ConstraintType.Equal, milpManager.FromConstant(1));

            return result;
        }
예제 #19
0
        public IVariable Calculate(IMilpManager milpManager, GoalType type, params IVariable[] arguments)
        {
            if (!SupportsOperation(type, arguments)) throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
            if (arguments.All(a => a.IsConstant()))
            {
                return milpManager.Operation(OperationType.Minimum, arguments);
            }

            var result = milpManager.CreateAnonymous(arguments.Any(a => a.IsReal()) ? Domain.AnyReal : Domain.AnyInteger);
            foreach (var argument in arguments)
            {
                result.Set(ConstraintType.LessOrEqual, argument);
            }

            return result;
        }
예제 #20
0
        public IVariable Calculate(IMilpManager milpManager, OperationType type, params IVariable[] arguments)
        {
            if (!SupportsOperation(type, arguments))
            {
                throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
            }
            if (arguments.All(a => a.IsConstant()))
            {
                var constantResult = arguments[0].ConstantValue.Value / arguments[1].ConstantValue.Value;
                if (arguments.All(a => a.IsInteger()))
                {
                    return(milpManager.FromConstant((int)constantResult));
                }
                else
                {
                    return(milpManager.FromConstant(constantResult));
                }
            }
            var domain = CalculateDomain(arguments);

            if (IsDividingByConstant(arguments))
            {
                var finalDomain    = arguments.All(x => x.IsConstant()) ? domain.MakeConstant() : domain;
                var physicalResult = milpManager.DivideVariableByConstant(arguments[0], arguments[1], finalDomain);
                physicalResult.ConstantValue = arguments[0].ConstantValue / arguments[1].ConstantValue;
                physicalResult.Expression    = $"{arguments[0].FullExpression()} / {arguments[1].FullExpression()}";
                return(physicalResult);
            }

            IVariable one    = milpManager.FromConstant(1);
            var       result = milpManager.CreateAnonymous(domain);

            result.Operation(OperationType.Multiplication, arguments[1])
            .Set(ConstraintType.LessOrEqual, arguments[0]);
            result.Operation(OperationType.Addition, one)
            .Operation(OperationType.Multiplication, arguments[1])
            .Set(ConstraintType.GreaterOrEqual, arguments[0].Operation(OperationType.Addition, one));

            result.ConstantValue = arguments.All(a => a.ConstantValue.HasValue)
                ? arguments[1].ConstantValue.Value == 0
                    ? (double?)null
                    : (long)arguments[0].ConstantValue.Value / (long)arguments[1].ConstantValue.Value
                : null;
            result.Expression = $"{arguments[0].FullExpression()} / {arguments[1].FullExpression()}";
            return(result);
        }
예제 #21
0
        public IVariable Set(IMilpManager milpManager, CompositeConstraintType type, ICompositeConstraintParameters parameters,
            IVariable leftVariable, params IVariable[] rightVariable)
        {
            var one = milpManager.FromConstant(1);
            var maximumIntegerValue = milpManager.FromConstant(milpManager.MaximumIntegerValue);

            var allVariables = new[] {leftVariable}.Concat(rightVariable).ToArray();
            var boundaryVariables = allVariables.Select(v => milpManager.CreateAnonymous(Domain.BinaryInteger)).ToArray();
            milpManager.Operation(OperationType.Addition, boundaryVariables).Set(ConstraintType.LessOrEqual, one);
            foreach (var pair in allVariables.Zip(boundaryVariables, Tuple.Create))
            {
                pair.Item1
                    .Set(ConstraintType.LessOrEqual, pair.Item2.Operation(OperationType.Multiplication, maximumIntegerValue))
                    .Set(ConstraintType.GreaterOrEqual, pair.Item2.Operation(OperationType.Multiplication, maximumIntegerValue).Operation(OperationType.Negation));
            }

            return leftVariable;
        }
        public IVariable Calculate(IMilpManager milpManager, GoalType type, params IVariable[] arguments)
        {
            if (!SupportsOperation(type, arguments))
            {
                throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
            }
            if (arguments.All(a => a.IsConstant()))
            {
                return(milpManager.Operation(OperationType.Maximum, arguments));
            }

            var result = milpManager.CreateAnonymous(arguments.Any(a => a.IsReal()) ? Domain.AnyReal : Domain.AnyInteger);

            arguments.Aggregate(milpManager.FromConstant(0), (existing, next) => existing.Operation(OperationType.Disjunction, result.Operation(OperationType.IsEqual, next)))
            .Set(ConstraintType.Equal, milpManager.FromConstant(1));

            return(result);
        }
예제 #23
0
        public IEnumerable <IVariable> Calculate(IMilpManager milpManager, CompositeOperationType type, ICompositeOperationParameters parameters,
                                                 params IVariable[] arguments)
        {
            if (!SupportsOperation(type, parameters, arguments))
            {
                throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, parameters, arguments));
            }
            var options = parameters as LoopParameters;

            var totalBound = milpManager.CreateAnonymous(Domain.PositiveOrZeroInteger);

            totalBound.Set(ConstraintType.LessOrEqual, milpManager.FromConstant(options.MaxIterations));

            options.BeforeLoopAction(totalBound, arguments);

            for (int i = 1; i <= options.MaxIterations; ++i)
            {
                var counter   = milpManager.FromConstant(i);
                var isLooping = counter.Operation(OperationType.IsLessOrEqual, totalBound);

                options.BeforeIterationAction(counter, isLooping, totalBound, arguments);

                for (int v = 0; v < arguments.Length; ++v)
                {
                    if (options.BeforeBody.Length > v)
                    {
                        options.BeforeBody[v](arguments[v], counter, isLooping, totalBound, arguments);
                    }

                    arguments[v] = milpManager.Operation(OperationType.Condition, isLooping, options.Body[v](arguments[v], counter, isLooping, totalBound, arguments), arguments[v]);

                    if (options.AfterBody.Length > v)
                    {
                        options.AfterBody[v](arguments[v], counter, isLooping, totalBound, arguments);
                    }
                }

                options.AfterIterationAction(counter, isLooping, totalBound, arguments);
            }

            options.AfterLoopAction(totalBound, arguments);

            return(arguments.Concat(new[] { totalBound }).ToArray());
        }
예제 #24
0
        public IVariable Set(IMilpManager milpManager, CompositeConstraintType type, ICompositeConstraintParameters parameters,
                             IVariable leftVariable, params IVariable[] rightVariable)
        {
            var one = milpManager.FromConstant(1);
            var maximumIntegerValue = milpManager.FromConstant(milpManager.MaximumIntegerValue);

            var allVariables = new[] { leftVariable }.Concat(rightVariable).ToArray();
            var boundaryVariables = allVariables.Select(v => milpManager.CreateAnonymous(Domain.BinaryInteger)).ToArray();

            milpManager.Operation(OperationType.Addition, boundaryVariables).Set(ConstraintType.LessOrEqual, one);
            foreach (var pair in allVariables.Zip(boundaryVariables, Tuple.Create))
            {
                pair.Item1
                .Set(ConstraintType.LessOrEqual, pair.Item2.Operation(OperationType.Multiplication, maximumIntegerValue))
                .Set(ConstraintType.GreaterOrEqual, pair.Item2.Operation(OperationType.Multiplication, maximumIntegerValue).Operation(OperationType.Negation));
            }

            return(leftVariable);
        }
        public IVariable Calculate(IMilpManager milpManager, GoalType type, params IVariable[] arguments)
        {
            if (!SupportsOperation(type, arguments))
            {
                throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
            }
            if (arguments.All(a => a.IsConstant()))
            {
                return(milpManager.Operation(OperationType.Minimum, arguments));
            }

            var result = milpManager.CreateAnonymous(arguments.Any(a => a.IsReal()) ? Domain.AnyReal : Domain.AnyInteger);

            foreach (var argument in arguments)
            {
                result.Set(ConstraintType.LessOrEqual, argument);
            }

            return(result);
        }
예제 #26
0
        public IVariable Calculate(IMilpManager milpManager, OperationType type, params IVariable[] arguments)
        {
            if (!SupportsOperation(type, arguments)) throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
            if (arguments.All(a => a.IsConstant()))
            {
                var constantResult = arguments[0].ConstantValue.Value/arguments[1].ConstantValue.Value;
                if (arguments.All(a => a.IsInteger()))
                {
                    return milpManager.FromConstant((int) constantResult);
                }
                else
                {
                    return milpManager.FromConstant(constantResult);
                }
            }
            var domain = CalculateDomain(arguments);
            if (IsDividingByConstant(arguments))
            {
                var finalDomain = arguments.All(x => x.IsConstant()) ? domain.MakeConstant() : domain;
                var physicalResult = milpManager.DivideVariableByConstant(arguments[0], arguments[1], finalDomain);
                physicalResult.ConstantValue = arguments[0].ConstantValue/arguments[1].ConstantValue;
                physicalResult.Expression = $"{arguments[0].FullExpression()} / {arguments[1].FullExpression()}";
                return physicalResult;
            }

            IVariable one = milpManager.FromConstant(1);
            var result = milpManager.CreateAnonymous(domain);
            result.Operation(OperationType.Multiplication, arguments[1])
                .Set(ConstraintType.LessOrEqual, arguments[0]);
            result.Operation(OperationType.Addition, one)
                .Operation(OperationType.Multiplication, arguments[1])
                .Set(ConstraintType.GreaterOrEqual, arguments[0].Operation(OperationType.Addition, one));

            result.ConstantValue = arguments.All(a => a.ConstantValue.HasValue)
                ? arguments[1].ConstantValue.Value == 0
                    ? (double?)null
                    : (long)arguments[0].ConstantValue.Value / (long)arguments[1].ConstantValue.Value
                : null;
            result.Expression = $"{arguments[0].FullExpression()} / {arguments[1].FullExpression()}";
            return result;
        }
예제 #27
0
        public IVariable Calculate(IMilpManager milpManager, OperationType type, params IVariable[] arguments)
        {
            if (!SupportsOperation(type, arguments))
            {
                throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
            }
            if (arguments.All(a => a.IsConstant()))
            {
                return(milpManager.FromConstant(arguments.Select(a => (int)a.ConstantValue).Aggregate(Math.Min)));
            }
            var variable       = milpManager.CreateAnonymous(Domain.BinaryInteger);
            var sum            = milpManager.Operation(OperationType.Addition, arguments);
            var argumentsCount = arguments.Length;

            sum.Operation(OperationType.Subtraction,
                          milpManager.FromConstant(argumentsCount).Operation(OperationType.Multiplication, variable))
            .Set(ConstraintType.LessOrEqual, milpManager.FromConstant(argumentsCount - 1))
            .Set(ConstraintType.GreaterOrEqual, milpManager.FromConstant(0));

            variable.ConstantValue = arguments.Aggregate((double?)1.0, (a, b) => a.HasValue && b.ConstantValue.HasValue ? Math.Min(a.Value, b.ConstantValue.Value) : (double?)null);
            variable.Expression    = $"{string.Join(" && ", arguments.Select(a => a.FullExpression()).ToArray())}";
            return(variable);
        }
예제 #28
0
        public IVariable Set(IMilpManager milpManager, CompositeConstraintType type, ICompositeConstraintParameters parameters,
            IVariable leftVariable, params IVariable[] rightVariable)
        {
            var maximumIntegerValue = milpManager.FromConstant(milpManager.MaximumIntegerValue);
            var one = milpManager.FromConstant(1);

            var allVariables = new[] { leftVariable }.Concat(rightVariable).ToArray();
            var boundaryVariables = allVariables.Select(v => milpManager.CreateAnonymous(Domain.BinaryInteger)).ToArray();
            milpManager.Operation(OperationType.Addition, boundaryVariables).Set(ConstraintType.LessOrEqual, one);

            for (int i = 0; i < allVariables.Length; ++i)
            {
                IVariable sum = boundaryVariables[i];
                if (i < allVariables.Length - 1)
                {
                    sum = sum.Operation(OperationType.Addition, boundaryVariables[i + 1]);
                }
                allVariables[i]
                    .Set(ConstraintType.LessOrEqual, sum.Operation(OperationType.Multiplication, maximumIntegerValue))
                    .Set(ConstraintType.GreaterOrEqual, sum.Operation(OperationType.Multiplication, maximumIntegerValue).Operation(OperationType.Negation));
            }

            return leftVariable;
        }
예제 #29
0
        public IVariable Calculate(IMilpManager milpManager, OperationType type, params IVariable[] arguments)
        {
            if (!SupportsOperation(type, arguments)) throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
            if (arguments.All(a => a.IsConstant()))
            {
                return milpManager.FromConstant(arguments[0].ConstantValue.Value > arguments[1].ConstantValue.Value ? 1 : 0);
            }
            var result = milpManager.CreateAnonymous(Domain.BinaryInteger);

            var first = arguments[0];
            var second = arguments[1];

            second.Operation(OperationType.Subtraction, first)
                .Operation(OperationType.Addition,
                    result.Operation(OperationType.Multiplication, milpManager.FromConstant(milpManager.IntegerInfinity)))
                .Set(ConstraintType.GreaterOrEqual, milpManager.FromConstant(0))
                .Set(ConstraintType.LessOrEqual, milpManager.FromConstant(milpManager.IntegerInfinity - (arguments.Any(a => a.IsReal()) ? milpManager.Epsilon : 1)));

            result.ConstantValue = arguments.All(a => a.ConstantValue.HasValue)
                ? arguments[0].ConstantValue > arguments[1].ConstantValue ? 1 : 0
                : (double?)null;
            result.Expression = $"{arguments[0].FullExpression()} ?> {arguments[1].FullExpression()}";
            return result;
        }
예제 #30
0
        public IEnumerable<IVariable> Calculate(IMilpManager milpManager, CompositeOperationType type, ICompositeOperationParameters parameters,
            params IVariable[] arguments)
        {
            if (!SupportsOperation(type, parameters, arguments)) throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, parameters, arguments));
            var typedParameters = parameters as Approximate2DParameters;
            var x = arguments.First();
            var y = arguments.Skip(1).First();

            if (arguments.All(i => i.IsConstant()))
            {
                return new[] { milpManager.FromConstant(typedParameters.Function(x.ConstantValue.Value, y.ConstantValue.Value)) };
            }

            var one = milpManager.FromConstant(1);

            var variables =
                Enumerable.Range(0, typedParameters.ArgumentsX.Count()).Select(p =>
                Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(q =>
                    milpManager.CreateAnonymous(typedParameters.ArgumentMustBeOnAGrid
                        ? Domain.BinaryInteger
                        : Domain.PositiveOrZeroReal).Set(ConstraintType.LessOrEqual, one)).ToArray())
                .ToArray();

            x.Set(ConstraintType.Equal, milpManager.Operation(OperationType.Addition,
                Enumerable.Range(0, typedParameters.ArgumentsX.Count()).SelectMany(indexX =>
                Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY =>
                    variables[indexX][indexY].Operation(OperationType.Multiplication, milpManager.FromConstant(typedParameters.ArgumentsX.ElementAt(indexX))))).ToArray()
            ));
            y.Set(ConstraintType.Equal, milpManager.Operation(OperationType.Addition,
                Enumerable.Range(0, typedParameters.ArgumentsX.Count()).SelectMany(indexX =>
                Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY =>
                    variables[indexX][indexY].Operation(OperationType.Multiplication, milpManager.FromConstant(typedParameters.ArgumentsY.ElementAt(indexY))))).ToArray()
            ));
            var z = milpManager.Operation(OperationType.Addition,
                Enumerable.Range(0, typedParameters.ArgumentsX.Count()).SelectMany(indexX =>
                Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY =>
                    variables[indexX][indexY].Operation(OperationType.Multiplication, milpManager.FromConstant(typedParameters.Function(typedParameters.ArgumentsX.ElementAt(indexX), typedParameters.ArgumentsY.ElementAt(indexY)))))).ToArray()
            );

            milpManager.Operation(OperationType.Addition, variables.SelectMany(v => v).ToArray()).Set(ConstraintType.Equal, one);

            var xSet = Enumerable.Range(0, typedParameters.ArgumentsX.Count()).Select(indexX => milpManager.Operation(OperationType.Addition, Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY => variables[indexX][indexY]).ToArray())).ToArray();
             milpManager.Set(CompositeConstraintType.SpecialOrderedSetType2, xSet.First(), xSet.Skip(1).ToArray());

            var ySet = Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY => milpManager.Operation(OperationType.Addition, Enumerable.Range(0, typedParameters.ArgumentsX.Count()).Select(indexX => variables[indexX][indexY]).ToArray())).ToArray();
            milpManager.Set(CompositeConstraintType.SpecialOrderedSetType2, ySet.First(), ySet.Skip(1).ToArray());

            if (!typedParameters.ArgumentMustBeOnAGrid)
            {
                var triangleSet = Enumerable.Range(0, typedParameters.ArgumentsY.Count()).SelectMany(indexY =>
                {
                    var variablesToSet = Enumerable.Range(0, typedParameters.ArgumentsX.Count()).Where(indexX => indexX + indexY < variables[indexX].Length).Select(indexX => variables[indexX][indexX + indexY]).ToArray();
                    if (variablesToSet.Any())
                    {
                        return new[] {milpManager.Operation(OperationType.Addition, variablesToSet)};
                    }

                    return new IVariable[0];
                }).ToArray();

                milpManager.Set(CompositeConstraintType.SpecialOrderedSetType2, triangleSet.First(), triangleSet.Skip(1).ToArray());
            }

            z.ConstantValue = x.IsConstant() && y.IsConstant() ? typedParameters.Function(x.ConstantValue.Value, y.ConstantValue.Value) : (double?)null;
            z.Expression = $"approximation2D({typedParameters.FunctionDescription})";

            return new[] { z };
        }
예제 #31
0
        public IEnumerable <IVariable> Calculate(IMilpManager milpManager, CompositeOperationType type, ICompositeOperationParameters parameters,
                                                 params IVariable[] arguments)
        {
            if (!SupportsOperation(type, parameters, arguments))
            {
                throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, parameters, arguments));
            }
            var typedParameters = parameters as Approximate2DParameters;
            var x = arguments.First();
            var y = arguments.Skip(1).First();

            if (arguments.All(i => i.IsConstant()))
            {
                return(new[] { milpManager.FromConstant(typedParameters.Function(x.ConstantValue.Value, y.ConstantValue.Value)) });
            }

            var one = milpManager.FromConstant(1);

            var variables =
                Enumerable.Range(0, typedParameters.ArgumentsX.Count()).Select(p =>
                                                                               Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(q =>
                                                                                                                                              milpManager.CreateAnonymous(typedParameters.ArgumentMustBeOnAGrid
                        ? Domain.BinaryInteger
                        : Domain.PositiveOrZeroReal).Set(ConstraintType.LessOrEqual, one)).ToArray())
                .ToArray();

            x.Set(ConstraintType.Equal, milpManager.Operation(OperationType.Addition,
                                                              Enumerable.Range(0, typedParameters.ArgumentsX.Count()).SelectMany(indexX =>
                                                                                                                                 Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY =>
                                                                                                                                                                                                variables[indexX][indexY].Operation(OperationType.Multiplication, milpManager.FromConstant(typedParameters.ArgumentsX.ElementAt(indexX))))).ToArray()
                                                              ));
            y.Set(ConstraintType.Equal, milpManager.Operation(OperationType.Addition,
                                                              Enumerable.Range(0, typedParameters.ArgumentsX.Count()).SelectMany(indexX =>
                                                                                                                                 Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY =>
                                                                                                                                                                                                variables[indexX][indexY].Operation(OperationType.Multiplication, milpManager.FromConstant(typedParameters.ArgumentsY.ElementAt(indexY))))).ToArray()
                                                              ));
            var z = milpManager.Operation(OperationType.Addition,
                                          Enumerable.Range(0, typedParameters.ArgumentsX.Count()).SelectMany(indexX =>
                                                                                                             Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY =>
                                                                                                                                                                            variables[indexX][indexY].Operation(OperationType.Multiplication, milpManager.FromConstant(typedParameters.Function(typedParameters.ArgumentsX.ElementAt(indexX), typedParameters.ArgumentsY.ElementAt(indexY)))))).ToArray()
                                          );

            milpManager.Operation(OperationType.Addition, variables.SelectMany(v => v).ToArray()).Set(ConstraintType.Equal, one);

            var xSet = Enumerable.Range(0, typedParameters.ArgumentsX.Count()).Select(indexX => milpManager.Operation(OperationType.Addition, Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY => variables[indexX][indexY]).ToArray())).ToArray();

            milpManager.Set(CompositeConstraintType.SpecialOrderedSetType2, xSet.First(), xSet.Skip(1).ToArray());

            var ySet = Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY => milpManager.Operation(OperationType.Addition, Enumerable.Range(0, typedParameters.ArgumentsX.Count()).Select(indexX => variables[indexX][indexY]).ToArray())).ToArray();

            milpManager.Set(CompositeConstraintType.SpecialOrderedSetType2, ySet.First(), ySet.Skip(1).ToArray());

            if (!typedParameters.ArgumentMustBeOnAGrid)
            {
                var triangleSet = Enumerable.Range(0, typedParameters.ArgumentsY.Count()).SelectMany(indexY =>
                {
                    var variablesToSet = Enumerable.Range(0, typedParameters.ArgumentsX.Count()).Where(indexX => indexX + indexY < variables[indexX].Length).Select(indexX => variables[indexX][indexX + indexY]).ToArray();
                    if (variablesToSet.Any())
                    {
                        return(new[] { milpManager.Operation(OperationType.Addition, variablesToSet) });
                    }

                    return(new IVariable[0]);
                }).ToArray();

                milpManager.Set(CompositeConstraintType.SpecialOrderedSetType2, triangleSet.First(), triangleSet.Skip(1).ToArray());
            }

            z.ConstantValue = x.IsConstant() && y.IsConstant() ? typedParameters.Function(x.ConstantValue.Value, y.ConstantValue.Value) : (double?)null;
            z.Expression    = $"approximation2D({typedParameters.FunctionDescription})";

            return(new[] { z });
        }