예제 #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(x => x.IsConstant()))
            {
                var sum = arguments.Select(x => x.ConstantValue.Value).Sum();
                if (arguments.All(x => x.IsInteger()))
                {
                    return(milpManager.FromConstant((int)sum));
                }
                return(milpManager.FromConstant(sum));
            }
            var domain = CalculateDomain(arguments);

            return(arguments.Aggregate((x, y) =>
            {
                var result = milpManager.SumVariables(x, y, domain);
                result.ConstantValue = x.ConstantValue + y.ConstantValue;
                result.Expression = $"{x.FullExpression()} + {y.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(a => a.IsConstant()))
            {
                var constantArgument = (int)arguments[0].ConstantValue.Value;
                var constantResult   = constantArgument == 0 ? 1 : Enumerable.Range(1, constantArgument).Aggregate((a, b) => a * b);
                return(milpManager.FromConstant(constantResult));
            }
            var number = arguments[0];
            var one    = milpManager.FromConstant(1);
            var result = one;

            for (int i = SoundBoundary(milpManager.MaximumIntegerValue); i >= 0; --i)
            {
                result = result.Operation(OperationType.Multiplication,
                                          milpManager.Operation(OperationType.Maximum, one,
                                                                number.Operation(OperationType.Subtraction, milpManager.FromConstant(i))));
            }

            var finalResult = result.ChangeDomain(Domain.PositiveOrZeroInteger);

            finalResult.Expression = $"{number.FullExpression()}!";
            return(finalResult);
        }
예제 #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 index = ((ArraySetParameters)parameters).Index;
            var value = ((ArraySetParameters)parameters).Value;

            if (index.IsConstant())
            {
                arguments[(int)index.ConstantValue.Value] = value;
                return(arguments);
            }

            var catenatedArguments = string.Join(", ", arguments.Select(a => a.FullExpression()).ToArray());

            for (int i = 0; i < arguments.Length; ++i)
            {
                arguments[i]            = milpManager.Operation(OperationType.Condition, milpManager.FromConstant(i).Operation(OperationType.IsEqual, index), value, arguments[i]);
                arguments[i].Expression = $"arraySet(wantedIndex: {index.FullExpression()}, value: {value.FullExpression()}, inArrayIndex: {i}, {catenatedArguments})";
            }

            return(arguments);
        }
        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);
        }
예제 #6
0
        public IVariable Calculate(IMilpManager milpManager, OperationType type, params IVariable[] arguments)
        {
            if (!SupportsOperation(type, arguments))
            {
                throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
            }
            if (arguments[0].IsConstant())
            {
                var value = -arguments[0].ConstantValue.Value;
                if (arguments[0].IsInteger())
                {
                    return(milpManager.FromConstant((int)value));
                }
                else
                {
                    return(milpManager.FromConstant(value));
                }
            }
            Domain domain = arguments[0].IsReal() ? Domain.AnyReal : Domain.AnyInteger;

            var result = milpManager.NegateVariable(arguments[0], domain);

            result.ConstantValue = -arguments[0].ConstantValue;
            result.Expression    = $"-{arguments[0].FullExpression()}";
            return(result);
        }
        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 => a.ConstantValue.Value).Distinct().Count()));
            }
            var total = milpManager.FromConstant(0);

            foreach (var first in arguments)
            {
                var different = milpManager.FromConstant(1);
                foreach (var second in arguments.TakeWhile(a => a != first))
                {
                    different = different.Operation(OperationType.Conjunction,
                                                    first.Operation(OperationType.IsNotEqual, second));
                }
                total = total.Operation(OperationType.Addition, different);
            }

            total.Expression = $"differentValuesCount({string.Join(",", arguments.Select(a => a.FullExpression()).ToArray())})";
            return(total);
        }
        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 });
        }
예제 #9
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);
        }
예제 #10
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 });
        }
예제 #11
0
        public IVariable Calculate(IMilpManager milpManager, OperationType type, params IVariable[] arguments)
        {
            if (!SupportsOperation(type, arguments))
            {
                throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
            }
            if (arguments[0].IsConstant())
            {
                if (arguments[0].ConstantValue.Value <= milpManager.Epsilon)
                {
                    return(arguments[2]);
                }
                return(arguments[1]);
            }
            var trueBranch  = arguments[0].Operation(OperationType.Multiplication, arguments[1]);
            var falseBranch = arguments[0].Operation(OperationType.BinaryNegation)
                              .Operation(OperationType.Multiplication, arguments[2]);
            var result = milpManager.Create(milpManager.Operation(OperationType.Addition,
                                                                  trueBranch,
                                                                  falseBranch
                                                                  ).ChangeDomain(trueBranch.LowestEncompassingDomain(falseBranch)));

            result.Expression    = $"{arguments[0].FullExpression()} ? {arguments[1].FullExpression()} : {arguments[2].FullExpression()}";
            result.ConstantValue = !arguments[0].ConstantValue.HasValue
                ? null
                : (int)arguments[0].ConstantValue.Value == 1 ? trueBranch.ConstantValue : falseBranch.ConstantValue;
            return(result);
        }
