1 // Copyright 2010-2021 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 namespace Google.OrTools.ConstraintSolver
15 {
16     using System;
17     using System.Collections.Generic;
18 
19     // IntVar[] helper class.
20     public static class IntVarArrayHelper
21     {
22         // All Different
AllDifferent(this IntVar[] vars)23         public static Constraint AllDifferent(this IntVar[] vars)
24         {
25             Solver solver = GetSolver(vars);
26             return solver.MakeAllDifferent(vars);
27         }
28         // Allowed assignment
AllowedAssignments(this IntVar[] vars, IntTupleSet tuples)29         public static Constraint AllowedAssignments(this IntVar[] vars, IntTupleSet tuples)
30         {
31             Solver solver = GetSolver(vars);
32             return solver.MakeAllowedAssignments(vars, tuples);
33         }
34         // sum of all vars.
Sum(this IntVar[] vars)35         public static IntExpr Sum(this IntVar[] vars)
36         {
37             Solver solver = GetSolver(vars);
38             return solver.MakeSum(vars);
39         }
40         // sum of all constraints.
Sum(this IConstraintWithStatus[] cts)41         public static IntExpr Sum(this IConstraintWithStatus[] cts)
42         {
43             Solver solver = GetSolver(cts);
44             IntVar[] vars = new IntVar[cts.Length];
45             for (int i = 0; i < cts.Length; ++i)
46             {
47                 vars[i] = cts[i].Var();
48             }
49             return solver.MakeSum(vars);
50         }
Sum(this IntExpr[] exprs)51         public static IntExpr Sum(this IntExpr[] exprs)
52         {
53             Solver solver = GetSolver(exprs);
54             IntVar[] vars = new IntVar[exprs.Length];
55             for (int i = 0; i < exprs.Length; ++i)
56             {
57                 vars[i] = exprs[i].Var();
58             }
59             return solver.MakeSum(vars);
60         }
61 
62         // scalar product
ScalProd(this IntVar[] vars, long[] coefs)63         public static IntExpr ScalProd(this IntVar[] vars, long[] coefs)
64         {
65             Solver solver = GetSolver(vars);
66             return solver.MakeScalProd(vars, coefs);
67         }
68 
69         // scalar product
ScalProd(this IntVar[] vars, int[] coefs)70         public static IntExpr ScalProd(this IntVar[] vars, int[] coefs)
71         {
72             Solver solver = GetSolver(vars);
73             return solver.MakeScalProd(vars, coefs);
74         }
75 
76         // get solver from array of integer variables
GetSolver(IntVar[] vars)77         private static Solver GetSolver(IntVar[] vars)
78         {
79             if (vars == null || vars.Length <= 0)
80                 throw new ArgumentException("Array <vars> cannot be null or empty");
81 
82             return vars[0].solver();
83         }
84         // get solver from array of integer expressions
GetSolver(IntExpr[] expressions)85         private static Solver GetSolver(IntExpr[] expressions)
86         {
87             if (expressions == null || expressions.Length <= 0)
88                 throw new ArgumentException("Array <expr> cannot be null or empty");
89 
90             return expressions[0].solver();
91         }
GetSolver(IConstraintWithStatus[] cts)92         private static Solver GetSolver(IConstraintWithStatus[] cts)
93         {
94             if (cts == null || cts.Length <= 0)
95                 throw new ArgumentException("Array <cts> cannot be null or empty");
96 
97             return cts[0].solver();
98         }
Element(this IntVar[] array, IntExpr index)99         public static IntExpr Element(this IntVar[] array, IntExpr index)
100         {
101             return index.solver().MakeElement(array, index.Var());
102         }
103         // min of all vars.
Min(this IntVar[] vars)104         public static IntExpr Min(this IntVar[] vars)
105         {
106             Solver solver = GetSolver(vars);
107             return solver.MakeMin(vars);
108         }
109         // min of all vars.
Max(this IntVar[] vars)110         public static IntExpr Max(this IntVar[] vars)
111         {
112             Solver solver = GetSolver(vars);
113             return solver.MakeMax(vars);
114         }
115         // count of all vars.
Count(this IntVar[] vars, long value, long count)116         public static Constraint Count(this IntVar[] vars, long value, long count)
117         {
118             Solver solver = GetSolver(vars);
119             return solver.MakeCount(vars, value, count);
120         }
121         // count of all vars.
Count(this IntVar[] vars, long value, IntExpr count)122         public static Constraint Count(this IntVar[] vars, long value, IntExpr count)
123         {
124             Solver solver = GetSolver(vars);
125             return solver.MakeCount(vars, value, count.Var());
126         }
Distribute(this IntVar[] vars, long[] values, IntVar[] cards)127         public static Constraint Distribute(this IntVar[] vars, long[] values, IntVar[] cards)
128         {
129             Solver solver = GetSolver(vars);
130             return solver.MakeDistribute(vars, values, cards);
131         }
Distribute(this IntVar[] vars, int[] values, IntVar[] cards)132         public static Constraint Distribute(this IntVar[] vars, int[] values, IntVar[] cards)
133         {
134             Solver solver = GetSolver(vars);
135             return solver.MakeDistribute(vars, values, cards);
136         }
Distribute(this IntVar[] vars, IntVar[] cards)137         public static Constraint Distribute(this IntVar[] vars, IntVar[] cards)
138         {
139             Solver solver = GetSolver(vars);
140             return solver.MakeDistribute(vars, cards);
141         }
Distribute(this IntVar[] vars, long card_min, long card_max, long card_size)142         public static Constraint Distribute(this IntVar[] vars, long card_min, long card_max, long card_size)
143         {
144             Solver solver = GetSolver(vars);
145             return solver.MakeDistribute(vars, card_min, card_max, card_size);
146         }
Transition(this IntVar[] vars, IntTupleSet transitions, long initial_state, long[] final_states)147         public static Constraint Transition(this IntVar[] vars, IntTupleSet transitions, long initial_state,
148                                             long[] final_states)
149         {
150             Solver solver = GetSolver(vars);
151             return solver.MakeTransitionConstraint(vars, transitions, initial_state, final_states);
152         }
Transition(this IntVar[] vars, IntTupleSet transitions, long initial_state, int[] final_states)153         public static Constraint Transition(this IntVar[] vars, IntTupleSet transitions, long initial_state,
154                                             int[] final_states)
155         {
156             Solver solver = GetSolver(vars);
157             return solver.MakeTransitionConstraint(vars, transitions, initial_state, final_states);
158         }
159 
160         // Matrix API
Flatten(this IntVar[,] vars)161         public static IntVar[] Flatten(this IntVar[,] vars)
162         {
163             int rows = vars.GetLength(0);
164             int cols = vars.GetLength(1);
165             IntVar[] flat = new IntVar[cols * rows];
166             for (int i = 0; i < rows; i++)
167             {
168                 for (int j = 0; j < cols; j++)
169                 {
170                     flat[i * cols + j] = vars[i, j];
171                 }
172             }
173             return flat;
174         }
175     }
176 
177     // TODO(user): Try to move this code back to the .swig with @define macros.
178     public partial class IntVarVector : IDisposable,
179                                         System.Collections.IEnumerable
180 #if !SWIG_DOTNET_1
181         ,
182                                         System.Collections.Generic.IList<IntVar>
183 #endif
184     {
185         // cast from C# IntVar array
operator IntVarVector(IntVar[] inVal)186         public static implicit operator IntVarVector(IntVar[] inVal)
187         {
188             var outVal = new IntVarVector();
189             foreach (IntVar element in inVal)
190             {
191                 outVal.Add(element);
192             }
193             return outVal;
194         }
195 
196         // cast to C# IntVar array
operator IntVar[](IntVarVector inVal)197         public static implicit operator IntVar[](IntVarVector inVal)
198         {
199             var outVal = new IntVar[inVal.Count];
200             inVal.CopyTo(outVal);
201             return outVal;
202         }
203     }
204 
205     public partial class SearchMonitorVector : IDisposable,
206                                                System.Collections.IEnumerable
207 #if !SWIG_DOTNET_1
208         ,
209                                                System.Collections.Generic.IList<SearchMonitor>
210 #endif
211     {
212         // cast from C# SearchMonitor array
operator SearchMonitorVector(SearchMonitor[] inVal)213         public static implicit operator SearchMonitorVector(SearchMonitor[] inVal)
214         {
215             var outVal = new SearchMonitorVector();
216             foreach (SearchMonitor element in inVal)
217             {
218                 outVal.Add(element);
219             }
220             return outVal;
221         }
222 
223         // cast to C# SearchMonitor array
operator SearchMonitor[](SearchMonitorVector inVal)224         public static implicit operator SearchMonitor[](SearchMonitorVector inVal)
225         {
226             var outVal = new SearchMonitor[inVal.Count];
227             inVal.CopyTo(outVal);
228             return outVal;
229         }
230     }
231 
232     public partial class DecisionBuilderVector : IDisposable,
233                                                  System.Collections.IEnumerable
234 #if !SWIG_DOTNET_1
235         ,
236                                                  System.Collections.Generic.IList<DecisionBuilder>
237 #endif
238     {
239         // cast from C# DecisionBuilder array
operator DecisionBuilderVector(DecisionBuilder[] inVal)240         public static implicit operator DecisionBuilderVector(DecisionBuilder[] inVal)
241         {
242             var outVal = new DecisionBuilderVector();
243             foreach (DecisionBuilder element in inVal)
244             {
245                 outVal.Add(element);
246             }
247             return outVal;
248         }
249 
250         // cast to C# DecisionBuilder array
operator DecisionBuilder[](DecisionBuilderVector inVal)251         public static implicit operator DecisionBuilder[](DecisionBuilderVector inVal)
252         {
253             var outVal = new DecisionBuilder[inVal.Count];
254             inVal.CopyTo(outVal);
255             return outVal;
256         }
257     }
258 
259     public partial class IntervalVarVector : IDisposable,
260                                              System.Collections.IEnumerable
261 #if !SWIG_DOTNET_1
262         ,
263                                              System.Collections.Generic.IList<IntervalVar>
264 #endif
265     {
266         // cast from C# IntervalVar array
operator IntervalVarVector(IntervalVar[] inVal)267         public static implicit operator IntervalVarVector(IntervalVar[] inVal)
268         {
269             var outVal = new IntervalVarVector();
270             foreach (IntervalVar element in inVal)
271             {
272                 outVal.Add(element);
273             }
274             return outVal;
275         }
276 
277         // cast to C# IntervalVar array
operator IntervalVar[](IntervalVarVector inVal)278         public static implicit operator IntervalVar[](IntervalVarVector inVal)
279         {
280             var outVal = new IntervalVar[inVal.Count];
281             inVal.CopyTo(outVal);
282             return outVal;
283         }
284     }
285 
286     public partial class SequenceVarVector : IDisposable,
287                                              System.Collections.IEnumerable
288 #if !SWIG_DOTNET_1
289         ,
290                                              System.Collections.Generic.IList<SequenceVar>
291 #endif
292     {
293         // cast from C# SequenceVar array
operator SequenceVarVector(SequenceVar[] inVal)294         public static implicit operator SequenceVarVector(SequenceVar[] inVal)
295         {
296             var outVal = new SequenceVarVector();
297             foreach (SequenceVar element in inVal)
298             {
299                 outVal.Add(element);
300             }
301             return outVal;
302         }
303 
304         // cast to C# SequenceVar array
operator SequenceVar[](SequenceVarVector inVal)305         public static implicit operator SequenceVar[](SequenceVarVector inVal)
306         {
307             var outVal = new SequenceVar[inVal.Count];
308             inVal.CopyTo(outVal);
309             return outVal;
310         }
311     }
312 
313     public partial class LocalSearchOperatorVector : IDisposable,
314                                                      System.Collections.IEnumerable
315 #if !SWIG_DOTNET_1
316         ,
317                                                      System.Collections.Generic.IList<LocalSearchOperator>
318 #endif
319     {
320         // cast from C# LocalSearchOperator array
operator LocalSearchOperatorVector(LocalSearchOperator[] inVal)321         public static implicit operator LocalSearchOperatorVector(LocalSearchOperator[] inVal)
322         {
323             var outVal = new LocalSearchOperatorVector();
324             foreach (LocalSearchOperator element in inVal)
325             {
326                 outVal.Add(element);
327             }
328             return outVal;
329         }
330 
331         // cast to C# LocalSearchOperator array
operator LocalSearchOperator[](LocalSearchOperatorVector inVal)332         public static implicit operator LocalSearchOperator[](LocalSearchOperatorVector inVal)
333         {
334             var outVal = new LocalSearchOperator[inVal.Count];
335             inVal.CopyTo(outVal);
336             return outVal;
337         }
338     }
339 
340     public partial class LocalSearchFilterVector : IDisposable,
341                                                    System.Collections.IEnumerable
342 #if !SWIG_DOTNET_1
343         ,
344                                                    System.Collections.Generic.IList<LocalSearchFilter>
345 #endif
346     {
347         // cast from C# LocalSearchFilter array
operator LocalSearchFilterVector(LocalSearchFilter[] inVal)348         public static implicit operator LocalSearchFilterVector(LocalSearchFilter[] inVal)
349         {
350             var outVal = new LocalSearchFilterVector();
351             foreach (LocalSearchFilter element in inVal)
352             {
353                 outVal.Add(element);
354             }
355             return outVal;
356         }
357 
358         // cast to C# LocalSearchFilter array
operator LocalSearchFilter[](LocalSearchFilterVector inVal)359         public static implicit operator LocalSearchFilter[](LocalSearchFilterVector inVal)
360         {
361             var outVal = new LocalSearchFilter[inVal.Count];
362             inVal.CopyTo(outVal);
363             return outVal;
364         }
365     }
366 
367     public partial class SymmetryBreakerVector : IDisposable,
368                                                  System.Collections.IEnumerable
369 #if !SWIG_DOTNET_1
370         ,
371                                                  System.Collections.Generic.IList<SymmetryBreaker>
372 #endif
373     {
374         // cast from C# SymmetryBreaker array
operator SymmetryBreakerVector(SymmetryBreaker[] inVal)375         public static implicit operator SymmetryBreakerVector(SymmetryBreaker[] inVal)
376         {
377             var outVal = new SymmetryBreakerVector();
378             foreach (SymmetryBreaker element in inVal)
379             {
380                 outVal.Add(element);
381             }
382             return outVal;
383         }
384 
385         // cast to C# SymmetryBreaker array
operator SymmetryBreaker[](SymmetryBreakerVector inVal)386         public static implicit operator SymmetryBreaker[](SymmetryBreakerVector inVal)
387         {
388             var outVal = new SymmetryBreaker[inVal.Count];
389             inVal.CopyTo(outVal);
390             return outVal;
391         }
392     }
393 } // namespace Google.OrTools.ConstraintSolver
394