From fd67eabfddc19dcd9a08f76c430ff308f0327d47 Mon Sep 17 00:00:00 2001 From: bollhals Date: Tue, 25 Jan 2022 01:16:38 +0100 Subject: [PATCH] improve GetVarValueMap --- ortools/sat/csharp/CpModel.cs | 63 ++++++++++++++---------- ortools/sat/csharp/IntegerExpressions.cs | 11 ++--- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/ortools/sat/csharp/CpModel.cs b/ortools/sat/csharp/CpModel.cs index 7cfddcb507..458f8bdb2b 100644 --- a/ortools/sat/csharp/CpModel.cs +++ b/ortools/sat/csharp/CpModel.cs @@ -26,7 +26,8 @@ public class CpModel { model_ = new CpModelProto(); constant_map_ = new Dictionary(); - terms_ = new Queue(); + var_value_map_ = new Dictionary(10); + terms_ = new Queue(10); } // Getters. @@ -121,17 +122,15 @@ public class CpModel private long FillLinearConstraint(LinearExpr expr, out LinearConstraintProto linear) { - linear = new LinearConstraintProto(); - Dictionary dict = new Dictionary(); - long constant = LinearExpr.GetVarValueMap(expr, 1L, dict, terms_); + var dict = var_value_map_; + dict.Clear(); + long constant = LinearExpr.GetVarValueMap(expr, dict, terms_); var count = dict.Count; + linear = new LinearConstraintProto(); linear.Vars.Capacity = count; + linear.Vars.AddRange(dict.Keys); linear.Coeffs.Capacity = count; - foreach (KeyValuePair term in dict) - { - linear.Vars.Add(term.Key.Index); - linear.Coeffs.Add(term.Value); - } + linear.Coeffs.AddRange(dict.Values); return constant; } /** @@ -1099,27 +1098,28 @@ public class CpModel } else { - Dictionary dict = new Dictionary(); - long constant = LinearExpr.GetVarValueMap(obj, 1L, dict, terms_); + var dict = var_value_map_; + dict.Clear(); + long constant = LinearExpr.GetVarValueMap(obj, dict, terms_); + var dictCount = dict.Count; + objective.Vars.Capacity = dictCount; + objective.Vars.AddRange(dict.Keys); + objective.Coeffs.Capacity = dictCount; if (minimize) { + objective.Coeffs.AddRange(dict.Values); objective.ScalingFactor = 1L; objective.Offset = constant; } else { + foreach (var coeff in dict.Values) + { + objective.Coeffs.Add(-coeff); + } objective.ScalingFactor = -1L; objective.Offset = -constant; } - - var dictCount = dict.Count; - objective.Vars.Capacity = dictCount; - objective.Coeffs.Capacity = dictCount; - foreach (KeyValuePair it in dict) - { - objective.Vars.Add(it.Key.Index); - objective.Coeffs.Add(minimize ? it.Value : -it.Value); - } } model_.Objective = objective; } @@ -1191,25 +1191,36 @@ public class CpModel internal LinearExpressionProto GetLinearExpressionProto(LinearExpr expr, bool negate = false) { - Dictionary dict = new Dictionary(); - long constant = LinearExpr.GetVarValueMap(expr, 1L, dict, terms_); + var dict = var_value_map_; + dict.Clear(); + long constant = LinearExpr.GetVarValueMap(expr, dict, terms_); long mult = negate ? -1 : 1; LinearExpressionProto linear = new LinearExpressionProto(); var dictCount = dict.Count; linear.Vars.Capacity = dictCount; + linear.Vars.AddRange(dict.Keys); linear.Coeffs.Capacity = dictCount; - foreach (KeyValuePair term in dict) + if (!negate) { - linear.Vars.Add(term.Key.Index); - linear.Coeffs.Add(term.Value * mult); + linear.Coeffs.AddRange(dict.Values); + linear.Offset = constant; } - linear.Offset = constant * mult; + else + { + foreach (var coeff in dict.Values) + { + linear.Coeffs.Add(-coeff); + } + linear.Offset = -constant; + } + return linear; } private CpModelProto model_; private Dictionary constant_map_; + private Dictionary var_value_map_; private BoolVar true_literal_; private Queue terms_; } diff --git a/ortools/sat/csharp/IntegerExpressions.cs b/ortools/sat/csharp/IntegerExpressions.cs index c922604b00..10e6640fb3 100644 --- a/ortools/sat/csharp/IntegerExpressions.cs +++ b/ortools/sat/csharp/IntegerExpressions.cs @@ -35,7 +35,7 @@ public interface ILiteral internal static class HelperExtensions { [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void AddOrIncrement(this Dictionary dict, IntVar key, long increment) + public static void AddOrIncrement(this Dictionary dict, int key, long increment) { #if NET6_0_OR_GREATER System.Runtime.InteropServices.CollectionsMarshal.GetValueRefOrAddDefault(dict, key, out _) += increment; @@ -360,11 +360,10 @@ public class LinearExpr } } - internal static long GetVarValueMap(LinearExpr e, long initial_coeff, Dictionary dict, - Queue terms) + internal static long GetVarValueMap(LinearExpr e, Dictionary dict, Queue terms) { long constant = 0; - long coefficient = initial_coeff; + long coefficient = 1; LinearExpr expr = e; terms.Clear(); @@ -390,10 +389,10 @@ public class LinearExpr } break; case IntVar intVar: - dict.AddOrIncrement(intVar, coefficient); + dict.AddOrIncrement(intVar.GetIndex(), coefficient); break; case NotBoolVar notBoolVar: - dict.AddOrIncrement((IntVar)notBoolVar.Not(), -coefficient); + dict.AddOrIncrement(notBoolVar.Not().GetIndex(), -coefficient); constant += coefficient; break; default: