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 IEnumerable <IVariable> Calculate(IMilpManager milpManager, CompositeOperationType type, ICompositeOperationParameters parameters, params IVariable[] arguments) { if (!SupportsOperation(type, parameters, arguments)) { throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, parameters, arguments)); } var typedParameters = parameters as Approximate2DParameters; var x = arguments.First(); var y = arguments.Skip(1).First(); if (arguments.All(i => i.IsConstant())) { return(new[] { milpManager.FromConstant(typedParameters.Function(x.ConstantValue.Value, y.ConstantValue.Value)) }); } var one = milpManager.FromConstant(1); var variables = Enumerable.Range(0, typedParameters.ArgumentsX.Count()).Select(p => Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(q => milpManager.CreateAnonymous(typedParameters.ArgumentMustBeOnAGrid ? Domain.BinaryInteger : Domain.PositiveOrZeroReal).Set(ConstraintType.LessOrEqual, one)).ToArray()) .ToArray(); x.Set(ConstraintType.Equal, milpManager.Operation(OperationType.Addition, Enumerable.Range(0, typedParameters.ArgumentsX.Count()).SelectMany(indexX => Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY => variables[indexX][indexY].Operation(OperationType.Multiplication, milpManager.FromConstant(typedParameters.ArgumentsX.ElementAt(indexX))))).ToArray() )); y.Set(ConstraintType.Equal, milpManager.Operation(OperationType.Addition, Enumerable.Range(0, typedParameters.ArgumentsX.Count()).SelectMany(indexX => Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY => variables[indexX][indexY].Operation(OperationType.Multiplication, milpManager.FromConstant(typedParameters.ArgumentsY.ElementAt(indexY))))).ToArray() )); var z = milpManager.Operation(OperationType.Addition, Enumerable.Range(0, typedParameters.ArgumentsX.Count()).SelectMany(indexX => Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY => variables[indexX][indexY].Operation(OperationType.Multiplication, milpManager.FromConstant(typedParameters.Function(typedParameters.ArgumentsX.ElementAt(indexX), typedParameters.ArgumentsY.ElementAt(indexY)))))).ToArray() ); milpManager.Operation(OperationType.Addition, variables.SelectMany(v => v).ToArray()).Set(ConstraintType.Equal, one); var xSet = Enumerable.Range(0, typedParameters.ArgumentsX.Count()).Select(indexX => milpManager.Operation(OperationType.Addition, Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY => variables[indexX][indexY]).ToArray())).ToArray(); milpManager.Set(CompositeConstraintType.SpecialOrderedSetType2, xSet.First(), xSet.Skip(1).ToArray()); var ySet = Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY => milpManager.Operation(OperationType.Addition, Enumerable.Range(0, typedParameters.ArgumentsX.Count()).Select(indexX => variables[indexX][indexY]).ToArray())).ToArray(); milpManager.Set(CompositeConstraintType.SpecialOrderedSetType2, ySet.First(), ySet.Skip(1).ToArray()); if (!typedParameters.ArgumentMustBeOnAGrid) { var triangleSet = Enumerable.Range(0, typedParameters.ArgumentsY.Count()).SelectMany(indexY => { var variablesToSet = Enumerable.Range(0, typedParameters.ArgumentsX.Count()).Where(indexX => indexX + indexY < variables[indexX].Length).Select(indexX => variables[indexX][indexX + indexY]).ToArray(); if (variablesToSet.Any()) { return(new[] { milpManager.Operation(OperationType.Addition, variablesToSet) }); } return(new IVariable[0]); }).ToArray(); milpManager.Set(CompositeConstraintType.SpecialOrderedSetType2, triangleSet.First(), triangleSet.Skip(1).ToArray()); } z.ConstantValue = x.IsConstant() && y.IsConstant() ? typedParameters.Function(x.ConstantValue.Value, y.ConstantValue.Value) : (double?)null; z.Expression = $"approximation2D({typedParameters.FunctionDescription})"; return(new[] { z }); }
public IEnumerable<IVariable> Calculate(IMilpManager milpManager, CompositeOperationType type, ICompositeOperationParameters parameters, params IVariable[] arguments) { if (!SupportsOperation(type, parameters, arguments)) throw new NotSupportedException(SolverUtilities.FormatUnsupportedMessage(type, parameters, arguments)); var typedParameters = parameters as Approximate2DParameters; var x = arguments.First(); var y = arguments.Skip(1).First(); if (arguments.All(i => i.IsConstant())) { return new[] { milpManager.FromConstant(typedParameters.Function(x.ConstantValue.Value, y.ConstantValue.Value)) }; } var one = milpManager.FromConstant(1); var variables = Enumerable.Range(0, typedParameters.ArgumentsX.Count()).Select(p => Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(q => milpManager.CreateAnonymous(typedParameters.ArgumentMustBeOnAGrid ? Domain.BinaryInteger : Domain.PositiveOrZeroReal).Set(ConstraintType.LessOrEqual, one)).ToArray()) .ToArray(); x.Set(ConstraintType.Equal, milpManager.Operation(OperationType.Addition, Enumerable.Range(0, typedParameters.ArgumentsX.Count()).SelectMany(indexX => Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY => variables[indexX][indexY].Operation(OperationType.Multiplication, milpManager.FromConstant(typedParameters.ArgumentsX.ElementAt(indexX))))).ToArray() )); y.Set(ConstraintType.Equal, milpManager.Operation(OperationType.Addition, Enumerable.Range(0, typedParameters.ArgumentsX.Count()).SelectMany(indexX => Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY => variables[indexX][indexY].Operation(OperationType.Multiplication, milpManager.FromConstant(typedParameters.ArgumentsY.ElementAt(indexY))))).ToArray() )); var z = milpManager.Operation(OperationType.Addition, Enumerable.Range(0, typedParameters.ArgumentsX.Count()).SelectMany(indexX => Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY => variables[indexX][indexY].Operation(OperationType.Multiplication, milpManager.FromConstant(typedParameters.Function(typedParameters.ArgumentsX.ElementAt(indexX), typedParameters.ArgumentsY.ElementAt(indexY)))))).ToArray() ); milpManager.Operation(OperationType.Addition, variables.SelectMany(v => v).ToArray()).Set(ConstraintType.Equal, one); var xSet = Enumerable.Range(0, typedParameters.ArgumentsX.Count()).Select(indexX => milpManager.Operation(OperationType.Addition, Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY => variables[indexX][indexY]).ToArray())).ToArray(); milpManager.Set(CompositeConstraintType.SpecialOrderedSetType2, xSet.First(), xSet.Skip(1).ToArray()); var ySet = Enumerable.Range(0, typedParameters.ArgumentsY.Count()).Select(indexY => milpManager.Operation(OperationType.Addition, Enumerable.Range(0, typedParameters.ArgumentsX.Count()).Select(indexX => variables[indexX][indexY]).ToArray())).ToArray(); milpManager.Set(CompositeConstraintType.SpecialOrderedSetType2, ySet.First(), ySet.Skip(1).ToArray()); if (!typedParameters.ArgumentMustBeOnAGrid) { var triangleSet = Enumerable.Range(0, typedParameters.ArgumentsY.Count()).SelectMany(indexY => { var variablesToSet = Enumerable.Range(0, typedParameters.ArgumentsX.Count()).Where(indexX => indexX + indexY < variables[indexX].Length).Select(indexX => variables[indexX][indexX + indexY]).ToArray(); if (variablesToSet.Any()) { return new[] {milpManager.Operation(OperationType.Addition, variablesToSet)}; } return new IVariable[0]; }).ToArray(); milpManager.Set(CompositeConstraintType.SpecialOrderedSetType2, triangleSet.First(), triangleSet.Skip(1).ToArray()); } z.ConstantValue = x.IsConstant() && y.IsConstant() ? typedParameters.Function(x.ConstantValue.Value, y.ConstantValue.Value) : (double?)null; z.Expression = $"approximation2D({typedParameters.FunctionDescription})"; return new[] { z }; }