cleanup c# swig: move vector calling to client .i, import vector.i instead of include; begin support for c# model_builder
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
%include "enums.swg"
|
||||
|
||||
%include "ortools/base/base.i"
|
||||
%include "ortools/util/csharp/vector.i"
|
||||
%import "ortools/util/csharp/vector.i"
|
||||
|
||||
// Include the file we want to wrap a first time.
|
||||
%{
|
||||
@@ -25,6 +25,9 @@
|
||||
|
||||
// by default vector<vector<int64_t>> is mapped to a jagged array i.e. .Net type long[][]
|
||||
// but here we want a regular matrix i.e. .Net type long[,]
|
||||
%template(Int64Vector) std::vector<int64_t>;
|
||||
%template(Int64VectorVector) std::vector<std::vector<int64_t> >;
|
||||
VECTOR_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64Vector);
|
||||
REGULAR_MATRIX_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64VectorVector);
|
||||
|
||||
%rename (UseReduction) operations_research::KnapsackSolver::use_reduction;
|
||||
|
||||
@@ -28,7 +28,7 @@ using System.Collections.Generic;
|
||||
%include "std_string.i"
|
||||
|
||||
%include "ortools/base/base.i"
|
||||
%include "ortools/util/csharp/vector.i"
|
||||
%import "ortools/util/csharp/vector.i"
|
||||
%include "ortools/util/csharp/proto.i"
|
||||
|
||||
// We need to forward-declare the proto here, so that PROTO_INPUT involving it
|
||||
@@ -226,7 +226,20 @@ DEFINE_ARGS_TO_R_CALLBACK(
|
||||
#undef DEFINE_ARGS_TO_R_CALLBACK
|
||||
#undef DEFINE_VOID_TO_STRING_CALLBACK
|
||||
|
||||
// Renaming
|
||||
%template(IntVector) std::vector<int>;
|
||||
%template(IntVectorVector) std::vector<std::vector<int> >;
|
||||
VECTOR_AS_CSHARP_ARRAY(int, int, int, IntVector);
|
||||
JAGGED_MATRIX_AS_CSHARP_ARRAY(int, int, int, IntVectorVector);
|
||||
//REGULAR_MATRIX_AS_CSHARP_ARRAY(int, int, int, IntVectorVector);
|
||||
|
||||
%template(Int64Vector) std::vector<int64_t>;
|
||||
%template(Int64VectorVector) std::vector<std::vector<int64_t> >;
|
||||
VECTOR_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64Vector);
|
||||
JAGGED_MATRIX_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64VectorVector);
|
||||
//REGULAR_MATRIX_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64VectorVector);
|
||||
|
||||
|
||||
// RENAMING
|
||||
namespace operations_research {
|
||||
|
||||
// Decision
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// Wrapper for RoutingIndexManager.
|
||||
|
||||
%include "ortools/base/base.i"
|
||||
%include "ortools/util/csharp/vector.i"
|
||||
%import "ortools/util/csharp/vector.i"
|
||||
|
||||
%{
|
||||
#include "ortools/constraint_solver/routing_index_manager.h"
|
||||
|
||||
@@ -30,6 +30,25 @@ set_target_properties(dotnet_linear_solver PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE ON)
|
||||
target_link_libraries(dotnet_linear_solver PRIVATE ortools::ortools)
|
||||
|
||||
set_property(SOURCE model_builder.i PROPERTY CPLUSPLUS ON)
|
||||
set_property(SOURCE model_builder.i PROPERTY SWIG_MODULE_NAME operations_research_model_builder)
|
||||
set_property(SOURCE model_builder.i PROPERTY COMPILE_DEFINITIONS
|
||||
${OR_TOOLS_COMPILE_DEFINITIONS} ABSL_MUST_USE_RESULT=)
|
||||
set_property(SOURCE model_builder.i PROPERTY COMPILE_OPTIONS
|
||||
-namespace ${DOTNET_PROJECT}.ModelBuilder
|
||||
-dllimport google-ortools-native)
|
||||
swig_add_library(dotnet_model_builder
|
||||
TYPE OBJECT
|
||||
LANGUAGE csharp
|
||||
OUTPUT_DIR ${DOTNET_PROJECT_DIR}/ortools/model_builder
|
||||
SOURCES model_builder.i)
|
||||
|
||||
#target_include_directories(dotnet_model_builder PRIVATE ${DOTNET_INCLUDE_DIRS})
|
||||
set_target_properties(dotnet_model_builder PROPERTIES
|
||||
SWIG_USE_TARGET_INCLUDE_DIRECTORIES ON
|
||||
POSITION_INDEPENDENT_CODE ON)
|
||||
target_link_libraries(dotnet_model_builder PRIVATE ortools::ortools)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
file(GLOB DOTNET_SRCS "*Tests.cs")
|
||||
foreach(FILE_NAME IN LISTS DOTNET_SRCS)
|
||||
|
||||
693
ortools/linear_solver/csharp/ModelBuilderExpr.cs
Normal file
693
ortools/linear_solver/csharp/ModelBuilderExpr.cs
Normal file
@@ -0,0 +1,693 @@
|
||||
// Copyright 2010-2022 Google LLC
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace Google.OrTools.ModelBuilder
|
||||
{
|
||||
using Google.OrTools.Util;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Google.Protobuf.Collections;
|
||||
|
||||
internal static class HelperExtensions
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void AddOrIncrement(this Dictionary<int, double> dict, int key, double increment)
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
System.Runtime.InteropServices.CollectionsMarshal.GetValueRefOrAddDefault(dict, key, out _) += increment;
|
||||
#else
|
||||
if (dict.TryGetValue(key, out var value))
|
||||
{
|
||||
dict[key] = value + increment;
|
||||
}
|
||||
else
|
||||
{
|
||||
dict.Add(key, increment);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static void TrySetCapacity<TField, TValues>(this RepeatedField<TField> field, IEnumerable<TValues> values)
|
||||
{
|
||||
if (values is ICollection<TValues> collection)
|
||||
{
|
||||
field.Capacity = collection.Count;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static void TryEnsureCapacity<TValue, TValues>(this List<TValue> list, IEnumerable<TValues> values)
|
||||
{
|
||||
// Check for ICollection as the generic version is not covariant and TValues could be LinearExpr, Variable, ...
|
||||
if (values is ICollection collection)
|
||||
{
|
||||
list.Capacity = Math.Max(list.Count + collection.Count, list.Capacity);
|
||||
}
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static bool TryDequeue<T>(this Queue<T> queue, out T value)
|
||||
{
|
||||
if (queue.Count > 0)
|
||||
{
|
||||
value = queue.Dequeue();
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Holds a term (expression * coefficient)
|
||||
public struct Term
|
||||
{
|
||||
public LinearExpr expr;
|
||||
public double coefficient;
|
||||
|
||||
public Term(LinearExpr e, double c)
|
||||
{
|
||||
this.expr = e;
|
||||
this.coefficient = c;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <summary>
|
||||
* Holds a linear expression: <c>sum (ai * xi) + b</c>.
|
||||
* </summary>
|
||||
*/
|
||||
public class LinearExpr
|
||||
{
|
||||
/** <summary> Creates <c>Sum(exprs)</c>.</summary> */
|
||||
public static LinearExpr Sum(IEnumerable<LinearExpr> exprs)
|
||||
{
|
||||
return NewBuilder(0).AddSum(exprs);
|
||||
}
|
||||
|
||||
/** <summary> Creates <c>Sum(exprs[i] * coeffs[i])</c>.</summary> */
|
||||
public static LinearExpr WeightedSum(IEnumerable<LinearExpr> exprs, IEnumerable<int> coeffs)
|
||||
{
|
||||
return NewBuilder(0).AddWeightedSum(exprs, coeffs);
|
||||
}
|
||||
|
||||
/** <summary> Creates <c>Sum(exprs[i] * coeffs[i])</c>.</summary> */
|
||||
public static LinearExpr WeightedSum(IEnumerable<LinearExpr> exprs, IEnumerable<double> coeffs)
|
||||
{
|
||||
return NewBuilder(0).AddWeightedSum(exprs, coeffs);
|
||||
}
|
||||
|
||||
/** <summary> Creates <c>expr * coeff</c>.</summary> */
|
||||
public static LinearExpr Term(LinearExpr expr, double coeff)
|
||||
{
|
||||
return Prod(expr, coeff);
|
||||
}
|
||||
|
||||
/** <summary> Creates <c>expr * coeff + offset</c>.</summary> */
|
||||
public static LinearExpr Affine(LinearExpr expr, double coeff, double offset)
|
||||
{
|
||||
if (offset == 0)
|
||||
{
|
||||
return Prod(expr, coeff);
|
||||
}
|
||||
return NewBuilder().AddTerm(expr, coeff).Add(offset);
|
||||
}
|
||||
|
||||
/** <summary> Creates a constant expression.</summary> */
|
||||
public static LinearExpr Constant(double value)
|
||||
{
|
||||
return NewBuilder(0).Add(value);
|
||||
}
|
||||
|
||||
/** <summary> Creates a builder class for linear expression.</summary> */
|
||||
public static LinearExprBuilder NewBuilder(int sizeHint = 2)
|
||||
{
|
||||
return new LinearExprBuilder(sizeHint);
|
||||
}
|
||||
|
||||
public static LinearExpr operator +(LinearExpr a, LinearExpr b)
|
||||
{
|
||||
return NewBuilder().Add(a).Add(b);
|
||||
}
|
||||
|
||||
public static LinearExpr operator +(LinearExpr a, double v)
|
||||
{
|
||||
return NewBuilder().Add(a).Add(v);
|
||||
}
|
||||
|
||||
public static LinearExpr operator +(double v, LinearExpr a)
|
||||
{
|
||||
return NewBuilder().Add(a).Add(v);
|
||||
}
|
||||
|
||||
public static LinearExpr operator -(LinearExpr a, LinearExpr b)
|
||||
{
|
||||
return NewBuilder().Add(a).AddTerm(b, -1);
|
||||
}
|
||||
|
||||
public static LinearExpr operator -(LinearExpr a, double v)
|
||||
{
|
||||
return NewBuilder().Add(a).Add(-v);
|
||||
}
|
||||
|
||||
public static LinearExpr operator -(double v, LinearExpr a)
|
||||
{
|
||||
return NewBuilder().AddTerm(a, -1).Add(v);
|
||||
}
|
||||
|
||||
public static LinearExpr operator *(LinearExpr a, double v)
|
||||
{
|
||||
return Prod(a, v);
|
||||
}
|
||||
|
||||
public static LinearExpr operator *(double v, LinearExpr a)
|
||||
{
|
||||
return Prod(a, v);
|
||||
}
|
||||
|
||||
public static LinearExpr operator -(LinearExpr a)
|
||||
{
|
||||
return Prod(a, -1);
|
||||
}
|
||||
|
||||
public static BoundedLinearExpression operator ==(LinearExpr a, LinearExpr b)
|
||||
{
|
||||
return new BoundedLinearExpression(a, b, true);
|
||||
}
|
||||
|
||||
public static BoundedLinearExpression operator !=(LinearExpr a, LinearExpr b)
|
||||
{
|
||||
return new BoundedLinearExpression(a, b, false);
|
||||
}
|
||||
|
||||
public static BoundedLinearExpression operator ==(LinearExpr a, double v)
|
||||
{
|
||||
return new BoundedLinearExpression(a, v, true);
|
||||
}
|
||||
|
||||
public static BoundedLinearExpression operator !=(LinearExpr a, double v)
|
||||
{
|
||||
return new BoundedLinearExpression(a, v, false);
|
||||
}
|
||||
|
||||
public static BoundedLinearExpression operator >=(LinearExpr a, double v)
|
||||
{
|
||||
return new BoundedLinearExpression(v, a, Double.PositiveInfinity);
|
||||
}
|
||||
|
||||
public static BoundedLinearExpression operator >=(double v, LinearExpr a)
|
||||
{
|
||||
return a <= v;
|
||||
}
|
||||
|
||||
public static BoundedLinearExpression operator <=(LinearExpr a, double v)
|
||||
{
|
||||
return new BoundedLinearExpression(Double.NegativeInfinity, a, v);
|
||||
}
|
||||
|
||||
public static BoundedLinearExpression operator <=(double v, LinearExpr a)
|
||||
{
|
||||
return a >= v;
|
||||
}
|
||||
|
||||
public static BoundedLinearExpression operator >=(LinearExpr a, LinearExpr b)
|
||||
{
|
||||
return new BoundedLinearExpression(0, a - b, Double.PositiveInfinity);
|
||||
}
|
||||
|
||||
public static BoundedLinearExpression operator <=(LinearExpr a, LinearExpr b)
|
||||
{
|
||||
return new BoundedLinearExpression(Double.NegativeInfinity, a - b, 0);
|
||||
}
|
||||
|
||||
internal static LinearExpr Prod(LinearExpr e, double v)
|
||||
{
|
||||
if (v == 0)
|
||||
{
|
||||
return NewBuilder(0);
|
||||
}
|
||||
else if (v == 1)
|
||||
{
|
||||
return e;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NewBuilder(1).AddTerm(e, v);
|
||||
}
|
||||
}
|
||||
|
||||
internal static double GetVarValueMap(LinearExpr e, Dictionary<int, double> dict, Queue<Term> terms)
|
||||
{
|
||||
double constant = 0;
|
||||
double coefficient = 1;
|
||||
LinearExpr expr = e;
|
||||
terms.Clear();
|
||||
|
||||
do
|
||||
{
|
||||
switch (expr)
|
||||
{
|
||||
case LinearExprBuilder builder:
|
||||
constant += coefficient * builder.Offset;
|
||||
if (coefficient == 1)
|
||||
{
|
||||
foreach (Term sub in builder.Terms)
|
||||
{
|
||||
terms.Enqueue(sub);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (Term sub in builder.Terms)
|
||||
{
|
||||
terms.Enqueue(new Term(sub.expr, sub.coefficient * coefficient));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Variable var:
|
||||
dict.AddOrIncrement(var.Index, coefficient);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Cannot evaluate '" + expr + "' in an expression");
|
||||
}
|
||||
|
||||
if (!terms.TryDequeue(out var term))
|
||||
{
|
||||
break;
|
||||
}
|
||||
expr = term.expr;
|
||||
coefficient = term.coefficient;
|
||||
} while (true);
|
||||
|
||||
return constant;
|
||||
}
|
||||
}
|
||||
|
||||
/** <summary> A builder class for linear expressions.</summary> */
|
||||
public sealed class LinearExprBuilder : LinearExpr
|
||||
{
|
||||
public LinearExprBuilder(int sizeHint = 2)
|
||||
{
|
||||
terms_ = new List<Term>(sizeHint);
|
||||
offset_ = 0;
|
||||
}
|
||||
|
||||
/** <summary> Adds <c>expr</c> to the builder.</summary> */
|
||||
public LinearExprBuilder Add(LinearExpr expr)
|
||||
{
|
||||
return AddTerm(expr, 1);
|
||||
}
|
||||
|
||||
/** <summary> Adds <c>constant</c> to the builder.</summary> */
|
||||
public LinearExprBuilder Add(double constant)
|
||||
{
|
||||
offset_ += constant;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** <summary> Adds <c>expr * coefficient</c> to the builder.</summary> */
|
||||
public LinearExprBuilder AddTerm(LinearExpr expr, double coefficient)
|
||||
{
|
||||
terms_.Add(new Term(expr, coefficient));
|
||||
return this;
|
||||
}
|
||||
|
||||
/** <summary> Adds <c>sum(exprs)</c> to the builder.</summary> */
|
||||
public LinearExprBuilder AddSum(IEnumerable<LinearExpr> exprs)
|
||||
{
|
||||
terms_.TryEnsureCapacity(exprs);
|
||||
foreach (LinearExpr expr in exprs)
|
||||
{
|
||||
AddTerm(expr, 1);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/** <summary> Adds <c>sum(exprs[i] * coeffs[i])</c> to the builder.</summary> */
|
||||
public LinearExprBuilder AddWeightedSum(IEnumerable<LinearExpr> exprs, IEnumerable<double> coefficients)
|
||||
{
|
||||
terms_.TryEnsureCapacity(exprs);
|
||||
foreach (var p in exprs.Zip(coefficients, (e, c) => new { Expr = e, Coeff = c }))
|
||||
{
|
||||
AddTerm(p.Expr, p.Coeff);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/** <summary> Adds <c>sum(exprs[i] * coeffs[i])</c> to the builder.</summary> */
|
||||
public LinearExprBuilder AddWeightedSum(IEnumerable<LinearExpr> exprs, IEnumerable<long> coefficients)
|
||||
{
|
||||
terms_.TryEnsureCapacity(exprs);
|
||||
foreach (var p in exprs.Zip(coefficients, (e, c) => new { Expr = e, Coeff = c }))
|
||||
{
|
||||
AddTerm(p.Expr, p.Coeff);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/** <summary> Adds <c>sum(exprs[i] * coeffs[i])</c> to the builder.</summary> */
|
||||
public LinearExprBuilder AddWeightedSum(IEnumerable<LinearExpr> exprs, IEnumerable<int> coefficients)
|
||||
{
|
||||
terms_.TryEnsureCapacity(exprs);
|
||||
foreach (var p in exprs.Zip(coefficients, (e, c) => new { Expr = e, Coeff = c }))
|
||||
{
|
||||
AddTerm(p.Expr, p.Coeff);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
string result = "";
|
||||
foreach (Term term in terms_)
|
||||
{
|
||||
bool first = String.IsNullOrEmpty(result);
|
||||
if (term.expr is null || term.coefficient == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (term.coefficient == 1)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
result += " + ";
|
||||
}
|
||||
|
||||
result += term.expr.ToString();
|
||||
}
|
||||
else if (term.coefficient > 0)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
result += " + ";
|
||||
}
|
||||
|
||||
result += String.Format("{0} * {1}", term.coefficient, term.expr.ToString());
|
||||
}
|
||||
else if (term.coefficient == -1)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
result += String.Format(" - {0}", term.expr.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
result += String.Format("-{0}", term.expr.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
result += String.Format(" - {0} * {1}", -term.coefficient, term.expr.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
result += String.Format("{0} * {1}", term.coefficient, term.expr.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (offset_ > 0)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(result))
|
||||
{
|
||||
result += String.Format(" + {0}", offset_);
|
||||
}
|
||||
else
|
||||
{
|
||||
result += String.Format("{0}", offset_);
|
||||
}
|
||||
}
|
||||
else if (offset_ < 0)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(result))
|
||||
{
|
||||
result += String.Format(" - {0}", -offset_);
|
||||
}
|
||||
else
|
||||
{
|
||||
result += String.Format("{0}", offset_);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public double Offset
|
||||
{
|
||||
get {
|
||||
return offset_;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Term> Terms
|
||||
{
|
||||
get {
|
||||
return terms_;
|
||||
}
|
||||
}
|
||||
|
||||
private double offset_;
|
||||
private List<Term> terms_;
|
||||
}
|
||||
|
||||
/**
|
||||
* <summary>
|
||||
* Holds a variable.
|
||||
* </summary>
|
||||
* <remarks>
|
||||
* This class must be constructed from the CpModel class.
|
||||
* </remarks>
|
||||
*/
|
||||
public class Variable : LinearExpr
|
||||
{
|
||||
public Variable(ModelBuilderHelper helper, double lb, double ub, bool isIntegral, string name)
|
||||
{
|
||||
helper_ = helper;
|
||||
index_ = helper_.AddVar();
|
||||
helper_.SetVarLowerBound(index_, lb);
|
||||
helper_.SetVarUpperBound(index_, ub);
|
||||
helper_.SetVarIntegrality(index_, isIntegral);
|
||||
if (!string.IsNullOrEmpty(name)) {
|
||||
helper_.SetVarName(index_, name);
|
||||
}
|
||||
}
|
||||
|
||||
public Variable(ModelBuilderHelper helper, int index)
|
||||
{
|
||||
helper_ = helper;
|
||||
index_ = index;
|
||||
}
|
||||
|
||||
/** Returns the index of the variable in the underlying ModelBuilderHelper. */
|
||||
public int Index
|
||||
{
|
||||
get {
|
||||
return index_;
|
||||
}
|
||||
}
|
||||
|
||||
/** The underlying VariableProto. */
|
||||
public ModelBuilderHelper Helper
|
||||
{
|
||||
get {
|
||||
return helper_;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the domain of the variable. */
|
||||
public double LowerBound
|
||||
{
|
||||
get {
|
||||
return helper_.VarLowerBound(index_);
|
||||
}
|
||||
}
|
||||
|
||||
public double UpperBound
|
||||
{
|
||||
get {
|
||||
return helper_.VarUpperBound(index_);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string name = helper_.VarName(index_);
|
||||
return string.IsNullOrEmpty(name) ? String.Format("var_{0}", index_) : name;
|
||||
}
|
||||
|
||||
/** Returns the name of the variable given upon creation. */
|
||||
public string Name
|
||||
{
|
||||
get {
|
||||
return helper_.VarName(index_);
|
||||
}
|
||||
}
|
||||
|
||||
protected readonly int index_;
|
||||
protected ModelBuilderHelper helper_;
|
||||
}
|
||||
|
||||
/**
|
||||
* <summary>
|
||||
* Holds a linear constraint: <c> expression ∈ domain</c>
|
||||
* </summary>
|
||||
* <remarks>
|
||||
* This class must be constructed from the CpModel class or from the comparison operators.
|
||||
* </remarks>
|
||||
*/
|
||||
public sealed class BoundedLinearExpression
|
||||
{
|
||||
public enum Type
|
||||
{
|
||||
BoundExpression,
|
||||
VarEqVar,
|
||||
VarDiffVar,
|
||||
VarEqCst,
|
||||
VarDiffCst,
|
||||
}
|
||||
|
||||
public BoundedLinearExpression(double lb, LinearExpr expr, double ub)
|
||||
{
|
||||
left_ = expr;
|
||||
right_ = null;
|
||||
lb_ = lb;
|
||||
ub_ = ub;
|
||||
type_ = Type.BoundExpression;
|
||||
}
|
||||
|
||||
public BoundedLinearExpression(LinearExpr left, LinearExpr right, bool equality)
|
||||
{
|
||||
left_ = left;
|
||||
right_ = right;
|
||||
lb_ = 0;
|
||||
ub_ = 0;
|
||||
type_ = equality ? Type.VarEqVar : Type.VarDiffVar;
|
||||
}
|
||||
|
||||
public BoundedLinearExpression(LinearExpr left, double v, bool equality)
|
||||
{
|
||||
left_ = left;
|
||||
right_ = null;
|
||||
lb_ = v;
|
||||
ub_ = 0;
|
||||
type_ = equality ? Type.VarEqCst : Type.VarDiffCst;
|
||||
}
|
||||
|
||||
bool IsTrue()
|
||||
{
|
||||
if (type_ == Type.VarEqVar)
|
||||
{
|
||||
return (object)left_ == (object)right_;
|
||||
}
|
||||
else if (type_ == Type.VarDiffVar)
|
||||
{
|
||||
return (object)left_ != (object)right_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool operator true(BoundedLinearExpression ble)
|
||||
{
|
||||
return ble.IsTrue();
|
||||
}
|
||||
|
||||
public static bool operator false(BoundedLinearExpression ble)
|
||||
{
|
||||
return !ble.IsTrue();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
switch (type_)
|
||||
{
|
||||
case Type.BoundExpression:
|
||||
return String.Format("{0} <= {1} <= {2}", lb_, left_, ub_);
|
||||
case Type.VarEqVar:
|
||||
return String.Format("{0} == {1}", left_, right_);
|
||||
case Type.VarDiffVar:
|
||||
return String.Format("{0} != {1}", left_, right_);
|
||||
case Type.VarEqCst:
|
||||
return String.Format("{0} == {1}", left_, lb_);
|
||||
case Type.VarDiffCst:
|
||||
return String.Format("{0} != {1}", left_, lb_);
|
||||
default:
|
||||
throw new ArgumentException("Wrong mode in BoundedLinearExpression.");
|
||||
}
|
||||
}
|
||||
|
||||
public static BoundedLinearExpression operator <=(BoundedLinearExpression a, double v)
|
||||
{
|
||||
if (a.CtType != Type.BoundExpression || a.Ub !=Double.PositiveInfinity)
|
||||
{
|
||||
throw new ArgumentException("Operator <= not supported for this BoundedLinearExpression");
|
||||
}
|
||||
return new BoundedLinearExpression(a.Lb, a.Left, v);
|
||||
}
|
||||
|
||||
public static BoundedLinearExpression operator >=(BoundedLinearExpression a, double v)
|
||||
{
|
||||
if (a.CtType != Type.BoundExpression || a.Lb != Double.NegativeInfinity)
|
||||
{
|
||||
throw new ArgumentException("Operator >= not supported for this BoundedLinearExpression");
|
||||
}
|
||||
return new BoundedLinearExpression(v, a.Left, a.Ub);
|
||||
}
|
||||
|
||||
public LinearExpr Left
|
||||
{
|
||||
get {
|
||||
return left_;
|
||||
}
|
||||
}
|
||||
|
||||
public LinearExpr Right
|
||||
{
|
||||
get {
|
||||
return right_;
|
||||
}
|
||||
}
|
||||
|
||||
public double Lb
|
||||
{
|
||||
get {
|
||||
return lb_;
|
||||
}
|
||||
}
|
||||
|
||||
public double Ub
|
||||
{
|
||||
get {
|
||||
return ub_;
|
||||
}
|
||||
}
|
||||
|
||||
public Type CtType
|
||||
{
|
||||
get {
|
||||
return type_;
|
||||
}
|
||||
}
|
||||
|
||||
private LinearExpr left_;
|
||||
private LinearExpr right_;
|
||||
private double lb_;
|
||||
private double ub_;
|
||||
private Type type_;
|
||||
}
|
||||
|
||||
} // namespace Google.OrTools.ModelBuilder
|
||||
@@ -33,7 +33,7 @@
|
||||
%include "std_vector.i"
|
||||
|
||||
%include "ortools/base/base.i"
|
||||
%include "ortools/util/csharp/vector.i"
|
||||
%import "ortools/util/csharp/vector.i"
|
||||
|
||||
%{
|
||||
#include "ortools/linear_solver/linear_solver.h"
|
||||
|
||||
150
ortools/linear_solver/csharp/model_builder.i
Normal file
150
ortools/linear_solver/csharp/model_builder.i
Normal file
@@ -0,0 +1,150 @@
|
||||
// Copyright 2010-2022 Google LLC
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
%include "stdint.i"
|
||||
|
||||
%include "ortools/base/base.i"
|
||||
%include "enums.swg"
|
||||
%import "ortools/util/csharp/vector.i"
|
||||
|
||||
%{
|
||||
#include "ortools/linear_solver/wrappers/model_builder_helper.h"
|
||||
%}
|
||||
|
||||
%module(directors="1") operations_research_model_builder
|
||||
|
||||
%template(IntVector) std::vector<int>;
|
||||
VECTOR_AS_CSHARP_ARRAY(int, int, int, IntVector);
|
||||
|
||||
%template(DoubleVector) std::vector<double>;
|
||||
VECTOR_AS_CSHARP_ARRAY(double, double, double, DoubleVector);
|
||||
|
||||
%extend operations_research::ModelBuilderHelper {
|
||||
std::string ExportToMpsString(bool obfuscate) {
|
||||
operations_research::MPModelExportOptions options;
|
||||
options.obfuscate = obfuscate;
|
||||
return $self->ExportToMpsString(options);
|
||||
}
|
||||
|
||||
std::string ExportToLpString(bool obfuscate) {
|
||||
operations_research::MPModelExportOptions options;
|
||||
options.obfuscate = obfuscate;
|
||||
return $self->ExportToLpString(options);
|
||||
}
|
||||
} // Extend operations_research::ModelBuilderHelper
|
||||
|
||||
%ignoreall
|
||||
|
||||
%unignore operations_research;
|
||||
|
||||
// Wrap the ModelBuilderHelper class.
|
||||
%unignore operations_research::ModelBuilderHelper;
|
||||
%unignore operations_research::ModelBuilderHelper::ModelBuilderHelper;
|
||||
%unignore operations_research::ModelBuilderHelper::~ModelBuilderHelper;
|
||||
|
||||
// Var API.
|
||||
%unignore operations_research::ModelBuilderHelper::AddVar;
|
||||
%unignore operations_research::ModelBuilderHelper::VarIsIntegral;
|
||||
%unignore operations_research::ModelBuilderHelper::VarLowerBound;
|
||||
%unignore operations_research::ModelBuilderHelper::VarName;
|
||||
%unignore operations_research::ModelBuilderHelper::VarObjectiveCoefficient;
|
||||
%unignore operations_research::ModelBuilderHelper::VarUpperBound;
|
||||
%rename (VariablesCount) operations_research::ModelBuilderHelper::num_variables;
|
||||
%unignore operations_research::ModelBuilderHelper::SetVarIntegrality;
|
||||
%unignore operations_research::ModelBuilderHelper::SetVarLowerBound;
|
||||
%unignore operations_research::ModelBuilderHelper::SetVarName;
|
||||
%unignore operations_research::ModelBuilderHelper::SetVarObjectiveCoefficient;
|
||||
%unignore operations_research::ModelBuilderHelper::SetVarUpperBound;
|
||||
|
||||
// Constraint API.
|
||||
%unignore operations_research::ModelBuilderHelper::AddConstraintTerm;
|
||||
%unignore operations_research::ModelBuilderHelper::AddLinearConstraint;
|
||||
%unignore operations_research::ModelBuilderHelper::ConstraintCoefficients;
|
||||
%unignore operations_research::ModelBuilderHelper::ConstraintLowerBound;
|
||||
%unignore operations_research::ModelBuilderHelper::ConstraintName;
|
||||
%unignore operations_research::ModelBuilderHelper::ConstraintUpperBound;
|
||||
%unignore operations_research::ModelBuilderHelper::ConstraintVarIndices;
|
||||
%rename (ConstraintsCount) operations_research::ModelBuilderHelper::num_constraints;
|
||||
%unignore operations_research::ModelBuilderHelper::SetConstraintLowerBound;
|
||||
%unignore operations_research::ModelBuilderHelper::SetConstraintName;
|
||||
%unignore operations_research::ModelBuilderHelper::SetConstraintUpperBound;
|
||||
|
||||
// Objective API.
|
||||
%unignore operations_research::ModelBuilderHelper::ClearObjective;
|
||||
%rename (Maximize) operations_research::ModelBuilderHelper::maximize;
|
||||
%unignore operations_research::ModelBuilderHelper::SetMaximize;
|
||||
%unignore operations_research::ModelBuilderHelper::ObjectiveOffset;
|
||||
%unignore operations_research::ModelBuilderHelper::SetObjectiveOffset;
|
||||
|
||||
// Model API.
|
||||
%rename (Name) operations_research::ModelBuilderHelper::name;
|
||||
%unignore operations_research::ModelBuilderHelper::SetName;
|
||||
%unignore operations_research::ModelBuilderHelper::WriteModelToFile;
|
||||
%unignore operations_research::ModelBuilderHelper::ImportFromMpsString;
|
||||
%unignore operations_research::ModelBuilderHelper::ImportFromMpsFile;
|
||||
%unignore operations_research::ModelBuilderHelper::ImportFromLpString;
|
||||
%unignore operations_research::ModelBuilderHelper::ImportFromLpFile;
|
||||
%unignore operations_research::ModelBuilderHelper::ExportToMpsString(bool);
|
||||
%unignore operations_research::ModelBuilderHelper::ExportToLpString(bool);
|
||||
%unignore operations_research::ModelBuilderHelper::OverwriteModel;
|
||||
|
||||
// Callbacks support.
|
||||
%feature("director") operations_research::LogCallback;
|
||||
%unignore operations_research::LogCallback;
|
||||
%unignore operations_research::LogCallback::~LogCallback;
|
||||
%unignore operations_research::LogCallback::NewMessage;
|
||||
|
||||
// Solver API.
|
||||
%unignore operations_research::ModelSolverHelper;
|
||||
%unignore operations_research::ModelSolverHelper::ModelSolverHelper(const std::string&);
|
||||
%unignore operations_research::ModelSolverHelper::SolverIsSupported;
|
||||
%unignore operations_research::ModelSolverHelper::Solve;
|
||||
%unignore operations_research::ModelSolverHelper::InterruptSolve;
|
||||
%rename (HasResponse) operations_research::ModelSolverHelper::has_response;
|
||||
%rename (HasSolution) operations_research::ModelSolverHelper::has_solution;
|
||||
%rename (Status) operations_research::ModelSolverHelper::status;
|
||||
%rename (ObjectiveValue) operations_research::ModelSolverHelper::objective_value;
|
||||
%rename (BestObjectiveBound) operations_research::ModelSolverHelper::best_objective_bound;
|
||||
%rename (VariableValue) operations_research::ModelSolverHelper::variable_value;
|
||||
%rename (ReducedCost) operations_research::ModelSolverHelper::reduced_cost;
|
||||
%rename (DualValue) operations_research::ModelSolverHelper::dual_value;
|
||||
%rename (Activity) operations_research::ModelSolverHelper::activity;
|
||||
%rename (StatusString) operations_research::ModelSolverHelper::status_string;
|
||||
%rename (WallTime) operations_research::ModelSolverHelper::wall_time;
|
||||
%rename (UserTime) operations_research::ModelSolverHelper::user_time;
|
||||
%unignore operations_research::ModelSolverHelper::EnableOutput;
|
||||
%unignore operations_research::ModelSolverHelper::ClearLogCallback;
|
||||
%unignore operations_research::ModelSolverHelper::SetLogCallbackFromDirectorClass;
|
||||
%unignore operations_research::ModelSolverHelper::SetTimeLimitInSeconds;
|
||||
%unignore operations_research::ModelSolverHelper::SetSolverSpecificParameters;
|
||||
|
||||
%unignore operations_research::SolveStatus;
|
||||
%unignore operations_research::OPTIMAL;
|
||||
%unignore operations_research::FEASIBLE;
|
||||
%unignore operations_research::INFEASIBLE;
|
||||
%unignore operations_research::UNBOUNDED;
|
||||
%unignore operations_research::ABNORMAL;
|
||||
%unignore operations_research::NOT_SOLVED;
|
||||
%unignore operations_research::MODEL_IS_VALID;
|
||||
%unignore operations_research::CANCELLED_BY_USER;
|
||||
%unignore operations_research::UNKNOWN_STATUS;
|
||||
%unignore operations_research::MODEL_INVALID;
|
||||
%unignore operations_research::INVALID_SOLVER_PARAMETERS;
|
||||
%unignore operations_research::SOLVER_TYPE_UNAVAILABLE;
|
||||
%unignore operations_research::INCOMPATIBLE_OPTIONS;
|
||||
|
||||
// For enums
|
||||
%include "ortools/linear_solver/wrappers/model_builder_helper.h"
|
||||
|
||||
%unignoreall
|
||||
|
||||
@@ -60,6 +60,14 @@ PROTO_INPUT(operations_research::sat::IntegerVariableProto,
|
||||
PROTO2_RETURN(operations_research::sat::CpSolverResponse,
|
||||
Google.OrTools.Sat.CpSolverResponse);
|
||||
|
||||
%template(IntVector) std::vector<int>;
|
||||
VECTOR_AS_CSHARP_ARRAY(int, int, int, IntVector);
|
||||
|
||||
%template(Int64Vector) std::vector<int64_t>;
|
||||
%template(Int64VectorVector) std::vector<std::vector<int64_t> >;
|
||||
VECTOR_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64Vector);
|
||||
JAGGED_MATRIX_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64VectorVector);
|
||||
|
||||
%ignoreall
|
||||
|
||||
// SatParameters are proto2, thus not compatible with C# Protobufs.
|
||||
|
||||
@@ -20,7 +20,7 @@ using System.Collections;
|
||||
|
||||
%include "ortools/base/base.i"
|
||||
|
||||
%include "ortools/util/csharp/vector.i"
|
||||
%import "ortools/util/csharp/vector.i"
|
||||
|
||||
%{
|
||||
#include "ortools/util/sorted_interval_list.h"
|
||||
@@ -28,6 +28,11 @@ using System.Collections;
|
||||
|
||||
%module(directors="1") operations_research_util
|
||||
|
||||
%template(Int64Vector) std::vector<int64_t>;
|
||||
%template(Int64VectorVector) std::vector<std::vector<int64_t> >;
|
||||
VECTOR_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64Vector);
|
||||
JAGGED_MATRIX_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64VectorVector);
|
||||
|
||||
%ignoreall
|
||||
|
||||
// SatParameters are proto2, thus not compatible with C# Protobufs.
|
||||
|
||||
@@ -251,14 +251,4 @@
|
||||
// By default vector<vector<Type>> is mapped to a jagged array i.e. .Net type[][]
|
||||
// If you want a regular matrix i.e. .Net type[,] use REGULAR_MATRIX_AS_CSHARP_ARRAY instead.
|
||||
%include "std_vector.i"
|
||||
%template(IntVector) std::vector<int>;
|
||||
%template(IntVectorVector) std::vector<std::vector<int> >;
|
||||
VECTOR_AS_CSHARP_ARRAY(int, int, int, IntVector);
|
||||
JAGGED_MATRIX_AS_CSHARP_ARRAY(int, int, int, IntVectorVector);
|
||||
//REGULAR_MATRIX_AS_CSHARP_ARRAY(int, int, int, IntVectorVector);
|
||||
|
||||
%template(Int64Vector) std::vector<int64_t>;
|
||||
%template(Int64VectorVector) std::vector<std::vector<int64_t> >;
|
||||
VECTOR_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64Vector);
|
||||
JAGGED_MATRIX_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64VectorVector);
|
||||
//REGULAR_MATRIX_AS_CSHARP_ARRAY(int64_t, int64_t, long, Int64VectorVector);
|
||||
|
||||
Reference in New Issue
Block a user