private void AfterDeserialization()
 {
     // BackwardsCompatibility3.3
     #region Backwards compatible code, remove with 3.4
     if (!Parameters.ContainsKey("BestKnownSolutions"))
     {
         Parameters.Add(new OptionalValueParameter <ItemSet <Permutation> >("BestKnownSolutions", "The list of best known solutions which is updated whenever a new better solution is found or may be the optimal solution if it is known beforehand.", null));
     }
     else if (Parameters["BestKnownSolutions"].GetType().Equals(typeof(OptionalValueParameter <ItemList <Permutation> >)))
     {
         ItemList <Permutation> list = ((OptionalValueParameter <ItemList <Permutation> >)Parameters["BestKnownSolutions"]).Value;
         Parameters.Remove("BestKnownSolutions");
         Parameters.Add(new OptionalValueParameter <ItemSet <Permutation> >("BestKnownSolutions", "The list of best known solutions which is updated whenever a new better solution is found or may be the optimal solution if it is known beforehand.", (list != null ? new ItemSet <Permutation>(list) : null)));
     }
     if (Parameters.ContainsKey("DistanceMatrix"))
     {
         DoubleMatrix d = ((ValueParameter <DoubleMatrix>)Parameters["DistanceMatrix"]).Value;
         Parameters.Remove("DistanceMatrix");
         Parameters.Add(new ValueParameter <DoubleMatrix>("Distances", "The distance matrix which can either be specified directly without the coordinates, or can be calculated automatically from the coordinates.", d));
     }
     if (!Parameters.ContainsKey("LowerBound"))
     {
         Parameters.Add(new OptionalValueParameter <DoubleValue>("LowerBound", "The Gilmore-Lawler lower bound to the solution quality."));
         LowerBound = new DoubleValue(GilmoreLawlerBoundCalculator.CalculateLowerBound(Weights, Distances));
     }
     if (!Parameters.ContainsKey("AverageQuality"))
     {
         Parameters.Add(new OptionalValueParameter <DoubleValue>("AverageQuality", "The expected quality of a random solution."));
         AverageQuality = new DoubleValue(ComputeAverageQuality());
     }
     #endregion
     RegisterEventHandlers();
 }
        private void UpdateParameterValues()
        {
            Permutation lbSolution;

            // calculate the optimum of a LAP relaxation and use it as lower bound of our QAP
            LowerBound = new DoubleValue(GilmoreLawlerBoundCalculator.CalculateLowerBound(Weights, Distances, out lbSolution));
            // evalute the LAP optimal solution as if it was a QAP solution
            var lbSolutionQuality = QAPEvaluator.Apply(lbSolution, Weights, Distances);

            // in case both qualities are the same it means that the LAP optimum is also a QAP optimum
            if (LowerBound.Value.IsAlmost(lbSolutionQuality))
            {
                BestKnownSolution = lbSolution;
                BestKnownQuality  = new DoubleValue(LowerBound.Value);
            }
            AverageQuality = new DoubleValue(ComputeAverageQuality());
        }