private static Domain CalculateDomain(IVariable[] arguments) { if (arguments.All(a => a.IsBinary())) { return Domain.BinaryInteger; } if (IsDividingByConstant(arguments)) { if (arguments.All(a => a.IsInteger())) { if (arguments.All(a => a.IsPositiveOrZero() || a.IsBinary())) { return Domain.PositiveOrZeroInteger; } return Domain.AnyInteger; } else { if (arguments.All(a => a.IsPositiveOrZero() || a.IsBinary())) { return Domain.PositiveOrZeroReal; } return Domain.AnyReal; } } if (arguments.All(a => a.IsPositiveOrZero() || a.IsBinary())) { return Domain.PositiveOrZeroInteger; } return Domain.AnyInteger; }
private static Domain CalculateDomain(IVariable[] arguments) { Domain domain; if (MultiplyBinaryVariables(arguments)) { domain = Domain.BinaryInteger; } else if (arguments.All(a => a.IsPositiveOrZero() || a.IsBinary())) { domain = arguments.Any(a => a.IsReal()) ? Domain.PositiveOrZeroReal : Domain.PositiveOrZeroInteger; } else { domain = arguments.Any(a => a.IsReal()) ? Domain.AnyReal : Domain.AnyInteger; } return arguments.All(a => a.IsConstant()) ? domain.MakeConstant() : domain; }
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 Domain CalculateDomain(IVariable[] arguments) { if (arguments.All(a => a.IsPositiveOrZero() || a.IsBinary())) { if (arguments.Any(a => a.IsReal())) { return arguments.Any(a => a.IsNotConstant()) ? Domain.PositiveOrZeroReal : Domain.PositiveOrZeroConstantReal; } return arguments.Any(a => a.IsNotConstant()) ? Domain.PositiveOrZeroInteger : Domain.PositiveOrZeroConstantInteger; } if (arguments.Any(a => a.IsReal())) { return arguments.Any(a => a.IsNotConstant()) ? Domain.AnyReal : Domain.AnyConstantReal; } return arguments.Any(a => a.IsNotConstant()) ? Domain.AnyInteger : Domain.AnyConstantInteger; }
private static bool MultiplyAnyIntegers(IVariable[] arguments) { return arguments.All(a => a.IsInteger()); }
private static bool MultiplyOnlyConstants(IVariable[] arguments) { return arguments.All(a => a.IsConstant()); }
private static bool MultiplyBinaryVariables(IVariable[] arguments) { return arguments.All(a => a.IsBinary()); }