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 }); }
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); }
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; }); }
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); }
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 IVariable Set(IMilpManager milpManager, ConstraintType type, IVariable leftVariable, IVariable rightVariable) { switch (type) { case ConstraintType.Equal: milpManager.SetEqual(leftVariable, rightVariable); leftVariable.ConstantValue = rightVariable.ConstantValue ?? leftVariable.ConstantValue; rightVariable.ConstantValue = leftVariable.ConstantValue ?? rightVariable.ConstantValue; break; case ConstraintType.LessOrEqual: milpManager.SetLessOrEqual(leftVariable, rightVariable); break; case ConstraintType.GreaterOrEqual: milpManager.SetGreaterOrEqual(leftVariable, rightVariable); break; case ConstraintType.LessThan: milpManager.Operation(OperationType.IsLessThan, leftVariable, rightVariable) .Set(ConstraintType.Equal, milpManager.FromConstant(1)); break; case ConstraintType.GreaterThan: milpManager.Operation(OperationType.IsGreaterThan, leftVariable, rightVariable) .Set(ConstraintType.Equal, milpManager.FromConstant(1)); break; case ConstraintType.NotEqual: milpManager.Operation(OperationType.IsNotEqual, leftVariable, rightVariable) .Set(ConstraintType.Equal, milpManager.FromConstant(1)); break; default: throw new InvalidOperationException("Cannot set constraint"); } 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(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; })); }
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 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; }
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); }
public IEnumerable<IVariable> Calculate(IMilpManager milpManager, CompositeOperationType type, ICompositeOperationParameters parameters, params IVariable[] arguments) { if (!SupportsOperation(type, parameters, arguments)) throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments)); var typedParameters = parameters as LexicographicalCompareParameters; if (arguments.All(i => i.IsConstant()) && typedParameters.Pattern.All(i => i.IsConstant())) { return new [] { CompareFinalResult(milpManager.FromConstant(arguments.Zip(typedParameters.Pattern, Tuple.Create) .Select(pair => pair.Item1.ConstantValue.Value - pair.Item2.ConstantValue.Value) .Select(v => v > 0 ? 1 : (v < 0 ? -1 : 0)) .FirstOrDefault(v => v != 0)), milpManager) }; } var compareResult = CalculateBatches(milpManager, parameters, arguments).ToArray(); while (compareResult.Length > 1) { var zero = milpManager.FromConstant(0); var newParameters = new LexicographicalCompareParameters { Pattern = Enumerable.Range(0, compareResult.Length).Select(x => zero).ToArray() }; compareResult = CalculateBatches(milpManager, newParameters, compareResult).ToArray(); } var result = compareResult.First(); result.ConstantValue = arguments.All(a => a.ConstantValue.HasValue) && typedParameters.Pattern.All(a => a.IsConstant()) ? ConstantFinalResult(arguments.Zip(typedParameters.Pattern, Tuple.Create).Select(p => p.Item1.ConstantValue.Value - p.Item2.ConstantValue.Value).Select(v => v > 0 ? 1 : v < 0 ? -1 : 0).TakeWhile(v => v != 0).FirstOrDefault()) : (double?)null; result.Expression = $"({string.Join(",", arguments.Select(a => a.FullExpression()).ToArray())}) {ComparerFinalResult} ({string.Join(",", typedParameters.Pattern.Select(a => a.FullExpression()).ToArray())})"; return new[] {CompareFinalResult(compareResult[0], milpManager)}; }
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); }
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[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 Set(IMilpManager milpManager, CompositeConstraintType type, ICompositeConstraintParameters parameters, IVariable leftVariable, params IVariable[] rightVariable) { rightVariable.Aggregate(milpManager.FromConstant(0), (current, variable) => current.Operation(OperationType.Addition, leftVariable.Operation(OperationType.IsEqual, variable))).Create() .Set(ConstraintType.Equal, milpManager.FromConstant(0)); return leftVariable; }
public IVariable Set(IMilpManager milpManager, CompositeConstraintType type, ICompositeConstraintParameters parameters, IVariable leftVariable, params IVariable[] rightVariable) { rightVariable.Aggregate(milpManager.FromConstant(0), (current, variable) => current.Operation(OperationType.Addition, leftVariable.Operation(OperationType.IsEqual, variable))).Create() .Set(ConstraintType.Equal, milpManager.FromConstant(0)); 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())) { 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); }
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[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; }
private static IVariable CalculateBatch(IMilpManager milpManager, IVariable[] first, IVariable[] second) { var power = (int)Math.Pow(2, first.Length); return first.Zip(second, Tuple.Create).Aggregate(milpManager.FromConstant(0), (result, pair) => { power /= 2; return result.Operation(OperationType.Addition, pair.Item1.Operation(OperationType.IsGreaterOrEqual, pair.Item2).Operation(OperationType.Multiplication, milpManager.FromConstant(power)), pair.Item1.Operation(OperationType.IsLessOrEqual, pair.Item2).Operation(OperationType.Multiplication, milpManager.FromConstant(-power)) ); }); }
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; }
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; }
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 }); }
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}; }
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; })); }
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 NthElementsParameters; if (arguments.All(a => a.IsConstant()) && typedParameters.Indexes.All(a => a.IsConstant())) { var sorted = arguments.OrderBy(a => a.ConstantValue.Value).ToArray(); return typedParameters.Indexes.Select(i => sorted[(int)i.ConstantValue.Value]); } var variables = new List<IVariable>(); var sums = arguments.Select(a => Tuple.Create(a, milpManager.Operation(OperationType.Addition, arguments.Where(b => a != b).Select(b => a.Operation(OperationType.IsGreaterOrEqual, b).Create()).ToArray()).Create())).ToArray(); var huge = milpManager.FromConstant(milpManager.MaximumIntegerValue); foreach(var indexVariable in typedParameters.Indexes) { var result = huge; foreach (var sum in sums) { result = result.Operation(OperationType.Minimum, milpManager.Operation(OperationType.Condition, sum.Item2.Operation(OperationType.IsGreaterOrEqual, indexVariable), sum.Item1, huge )); } var singleVariable = result.Create(); singleVariable.Expression = $"nthElement(index: {indexVariable.FullExpression()}, {string.Join(",", arguments.Select(a => a.FullExpression()).ToArray())})"; variables.Add(singleVariable); } return variables; }
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 Set(IMilpManager milpManager, CompositeConstraintType type, ICompositeConstraintParameters parameters, IVariable leftVariable, params IVariable[] rightVariable) { leftVariable.Operation(OperationType.DifferentValuesCount, rightVariable) .Set(ConstraintType.Equal, milpManager.FromConstant(rightVariable.Length + 1)); return(leftVariable); }
public IVariable Set(IMilpManager milpManager, CompositeConstraintType type, ICompositeConstraintParameters parameters, IVariable leftVariable, params IVariable[] rightVariable) { leftVariable.Operation(OperationType.DifferentValuesCount, rightVariable) .Set(ConstraintType.Equal, milpManager.FromConstant(rightVariable.Length + 1)); 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.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)); }
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); }
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); }
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 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()); }
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, 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); }
public IEnumerable <IVariable> Calculate(IMilpManager milpManager, CompositeOperationType type, ICompositeOperationParameters parameters, params IVariable[] arguments) { if (!SupportsOperation(type, parameters, arguments)) { throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, arguments)); } var typedParameters = parameters as LexicographicalCompareParameters; if (arguments.All(i => i.IsConstant()) && typedParameters.Pattern.All(i => i.IsConstant())) { return(new [] { CompareFinalResult(milpManager.FromConstant(arguments.Zip(typedParameters.Pattern, Tuple.Create) .Select(pair => pair.Item1.ConstantValue.Value - pair.Item2.ConstantValue.Value) .Select(v => v > 0 ? 1 : (v < 0 ? -1 : 0)) .FirstOrDefault(v => v != 0)), milpManager) }); } var compareResult = CalculateBatches(milpManager, parameters, arguments).ToArray(); while (compareResult.Length > 1) { var zero = milpManager.FromConstant(0); var newParameters = new LexicographicalCompareParameters { Pattern = Enumerable.Range(0, compareResult.Length).Select(x => zero).ToArray() }; compareResult = CalculateBatches(milpManager, newParameters, compareResult).ToArray(); } var result = compareResult.First(); result.ConstantValue = arguments.All(a => a.ConstantValue.HasValue) && typedParameters.Pattern.All(a => a.IsConstant()) ? ConstantFinalResult(arguments.Zip(typedParameters.Pattern, Tuple.Create).Select(p => p.Item1.ConstantValue.Value - p.Item2.ConstantValue.Value).Select(v => v > 0 ? 1 : v < 0 ? -1 : 0).TakeWhile(v => v != 0).FirstOrDefault()) : (double?)null; result.Expression = $"({string.Join(",", arguments.Select(a => a.FullExpression()).ToArray())}) {ComparerFinalResult} ({string.Join(",", typedParameters.Pattern.Select(a => a.FullExpression()).ToArray())})"; return(new[] { CompareFinalResult(compareResult[0], milpManager) }); }
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.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; }
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; }
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; }
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); }
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; }
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(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; }
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 IVariable Set(IMilpManager milpManager, ConstraintType type, IVariable leftVariable, IVariable rightVariable) { switch (type) { case ConstraintType.Equal: milpManager.SetEqual(leftVariable, rightVariable); leftVariable.ConstantValue = rightVariable.ConstantValue ?? leftVariable.ConstantValue; rightVariable.ConstantValue = leftVariable.ConstantValue ?? rightVariable.ConstantValue; break; case ConstraintType.LessOrEqual: milpManager.SetLessOrEqual(leftVariable, rightVariable); break; case ConstraintType.GreaterOrEqual: milpManager.SetGreaterOrEqual(leftVariable, rightVariable); break; case ConstraintType.LessThan: milpManager.Operation(OperationType.IsLessThan, leftVariable, rightVariable) .Set(ConstraintType.Equal, milpManager.FromConstant(1)); break; case ConstraintType.GreaterThan: milpManager.Operation(OperationType.IsGreaterThan, leftVariable, rightVariable) .Set(ConstraintType.Equal, milpManager.FromConstant(1)); break; case ConstraintType.NotEqual: milpManager.Operation(OperationType.IsNotEqual, leftVariable, rightVariable) .Set(ConstraintType.Equal, milpManager.FromConstant(1)); break; default: throw new InvalidOperationException("Cannot set constraint"); } 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(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; }); }
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; }
private static IVariable CalculateBatch(IMilpManager milpManager, IVariable[] first, IVariable[] second) { var power = (int)Math.Pow(2, first.Length); return(first.Zip(second, Tuple.Create).Aggregate(milpManager.FromConstant(0), (result, pair) => { power /= 2; return result.Operation(OperationType.Addition, pair.Item1.Operation(OperationType.IsGreaterOrEqual, pair.Item2).Operation(OperationType.Multiplication, milpManager.FromConstant(power)), pair.Item1.Operation(OperationType.IsLessOrEqual, pair.Item2).Operation(OperationType.Multiplication, milpManager.FromConstant(-power)) ); })); }
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); }
private static IVariable CalculatePower(IVariable number, IVariable power, IMilpManager milpManager, IVariable isEdgeCase) { var digits = (int)Math.Ceiling(Math.Log(milpManager.IntegerWidth, 2.0)); var infinity = milpManager.FromConstant(milpManager.MaximumIntegerValue); var currentPower = milpManager.Operation(OperationType.Minimum, number, isEdgeCase.Operation(OperationType.BinaryNegation).Operation(OperationType.Multiplication, infinity)); var decomposition = power.CompositeOperation(CompositeOperationType.UnsignedMagnitudeDecomposition).Take(digits).ToArray(); var one = milpManager.FromConstant(1); var result = one; for (int i = 0; i < digits; ++i) { if (i > 0) { var isAnyNonzeroDigitLater = milpManager.Operation(OperationType.Disjunction, decomposition.Skip(i).ToArray()); var numberToMultiply = milpManager.Operation(OperationType.Minimum, currentPower, isAnyNonzeroDigitLater.Operation(OperationType.Multiplication, infinity)); currentPower = numberToMultiply.Operation(OperationType.Multiplication, numberToMultiply); } result = result.Operation(OperationType.Multiplication, one.Operation(OperationType.Maximum, currentPower.Operation(OperationType.Multiplication, decomposition[i]))); } return(result); }
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.Select(a => (int)a.ConstantValue).Aggregate((a, b) => (a + b) % 2)); } var variable = arguments.Aggregate((a,b) => milpManager.Operation(OperationType.Disjunction, milpManager.Operation(OperationType.Conjunction, a.Operation(OperationType.BinaryNegation), b), milpManager.Operation(OperationType.Conjunction, a, b.Operation(OperationType.BinaryNegation)))); variable.Expression = $"{string.Join(" ^ ", arguments.Select(a => a.FullExpression()).ToArray())}"; return variable; }
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; }
private static IVariable CalculatePower(IVariable number, IVariable power, IMilpManager milpManager, IVariable isEdgeCase) { var digits = (int)Math.Ceiling(Math.Log(milpManager.IntegerWidth, 2.0)); var infinity = milpManager.FromConstant(milpManager.MaximumIntegerValue); var currentPower = milpManager.Operation(OperationType.Minimum, number, isEdgeCase.Operation(OperationType.BinaryNegation).Operation(OperationType.Multiplication, infinity)); var decomposition = power.CompositeOperation(CompositeOperationType.UnsignedMagnitudeDecomposition).Take(digits).ToArray(); var one = milpManager.FromConstant(1); var result = one; for (int i = 0; i < digits; ++i) { if (i > 0) { var isAnyNonzeroDigitLater = milpManager.Operation(OperationType.Disjunction, decomposition.Skip(i).ToArray()); var numberToMultiply = milpManager.Operation(OperationType.Minimum, currentPower, isAnyNonzeroDigitLater.Operation(OperationType.Multiplication, infinity)); currentPower = numberToMultiply.Operation(OperationType.Multiplication, numberToMultiply); } result = result.Operation(OperationType.Multiplication, one.Operation(OperationType.Maximum, currentPower.Operation(OperationType.Multiplication, decomposition[i]))); } 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[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; }
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); }
private IVariable MakeLongMultiplication(IMilpManager baseMilpManager, Domain domain, IVariable zero, IVariable second, IVariable first) { var result = zero; var secondDigits = second.CompositeOperation(CompositeOperationType.UnsignedMagnitudeDecomposition).ToArray(); for (int index = 0, power = 1; index < secondDigits.Length; ++index, power = power * 2) { result = result.Operation(OperationType.Addition, MultipleByBinaryDigit(baseMilpManager, first, secondDigits[index]) .ChangeDomain(domain) .Operation(OperationType.Multiplication, baseMilpManager.FromConstant(power)) ); } return(result); }
private IEnumerable<IVariable> InternalCalculate(IMilpManager milpManager, IVariable[] arguments, uint decompositionBase) { if (arguments[0].IsConstant()) { uint currentValue = (uint)arguments[0].ConstantValue.Value; for (int i = 0; i < GetDigitsCount(milpManager, decompositionBase); ++i) { yield return milpManager.FromConstant((int)(currentValue % decompositionBase)); currentValue /= decompositionBase; } yield break; } foreach (var i in CalculateForVariable(milpManager, arguments, decompositionBase)) { yield return i; } }