예제 #12
0
 public IVariable Calculate(IMilpManager milpManager, GoalType type, params IVariable[] arguments)
 {
     if (!SupportsOperation(type, arguments))
     {
         throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
     }
     return(arguments[0]);
 }
예제 #13
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));
     }
     return(InternalCalculate(milpManager, arguments, ((DecompositionParameters)parameters).Base));
 }
예제 #14
0
        public virtual IVariable Operation(OperationType type, params IVariable[] variables)
        {
            if (Operations[type].SupportsOperation(type, variables))
            {
                return(Operations[type].Calculate(this, type, variables));
            }

            throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, variables));
        }
예제 #15
0
 public IVariable Calculate(IMilpManager milpManager, OperationType type, params IVariable[] arguments)
 {
     if (!SupportsOperation(type, arguments))
     {
         throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
     }
     return
         (arguments.Aggregate((left, right) => left.Operation(OperationType.Addition, right.Operation(OperationType.Negation))));
 }
예제 #16
0
        public IVariable MakeGoal(GoalType type, params IVariable[] variables)
        {
            if (GoalCalculators[type].SupportsOperation(type, variables))
            {
                return(GoalCalculators[type].Calculate(this, type, variables));
            }

            throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, variables));
        }
예제 #17
0
        public virtual IEnumerable <IVariable> CompositeOperation(CompositeOperationType type,
                                                                  ICompositeOperationParameters parameters, params IVariable[] variables)
        {
            if (CompositeOperations[type].SupportsOperation(type, parameters, variables))
            {
                return(CompositeOperations[type].Calculate(this, type, parameters, variables));
            }

            throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, parameters, variables));
        }
 public IVariable Calculate(IMilpManager milpManager, OperationType type, params IVariable[] arguments)
 {
     if (!SupportsOperation(type, arguments)) throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
     if (arguments[0].IsConstant())
     {
         return milpManager.FromConstant((int) (1 - arguments[0].ConstantValue.Value));
     }
     var result = milpManager.FromConstant(1).Operation(OperationType.Subtraction, arguments[0]).ChangeDomain(Domain.BinaryInteger).Create();
     result.Expression = $"!{arguments[0].FullExpression()}";
     return result;
 }
        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 = Math.Pow(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 number = arguments[0];
            var power  = arguments[1];

            var one  = milpManager.FromConstant(1);
            var zero = milpManager.FromConstant(0);
            var isNumberLessOrEqualOne = number.Operation(OperationType.IsLessOrEqual, one);
            var isPowerZero            = power.Operation(OperationType.IsLessOrEqual, zero);
            var isPowerOne             = power.Operation(OperationType.IsEqual, one);
            var isEdgeCase             = milpManager.Operation(OperationType.Disjunction, isNumberLessOrEqualOne, isPowerZero, isPowerOne);
            var result = milpManager.Operation(
                OperationType.Condition,
                isPowerZero,
                one,
                milpManager.Operation(
                    OperationType.Condition,
                    isNumberLessOrEqualOne,
                    number,
                    milpManager.Operation(
                        OperationType.Condition,
                        isPowerOne,
                        number,
                        CalculatePower(number, power, milpManager, isEdgeCase)
                        )
                    )
                );

            result.ConstantValue = number.ConstantValue.HasValue && power.ConstantValue.HasValue
                ? number.ConstantValue == 0
                    ? 0.0
                    : power.ConstantValue == 0
                        ? number.ConstantValue
                        : Math.Pow(number.ConstantValue.Value, power.ConstantValue.Value)
                : (double?)null;
            result.Expression = $"{number.FullExpression()} ** {power.FullExpression()}";
            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.Length > 2)
     {
         return(arguments[0].Operation(type, milpManager.Operation(type, arguments.Skip(1).ToArray())));
     }
     return(CalculateForTwoVariables(milpManager, type, arguments));
 }
