587 lines
18 KiB
C#
587 lines
18 KiB
C#
// Copyright 2010-2024 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.ConstraintSolver
|
|
{
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
public partial class Solver : IDisposable
|
|
{
|
|
public IntVar[] MakeIntVarArray(int count, long min, long max)
|
|
{
|
|
IntVar[] array = new IntVar[count];
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
array[i] = MakeIntVar(min, max);
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntVar[] MakeIntVarArray(int count, long min, long max, string name)
|
|
{
|
|
IntVar[] array = new IntVar[count];
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
string var_name = name + i;
|
|
array[i] = MakeIntVar(min, max, var_name);
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntVar[] MakeIntVarArray(int count, long[] values)
|
|
{
|
|
IntVar[] array = new IntVar[count];
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
array[i] = MakeIntVar(values);
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntVar[] MakeIntVarArray(int count, long[] values, string name)
|
|
{
|
|
IntVar[] array = new IntVar[count];
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
string var_name = name + i;
|
|
array[i] = MakeIntVar(values, var_name);
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntVar[] MakeIntVarArray(int count, int[] values)
|
|
{
|
|
IntVar[] array = new IntVar[count];
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
array[i] = MakeIntVar(values);
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntVar[] MakeIntVarArray(int count, int[] values, string name)
|
|
{
|
|
IntVar[] array = new IntVar[count];
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
string var_name = name + i;
|
|
array[i] = MakeIntVar(values, var_name);
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntVar[] MakeBoolVarArray(int count)
|
|
{
|
|
IntVar[] array = new IntVar[count];
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
array[i] = MakeBoolVar();
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntVar[] MakeBoolVarArray(int count, string name)
|
|
{
|
|
IntVar[] array = new IntVar[count];
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
string var_name = name + i;
|
|
array[i] = MakeBoolVar(var_name);
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntVar[,] MakeIntVarMatrix(int rows, int cols, long min, long max)
|
|
{
|
|
IntVar[,] array = new IntVar[rows, cols];
|
|
for (int i = 0; i < rows; ++i)
|
|
{
|
|
for (int j = 0; j < cols; ++j)
|
|
{
|
|
array[i, j] = MakeIntVar(min, max);
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntVar[,] MakeIntVarMatrix(int rows, int cols, long min, long max, string name)
|
|
{
|
|
IntVar[,] array = new IntVar[rows, cols];
|
|
for (int i = 0; i < rows; ++i)
|
|
{
|
|
for (int j = 0; j < cols; ++j)
|
|
{
|
|
string var_name = name + "[" + i + ", " + j + "]";
|
|
array[i, j] = MakeIntVar(min, max, var_name);
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntVar[,] MakeIntVarMatrix(int rows, int cols, long[] values)
|
|
{
|
|
IntVar[,] array = new IntVar[rows, cols];
|
|
for (int i = 0; i < rows; ++i)
|
|
{
|
|
for (int j = 0; j < cols; ++j)
|
|
{
|
|
array[i, j] = MakeIntVar(values);
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntVar[,] MakeIntVarMatrix(int rows, int cols, long[] values, string name)
|
|
{
|
|
IntVar[,] array = new IntVar[rows, cols];
|
|
for (int i = 0; i < rows; ++i)
|
|
{
|
|
for (int j = 0; j < cols; ++j)
|
|
{
|
|
string var_name = name + "[" + i + ", " + j + "]";
|
|
array[i, j] = MakeIntVar(values, var_name);
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntVar[,] MakeIntVarMatrix(int rows, int cols, int[] values)
|
|
{
|
|
IntVar[,] array = new IntVar[rows, cols];
|
|
for (int i = 0; i < rows; ++i)
|
|
{
|
|
for (int j = 0; j < cols; ++j)
|
|
{
|
|
array[i, j] = MakeIntVar(values);
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntVar[,] MakeIntVarMatrix(int rows, int cols, int[] values, string name)
|
|
{
|
|
IntVar[,] array = new IntVar[rows, cols];
|
|
for (int i = 0; i < rows; ++i)
|
|
{
|
|
for (int j = 0; j < cols; ++j)
|
|
{
|
|
string var_name = name + "[" + i + ", " + j + "]";
|
|
array[i, j] = MakeIntVar(values, var_name);
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntVar[,] MakeBoolVarMatrix(int rows, int cols)
|
|
{
|
|
IntVar[,] array = new IntVar[rows, cols];
|
|
for (int i = 0; i < rows; ++i)
|
|
{
|
|
for (int j = 0; j < cols; ++j)
|
|
{
|
|
array[i, j] = MakeBoolVar();
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntVar[,] MakeBoolVarMatrix(int rows, int cols, string name)
|
|
{
|
|
IntVar[,] array = new IntVar[rows, cols];
|
|
for (int i = 0; i < rows; ++i)
|
|
{
|
|
for (int j = 0; j < cols; ++j)
|
|
{
|
|
string var_name = name + "[" + i + ", " + j + "]";
|
|
array[i, j] = MakeBoolVar(var_name);
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntervalVar[] MakeFixedDurationIntervalVarArray(int count, long start_min, long start_max, long duration,
|
|
bool optional)
|
|
{
|
|
IntervalVar[] array = new IntervalVar[count];
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
array[i] = MakeFixedDurationIntervalVar(start_min, start_max, duration, optional, "");
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntervalVar[] MakeFixedDurationIntervalVarArray(int count, long start_min, long start_max, long duration,
|
|
bool optional, string name)
|
|
{
|
|
IntervalVar[] array = new IntervalVar[count];
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
array[i] = MakeFixedDurationIntervalVar(start_min, start_max, duration, optional, name + i);
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntervalVar[] MakeFixedDurationIntervalVarArray(int count, long[] start_min, long[] start_max,
|
|
long[] duration, bool optional, string name)
|
|
{
|
|
IntervalVar[] array = new IntervalVar[count];
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
array[i] = MakeFixedDurationIntervalVar(start_min[i], start_max[i], duration[i], optional, name + i);
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public IntervalVar[] MakeFixedDurationIntervalVarArray(int count, int[] start_min, int[] start_max, int[] duration,
|
|
bool optional, string name)
|
|
{
|
|
IntervalVar[] array = new IntervalVar[count];
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
array[i] = MakeFixedDurationIntervalVar(start_min[i], start_max[i], duration[i], optional, name + i);
|
|
}
|
|
return array;
|
|
}
|
|
public IntervalVar[] MakeFixedDurationIntervalVarArray(IntVar[] starts, int[] durations, string name)
|
|
{
|
|
int count = starts.Length;
|
|
IntervalVar[] array = new IntervalVar[count];
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
array[i] = MakeFixedDurationIntervalVar(starts[i], durations[i], name + i);
|
|
}
|
|
return array;
|
|
}
|
|
public IntervalVar[] MakeFixedDurationIntervalVarArray(IntVar[] starts, long[] durations, string name)
|
|
{
|
|
int count = starts.Length;
|
|
IntervalVar[] array = new IntervalVar[count];
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
array[i] = MakeFixedDurationIntervalVar(starts[i], durations[i], name + i);
|
|
}
|
|
return array;
|
|
}
|
|
public void NewSearch(DecisionBuilder db)
|
|
{
|
|
pinned_decision_builder_ = db;
|
|
pinned_search_monitors_.Clear();
|
|
NewSearchAux(db);
|
|
}
|
|
|
|
public void NewSearch(DecisionBuilder db, SearchMonitor sm1)
|
|
{
|
|
pinned_decision_builder_ = db;
|
|
pinned_search_monitors_.Clear();
|
|
pinned_search_monitors_.Add(sm1);
|
|
NewSearchAux(db, sm1);
|
|
}
|
|
|
|
public void NewSearch(DecisionBuilder db, SearchMonitor sm1, SearchMonitor sm2)
|
|
{
|
|
pinned_decision_builder_ = db;
|
|
pinned_search_monitors_.Clear();
|
|
pinned_search_monitors_.Add(sm1);
|
|
pinned_search_monitors_.Add(sm2);
|
|
NewSearchAux(db, sm1, sm2);
|
|
}
|
|
|
|
public void NewSearch(DecisionBuilder db, SearchMonitor sm1, SearchMonitor sm2, SearchMonitor sm3)
|
|
{
|
|
pinned_decision_builder_ = db;
|
|
pinned_search_monitors_.Clear();
|
|
pinned_search_monitors_.Add(sm1);
|
|
pinned_search_monitors_.Add(sm2);
|
|
pinned_search_monitors_.Add(sm3);
|
|
NewSearchAux(db, sm1, sm2, sm3);
|
|
}
|
|
|
|
public void NewSearch(DecisionBuilder db, SearchMonitor sm1, SearchMonitor sm2, SearchMonitor sm3,
|
|
SearchMonitor sm4)
|
|
{
|
|
pinned_decision_builder_ = db;
|
|
pinned_search_monitors_.Clear();
|
|
pinned_search_monitors_.Add(sm1);
|
|
pinned_search_monitors_.Add(sm2);
|
|
pinned_search_monitors_.Add(sm3);
|
|
pinned_search_monitors_.Add(sm4);
|
|
NewSearchAux(db, sm1, sm2, sm3, sm4);
|
|
}
|
|
|
|
public void NewSearch(DecisionBuilder db, SearchMonitor[] monitors)
|
|
{
|
|
pinned_decision_builder_ = db;
|
|
pinned_search_monitors_.Clear();
|
|
pinned_search_monitors_.AddRange(monitors);
|
|
NewSearchAux(db, monitors);
|
|
}
|
|
|
|
public void EndSearch()
|
|
{
|
|
pinned_decision_builder_ = null;
|
|
pinned_search_monitors_.Clear();
|
|
EndSearchAux();
|
|
}
|
|
|
|
private System.Collections.Generic.List<SearchMonitor> pinned_search_monitors_ =
|
|
new System.Collections.Generic.List<SearchMonitor>();
|
|
private DecisionBuilder pinned_decision_builder_;
|
|
}
|
|
|
|
public partial class IntExpr : PropagationBaseObject
|
|
{
|
|
public static IntExpr operator +(IntExpr a, IntExpr b)
|
|
{
|
|
return a.solver().MakeSum(a, b);
|
|
}
|
|
public static IntExpr operator +(IntExpr a, long v)
|
|
{
|
|
return a.solver().MakeSum(a, v);
|
|
}
|
|
public static IntExpr operator +(long v, IntExpr a)
|
|
{
|
|
return a.solver().MakeSum(a, v);
|
|
}
|
|
public static IntExpr operator -(IntExpr a, IntExpr b)
|
|
{
|
|
return a.solver().MakeDifference(a, b);
|
|
}
|
|
public static IntExpr operator -(IntExpr a, long v)
|
|
{
|
|
return a.solver().MakeSum(a, -v);
|
|
}
|
|
public static IntExpr operator -(long v, IntExpr a)
|
|
{
|
|
return a.solver().MakeDifference(v, a);
|
|
}
|
|
public static IntExpr operator *(IntExpr a, IntExpr b)
|
|
{
|
|
return a.solver().MakeProd(a, b);
|
|
}
|
|
public static IntExpr operator *(IntExpr a, long v)
|
|
{
|
|
return a.solver().MakeProd(a, v);
|
|
}
|
|
public static IntExpr operator *(long v, IntExpr a)
|
|
{
|
|
return a.solver().MakeProd(a, v);
|
|
}
|
|
public static IntExpr operator /(IntExpr a, long v)
|
|
{
|
|
return a.solver().MakeDiv(a, v);
|
|
}
|
|
public static IntExpr operator %(IntExpr a, long v)
|
|
{
|
|
return a.solver().MakeModulo(a, v);
|
|
}
|
|
public static IntExpr operator -(IntExpr a)
|
|
{
|
|
return a.solver().MakeOpposite(a);
|
|
}
|
|
public IntExpr Abs()
|
|
{
|
|
return this.solver().MakeAbs(this);
|
|
}
|
|
public IntExpr Square()
|
|
{
|
|
return this.solver().MakeSquare(this);
|
|
}
|
|
public static IntExprEquality operator ==(IntExpr a, IntExpr b)
|
|
{
|
|
return new IntExprEquality(a, b, true);
|
|
}
|
|
public static IntExprEquality operator !=(IntExpr a, IntExpr b)
|
|
{
|
|
return new IntExprEquality(a, b, false);
|
|
}
|
|
public static WrappedConstraint operator ==(IntExpr a, long v)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeEquality(a, v));
|
|
}
|
|
public static WrappedConstraint operator !=(IntExpr a, long v)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeNonEquality(a.Var(), v));
|
|
}
|
|
public static WrappedConstraint operator >=(IntExpr a, long v)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a, v));
|
|
}
|
|
public static WrappedConstraint operator>(IntExpr a, long v)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeGreater(a, v));
|
|
}
|
|
public static WrappedConstraint operator <=(IntExpr a, long v)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeLessOrEqual(a, v));
|
|
}
|
|
public static WrappedConstraint operator<(IntExpr a, long v)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeLess(a, v));
|
|
}
|
|
public static WrappedConstraint operator >=(IntExpr a, IntExpr b)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), b.Var()));
|
|
}
|
|
public static WrappedConstraint operator>(IntExpr a, IntExpr b)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeGreater(a.Var(), b.Var()));
|
|
}
|
|
public static WrappedConstraint operator <=(IntExpr a, IntExpr b)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), b.Var()));
|
|
}
|
|
public static WrappedConstraint operator<(IntExpr a, IntExpr b)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeLess(a.Var(), b.Var()));
|
|
}
|
|
}
|
|
|
|
public partial class Constraint : PropagationBaseObject, IConstraintWithStatus
|
|
{
|
|
public static implicit operator IntVar(Constraint eq)
|
|
{
|
|
return eq.Var();
|
|
}
|
|
|
|
public static implicit operator IntExpr(Constraint eq)
|
|
{
|
|
return eq.Var();
|
|
}
|
|
public static IntExpr operator +(Constraint a, Constraint b)
|
|
{
|
|
return a.solver().MakeSum(a.Var(), b.Var());
|
|
}
|
|
public static IntExpr operator +(Constraint a, long v)
|
|
{
|
|
return a.solver().MakeSum(a.Var(), v);
|
|
}
|
|
public static IntExpr operator +(long v, Constraint a)
|
|
{
|
|
return a.solver().MakeSum(a.Var(), v);
|
|
}
|
|
public static IntExpr operator -(Constraint a, Constraint b)
|
|
{
|
|
return a.solver().MakeDifference(a.Var(), b.Var());
|
|
}
|
|
public static IntExpr operator -(Constraint a, long v)
|
|
{
|
|
return a.solver().MakeSum(a.Var(), -v);
|
|
}
|
|
public static IntExpr operator -(long v, Constraint a)
|
|
{
|
|
return a.solver().MakeDifference(v, a.Var());
|
|
}
|
|
public static IntExpr operator *(Constraint a, Constraint b)
|
|
{
|
|
return a.solver().MakeProd(a.Var(), b.Var());
|
|
}
|
|
public static IntExpr operator *(Constraint a, long v)
|
|
{
|
|
return a.solver().MakeProd(a.Var(), v);
|
|
}
|
|
public static IntExpr operator *(long v, Constraint a)
|
|
{
|
|
return a.solver().MakeProd(a.Var(), v);
|
|
}
|
|
public static IntExpr operator /(Constraint a, long v)
|
|
{
|
|
return a.solver().MakeDiv(a.Var(), v);
|
|
}
|
|
public static IntExpr operator -(Constraint a)
|
|
{
|
|
return a.solver().MakeOpposite(a.Var());
|
|
}
|
|
public IntExpr Abs()
|
|
{
|
|
return this.solver().MakeAbs(this.Var());
|
|
}
|
|
public IntExpr Square()
|
|
{
|
|
return this.solver().MakeSquare(this.Var());
|
|
}
|
|
public static WrappedConstraint operator ==(Constraint a, long v)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeEquality(a.Var(), v));
|
|
}
|
|
public static WrappedConstraint operator ==(long v, Constraint a)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeEquality(a.Var(), v));
|
|
}
|
|
public static WrappedConstraint operator !=(Constraint a, long v)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeNonEquality(a.Var(), v));
|
|
}
|
|
public static WrappedConstraint operator !=(long v, Constraint a)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeNonEquality(a.Var(), v));
|
|
}
|
|
public static WrappedConstraint operator >=(Constraint a, long v)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), v));
|
|
}
|
|
public static WrappedConstraint operator >=(long v, Constraint a)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), v));
|
|
}
|
|
public static WrappedConstraint operator>(Constraint a, long v)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeGreater(a.Var(), v));
|
|
}
|
|
public static WrappedConstraint operator>(long v, Constraint a)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeLess(a.Var(), v));
|
|
}
|
|
public static WrappedConstraint operator <=(Constraint a, long v)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), v));
|
|
}
|
|
public static WrappedConstraint operator <=(long v, Constraint a)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), v));
|
|
}
|
|
public static WrappedConstraint operator<(Constraint a, long v)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeLess(a.Var(), v));
|
|
}
|
|
public static WrappedConstraint operator<(long v, Constraint a)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeGreater(a.Var(), v));
|
|
}
|
|
public static WrappedConstraint operator >=(Constraint a, Constraint b)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), b.Var()));
|
|
}
|
|
public static WrappedConstraint operator>(Constraint a, Constraint b)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeGreater(a.Var(), b.Var()));
|
|
}
|
|
public static WrappedConstraint operator <=(Constraint a, Constraint b)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), b.Var()));
|
|
}
|
|
public static WrappedConstraint operator<(Constraint a, Constraint b)
|
|
{
|
|
return new WrappedConstraint(a.solver().MakeLess(a.Var(), b.Var()));
|
|
}
|
|
public static ConstraintEquality operator ==(Constraint a, Constraint b)
|
|
{
|
|
return new ConstraintEquality(a, b, true);
|
|
}
|
|
public static ConstraintEquality operator !=(Constraint a, Constraint b)
|
|
{
|
|
return new ConstraintEquality(a, b, false);
|
|
}
|
|
}
|
|
} // namespace Google.OrTools.ConstraintSolver
|