예제 #21
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((int)(arguments[0].ConstantValue.Value == 0 ? 1 : arguments[1].ConstantValue.Value));
            }

            var variable = arguments[0].Operation(OperationType.BinaryNegation).Operation(OperationType.Disjunction, arguments[1]);
            variable.Expression = $"{arguments[0].FullExpression()} => {arguments[1].FullExpression()}";
            return variable;
        }
예제 #22
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));
            }

            return(milpManager.MakeGoal(GoalType.MaximizeMaximum, arguments).MakeGoal(GoalType.Minimize));
        }
예제 #23
0
        public void GetPossibleMovesTest()
        {
            Board           board        = new Board();
            List <GameMove> moves        = SolverUtilities.GetPossibleMoves(board);
            BoardState      initialState = board.GetBoardState();

            foreach (GameMove move in moves)
            {
                board.DoMove(move);
                BoardState moveState = board.GetBoardState();
                Assert.IsFalse(initialState.Equals(moveState));
                board.UndoMove();
                BoardState undoMoveState = board.GetBoardState();
                Assert.IsTrue(initialState.Equals(undoMoveState));
            }
        }
예제 #24
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(v => v.IsConstant()))
            {
                return(milpManager.FromConstant(Gcd((int)arguments[0].ConstantValue.Value, (int)arguments[1].ConstantValue.Value)));
            }
            var a   = arguments[0];
            var b   = arguments[1];
            var gcd = CalculateInternal(milpManager, a, b);

            return(gcd);
        }
예제 #25
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);
        }
        public IVariable Calculate(IMilpManager milpManager, OperationType type, params IVariable[] arguments)
        {
            if (!SupportsOperation(type, arguments))
            {
                throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments));
            }
            if (arguments.Length == 1)
            {
                return(arguments[0]);
            }
            if (MultiplyOnlyConstants(arguments))
            {
                var result = arguments.Select(a => a.ConstantValue.Value).Aggregate((a, b) => a * b);
                if (arguments.All(a => a.IsInteger()))
                {
                    return(milpManager.FromConstant((int)result));
                }
                else
                {
                    return(milpManager.FromConstant(result));
                }
            }

            var domain = CalculateDomain(arguments);

            if (MultiplyAtMostOneNonconstant(arguments))
            {
                return(arguments.Aggregate((x, y) =>
                {
                    var result = y.IsConstant()
                        ? milpManager.MultiplyVariableByConstant(x, y, domain)
                        : milpManager.MultiplyVariableByConstant(y, x, domain);
                    result.ConstantValue = x.ConstantValue * y.ConstantValue;
                    result.Expression = $"{x.FullExpression()} * {y.FullExpression()}";
                    return result;
                }));
            }

            if (MultiplyBinaryVariables(arguments))
            {
                return(milpManager.Operation(OperationType.Conjunction, arguments));
            }

            return(MultiplyIntegers(milpManager, domain, arguments));
        }
예제 #27
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));
            }
            if (arguments.All(a => a.IsConstant()))
            {
                return(arguments.OrderBy(a => a.ConstantValue.Value));
            }
            var castedParameters = parameters as CountingSortParameters;
            var values           = castedParameters.Values;
            var valuesWithCounts = new Dictionary <IVariable, IVariable>();
            var zero             = milpManager.FromConstant(0);

            foreach (var value in values)
            {
                valuesWithCounts[value] = arguments.Aggregate(zero,
                                                              (current, val) =>
                                                              current.Operation(OperationType.Addition, val.Operation(OperationType.IsEqual, value)));
            }

            var sum = zero;

            foreach (var value in values)
            {
                sum = sum.Operation(OperationType.Addition, valuesWithCounts[value]);
                valuesWithCounts[value] = sum;
            }

            var infinity = milpManager.FromConstant(milpManager.MaximumIntegerValue);
            var results  = Enumerable.Range(1, arguments.Length).Select(p =>
            {
                var position = milpManager.FromConstant(p);
                var result   = milpManager.Operation(OperationType.Minimum,
                                                     values.Select(value =>
                                                                   milpManager.Operation(OperationType.Condition,
                                                                                         position.Operation(OperationType.IsLessOrEqual, valuesWithCounts[value]), value, infinity)
                                                                   ).ToArray());
                result.Expression = $"countingSort(position: {p}, {string.Join(", ", arguments.Select(a => a.FullExpression()).ToArray())})";
                return(result);
            }).ToArray();

            return(results);
        }
예제 #28
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.Operation(OperationType.IsGreaterThan, arguments[1], arguments[0]);

            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);
        }
        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);
        }
예제 #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 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());
        }