Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
07/28/11 14:16:21 (13 years ago)
Author:
svonolfe
Message:

Merged changes from trunk (#1561) into branch (#1177)

Location:
branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Analyzer/BestSolution/BestVRPSolutionAnalyzer.cs

    r5867 r6607  
    153153          else
    154154            results.Add(new Result("Best valid VRP Solution", validSolution));
     155
     156          results.Add(new Result("Best valid VRP Solution Distance", new DoubleValue(distances[i].Value)));
     157          results.Add(new Result("Best valid VRP Solution VehicleUtilization", new DoubleValue(vehiclesUtilizations[i].Value)));
    155158        }
    156159      } else {
     
    160163            validSolution.Solution = best.Clone() as IVRPEncoding;
    161164            validSolution.Quality.Value = qualities[i].Value;
     165            (results["Best valid VRP Solution Distance"].Value as DoubleValue).Value = distances[i].Value;
     166            (results["Best valid VRP Solution VehicleUtilization"].Value as DoubleValue).Value = vehiclesUtilizations[i].Value;
    162167          }
    163168        }
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Alba/Moves/LambdaInterchange/AlbaStochasticLambdaInterchangeMutliMoveGenerator.cs

    r5867 r6607  
    6262    }
    6363
    64     protected override AlbaLambdaInterchangeMove[] GenerateMoves(AlbaEncoding individual, IVRPProblemInstance problemInstance, int lambda) {
    65       int sampleSize = SampleSizeParameter.ActualValue.Value;
    66 
     64    public static AlbaLambdaInterchangeMove[] GenerateAllMoves(AlbaEncoding individual, IVRPProblemInstance problemInstance, int lambda, int sampleSize, IRandom rand) {
    6765      AlbaLambdaInterchangeMove[] moves = new AlbaLambdaInterchangeMove[sampleSize];
    6866      for (int i = 0; i < sampleSize; i++) {
    6967        moves[i] = AlbaStochasticLambdaInterchangeSingleMoveGenerator.Apply(
    70           individual, problemInstance.Cities.Value, lambda, RandomParameter.ActualValue);
     68          individual, problemInstance.Cities.Value, lambda, rand);
    7169      }
    7270
    7371      return moves;
    7472    }
     73
     74    protected override AlbaLambdaInterchangeMove[] GenerateMoves(AlbaEncoding individual, IVRPProblemInstance problemInstance, int lambda) {
     75      return GenerateAllMoves(individual, problemInstance, lambda, SampleSizeParameter.Value.Value, RandomParameter.ActualValue);
     76    }
    7577  }
    7678}
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/General/Moves/VRPMoveMaker.cs

    r5127 r6607  
    7474         
    7575            string resultName = evaluatorParameter.ActualName;
    76             if (!this.Parameters.Exists(p => p.Name == resultName)) {
     76            if (!this.Parameters.ContainsKey(resultName)) {
    7777              ILookupParameter resultParameter = new LookupParameter<IItem>(resultName);
    7878              resultParameter.ExecutionContext = ExecutionContext;
     
    8282
    8383            string moveResultName = VRPMoveEvaluator.MovePrefix + resultName;
    84             if (!this.Parameters.Exists(p => p.Name == moveResultName)) {
     84            if (!this.Parameters.ContainsKey(moveResultName)) {
    8585              ILookupParameter moveResultParameter = new LookupParameter<IItem>(moveResultName);
    8686              moveResultParameter.ExecutionContext = ExecutionContext;
     
    9191            ILookupParameter result = Parameters[resultName] as ILookupParameter;
    9292            ILookupParameter moveResult = Parameters[moveResultName] as ILookupParameter;
    93             result.ActualValue = moveResult.ActualValue.Clone() as IItem;
     93            result.ActualValue = moveResult.ActualValue;
    9494          }
    9595        }
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Creators/IterativeInsertionCreator.cs

    r5127 r6607  
    8383    private static PotvinEncoding CreateSolution(IVRPProblemInstance instance, IRandom random, bool adhereTimeWindows) {
    8484      PotvinEncoding result = new PotvinEncoding(instance);
    85       IVRPEvaluator eval = instance.EvaluatorParameter.Value;
    8685
    8786      List<int> customers = new List<int>();
     
    105104        currentTour.Stops.Insert(stopIdx, customers[index]);
    106105
    107         CVRPEvaluation evaluation = eval.Evaluate(instance, currentTour) as CVRPEvaluation;
     106        CVRPEvaluation evaluation = instance.Evaluate(currentTour) as CVRPEvaluation;
    108107        if (result.Tours.Count < instance.Vehicles.Value &&
    109           ((adhereTimeWindows && !eval.Feasible(evaluation)) || ((!adhereTimeWindows) && evaluation.Overload > double.Epsilon))) {
     108          ((adhereTimeWindows && !instance.Feasible(evaluation)) || ((!adhereTimeWindows) && evaluation.Overload > double.Epsilon))) {
    110109          currentTour.Stops.RemoveAt(stopIdx);
    111110
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Crossovers/PotvinCrossover.cs

    r4752 r6607  
    3939    }
    4040
     41    public IValueParameter<BoolValue> AllowInfeasibleSolutions {
     42      get { return (IValueParameter<BoolValue>)Parameters["AllowInfeasibleSolutions"]; }
     43    }
     44
    4145    [StorableConstructor]
    4246    protected PotvinCrossover(bool deserializing) : base(deserializing) { }
     
    4448    public PotvinCrossover() {
    4549      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic manipulation operators."));
     50      Parameters.Add(new ValueParameter<BoolValue>("AllowInfeasibleSolutions", "Indicates if infeasible solutions should be allowed.", new BoolValue(false)));
    4651    }
    4752
     
    5257    protected abstract PotvinEncoding Crossover(IRandom random, PotvinEncoding parent1, PotvinEncoding parent2);
    5358
    54     protected bool FindInsertionPlace(PotvinEncoding individual, int city, out int route, out int place) {
     59    protected static bool FindInsertionPlace(PotvinEncoding individual, int city, bool allowInfeasible,
     60        out int route, out int place) {
    5561      return individual.FindInsertionPlace(
    56         city, -1, out route, out place);
     62        city, -1, allowInfeasible,
     63        out route, out place);
    5764    }
    5865
     
    7077    }
    7178
    72     protected bool Repair(IRandom random, PotvinEncoding solution, Tour newTour) {
     79    protected static bool RouteUnrouted(PotvinEncoding solution, bool allowInfeasible) {
    7380      bool success = true;
    74      
     81      int index = 0;
     82      while (index < solution.Unrouted.Count && success) {
     83        int unrouted = solution.Unrouted[index];
     84
     85        int route, place;
     86        if (FindInsertionPlace(solution, unrouted, allowInfeasible,
     87          out route, out place)) {
     88          solution.Tours[route].Stops.Insert(place, unrouted);
     89        } else {
     90          success = false;
     91        }
     92
     93        index++;
     94      }
     95
     96      for (int i = 0; i < index; i++)
     97        solution.Unrouted.RemoveAt(0);
     98
     99      return success;
     100    }
     101
     102    protected static bool Repair(IRandom random, PotvinEncoding solution, Tour newTour, IVRPProblemInstance instance, bool allowInfeasible) {
     103      bool success = true;
     104
    75105      //remove duplicates from new tour     
    76106      for (int i = 0; i < newTour.Stops.Count; i++) {
     
    106136      }
    107137
     138      if (!allowInfeasible && !instance.Feasible(newTour))
     139        return false;
     140
    108141      //route unrouted vehicles
    109       int index = 0;
    110       while (index < solution.Unrouted.Count && success) {
    111         int unrouted = solution.Unrouted[index];
    112 
    113         int route, place;
    114         if(FindInsertionPlace(solution, unrouted, out route, out place)) {
    115           solution.Tours[route].Stops.Insert(place, unrouted);
    116         } else {
    117           success = false;
    118         }
    119 
    120         index++;
    121       }
    122 
    123       for (int i = 0; i < index; i++)
    124         solution.Unrouted.RemoveAt(0);
     142      success = RouteUnrouted(solution, allowInfeasible);
    125143
    126144      return success;
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Crossovers/PotvinRouteBasedCrossover.cs

    r4752 r6607  
    4646     
    4747    protected override PotvinEncoding Crossover(IRandom random, PotvinEncoding parent1, PotvinEncoding parent2) {
     48      bool allowInfeasible = AllowInfeasibleSolutions.Value.Value;
     49
    4850      PotvinEncoding child = parent2.Clone() as PotvinEncoding;
    4951
     
    6163          child.Unrouted.Add(city);
    6264
    63       if (Repair(random, child, replacing))
     65      if (Repair(random, child, replacing, ProblemInstance, allowInfeasible) || allowInfeasible)
    6466        return child;
    6567      else {
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Crossovers/PotvinSequenceBasedCrossover.cs

    r4752 r6607  
    4646       
    4747    protected override PotvinEncoding Crossover(IRandom random, PotvinEncoding parent1, PotvinEncoding parent2) {
     48      bool allowInfeasible = AllowInfeasibleSolutions.Value.Value;
     49     
    4850      PotvinEncoding child = parent1.Clone() as PotvinEncoding;
    4951      Tour newTour = new Tour();
     
    7678          child.Unrouted.Add(city);
    7779
    78       if (ProblemInstance.Feasible(newTour) &&
    79           Repair(random, child, newTour)) {
     80      if (Repair(random, child, newTour, ProblemInstance, allowInfeasible) || allowInfeasible) {
    8081        return child;
    8182      } else {
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Manipulators/PotvinManipulator.cs

    r4752 r6607  
    3838    }
    3939
     40    public IValueParameter<BoolValue> AllowInfeasibleSolutions {
     41      get { return (IValueParameter<BoolValue>)Parameters["AllowInfeasibleSolutions"]; }
     42    }
     43
    4044    [StorableConstructor]
    4145    protected PotvinManipulator(bool deserializing) : base(deserializing) { }
     
    4347    public PotvinManipulator() {
    4448      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic manipulation operators."));
     49      Parameters.Add(new ValueParameter<BoolValue>("AllowInfeasibleSolutions", "Indicates if infeasible solutions should be allowed.", new BoolValue(false)));
    4550    }
    4651
     
    7883    }
    7984
    80     protected bool FindInsertionPlace(PotvinEncoding individual, int city, int routeToAvoid, out int route, out int place) {
     85    protected bool FindInsertionPlace(PotvinEncoding individual, int city, int routeToAvoid, bool allowInfeasible, out int route, out int place) {
    8186      return individual.FindInsertionPlace(
    82         city, routeToAvoid, out route, out place);
     87        city, routeToAvoid, allowInfeasible, out route, out place);
    8388    }
    8489   
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Manipulators/PotvinOneLevelExchangeManipulator.cs

    r4752 r6607  
    4646   
    4747    protected override void Manipulate(IRandom random, PotvinEncoding individual) {
     48      bool allowInfeasible = AllowInfeasibleSolutions.Value.Value;
     49     
    4850      int selectedIndex = SelectRandomTourBiasedByLength(random, individual);
    4951      Tour route1 =
     
    5456        int insertedRoute, insertedPlace;
    5557
    56         if (FindInsertionPlace(individual, route1.Stops[i], selectedIndex, out insertedRoute, out insertedPlace)) {
     58        if (FindInsertionPlace(individual, route1.Stops[i], selectedIndex, allowInfeasible, out insertedRoute, out insertedPlace)) {
    5759          individual.Tours[insertedRoute].Stops.Insert(insertedPlace, route1.Stops[i]);
    5860          replaced.Add(route1.Stops[i]);
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Manipulators/PotvinTwoLevelExchangeManipulator.cs

    r5867 r6607  
    4646
    4747    protected override void Manipulate(IRandom random, PotvinEncoding individual) {
     48      bool allowInfeasible = AllowInfeasibleSolutions.Value.Value;
     49     
    4850      int selectedIndex = SelectRandomTourBiasedByLength(random, individual);
    4951      Tour route1 = individual.Tours[selectedIndex];
     
    6567                int routeIdx, place;
    6668                if (FindInsertionPlace(individual,
    67                   customer2, selectedIndex, out routeIdx, out place)) {
     69                  customer2, selectedIndex, allowInfeasible, out routeIdx, out place)) {
    6870                  individual.Tours[routeIdx].Stops.Insert(place, customer2);
    6971                  route1.Stops.RemoveAt(customer1Position);
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Moves/CustomerRelocation/PotvinCustomerRelocationMoveMaker.cs

    r5867 r6607  
    106106
    107107      //reset move quality
    108       VRPEvaluation eval = ProblemInstance.EvaluatorParameter.Value.Evaluate(ProblemInstance, newSolution);
     108      VRPEvaluation eval = ProblemInstance.Evaluate(newSolution);
    109109      MoveQualityParameter.ActualValue.Value = eval.Quality;
    110110
    111111      //update penalty factor
    112112      double sigma = SigmaParameter.Value.Value;
    113       if (ProblemInstance.EvaluatorParameter.Value.Feasible(eval)) {
     113      if (ProblemInstance.Feasible(eval)) {
    114114        newSolution.PenaltyFactor /= (1 + sigma);
    115115        if (newSolution.PenaltyFactor < MinPenaltyFactorParameter.Value.Value)
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/PotvinEncoding.cs

    r5202 r6607  
    8080
    8181    public double GetTourLength(Tour tour) {
    82       double length = 0;
    83 
    84       if (tour.Stops.Count > 0) {
    85         List<int> cities = new List<int>();
    86         cities.Add(0);
    87         foreach (int city in tour.Stops) {
    88           cities.Add(city);
    89         }
    90         cities.Add(0);
    91 
    92         for (int i = 1; i < cities.Count; i++) {
    93           length += ProblemInstance.GetDistance(cities[i - 1], cities[i]);
    94         }
    95       } 
    96 
    97       return length;
     82      return tour.GetTourLength(ProblemInstance);
    9883    }
    9984
     
    10590        tour.Stops.Insert(i, city);
    10691
    107         VRPEvaluation eval = ProblemInstance.EvaluatorParameter.Value.Evaluate(ProblemInstance, tour);
     92        VRPEvaluation eval = ProblemInstance.Evaluate(tour);
    10893        double quality = eval.Quality + eval.Penalty * (PenaltyFactor - 1.0);
    10994
     
    122107    }
    123108
    124     public bool FindInsertionPlace(int city, int routeToAvoid, out int route, out int place) {
     109    public bool FindInsertionPlace(int city, int routeToAvoid, bool allowInfeasible, out int route, out int place) {
    125110      route = -1;
    126111      place = -1;
    127       double minDetour = 0;
     112      bool bestFeasible = false;
     113      double minDetour = double.MaxValue;
    128114
    129115      for (int tour = 0; tour < Tours.Count; tour++) {
    130116        if (tour != routeToAvoid) {
    131           double length = GetTourLength(Tours[tour]);
     117          for (int i = 0; i <= Tours[tour].Stops.Count; i++) {
     118            double length = GetTourLength(Tours[tour]);
    132119
    133           for (int i = 0; i <= Tours[tour].Stops.Count; i++) {
    134120            Tours[tour].Stops.Insert(i, city);
    135121
    136             VRPEvaluation eval = ProblemInstance.EvaluatorParameter.Value.Evaluate(
    137               ProblemInstance, Tours[tour]);
    138             if (ProblemInstance.EvaluatorParameter.Value.Feasible(eval)) {
    139               double newLength = eval.Distance;
     122            bool feasible = ProblemInstance.Feasible(Tours[tour]);
    140123
     124            if (feasible || allowInfeasible && !bestFeasible) {
     125              double newLength = GetTourLength(Tours[tour]);
    141126              double detour = newLength - length;
    142127
    143               if (route <= 0 || detour < minDetour) {
     128              if (route < 0 || detour < minDetour || feasible && !bestFeasible) {
    144129                route = tour;
    145130                place = i;
    146131                minDetour = detour;
     132
     133                if (feasible)
     134                  bestFeasible = true;
    147135              }
    148136            }
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Prins/Manipulators/PrinsLSManipulator.cs

    r4752 r6607  
    4949
    5050    protected double GetQuality(PrinsEncoding individual) {
    51       return ProblemInstance.Evaluate(individual);
     51      return ProblemInstance.Evaluate(individual).Quality;
    5252    }
    5353
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Prins/PrinsEncoding.cs

    r4752 r6607  
    6161
    6262          VRPEvaluation eval =
    63             ProblemInstance.EvaluatorParameter.Value.Evaluate(ProblemInstance,
    64              tour);
     63            ProblemInstance.Evaluate(tour);
    6564
    6665          double cost = eval.Quality;
    67           feasible = ProblemInstance.EvaluatorParameter.Value.Feasible(eval);
     66          feasible = ProblemInstance.Feasible(eval);
    6867
    6968          if (feasible) {
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Tour.cs

    r4752 r6607  
    2727using HeuristicLab.Common;
    2828using HeuristicLab.Core;
     29using HeuristicLab.Problems.VehicleRouting.Interfaces;
    2930
    3031namespace HeuristicLab.Problems.VehicleRouting {
     
    4647        this.Stops = new List<int>(original.Stops);
    4748    }
     49
     50    public double GetTourLength(IVRPProblemInstance instance) {
     51      double length = 0;
     52
     53      if (Stops.Count > 0) {
     54        List<int> cities = new List<int>();
     55        cities.Add(0);
     56        foreach (int city in Stops) {
     57          cities.Add(city);
     58        }
     59        cities.Add(0);
     60
     61        for (int i = 1; i < cities.Count; i++) {
     62          length += instance.GetDistance(cities[i - 1], cities[i]);
     63        }
     64      }
     65
     66      return length;
     67    }
    4868  }
    4969}
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/HeuristicLab.Problems.VehicleRouting-3.4.csproj

    r6093 r6607  
    128128    <Compile Include="Encodings\Alba\Crossovers\AlbaCrossover.cs" />
    129129    <Compile Include="Encodings\Alba\Crossovers\AlbaPermutationCrossover.cs" />
     130    <Compile Include="Encodings\Alba\LocalImprovement\AlbaLambdaInterchangeLocalImprovementOperator.cs" />
    130131    <Compile Include="Encodings\Alba\Manipulators\AlbaCustomerInsertionManipulator.cs" />
    131132    <Compile Include="Encodings\Alba\Manipulators\AlbaCustomerInversionManipulator.cs" />
     
    194195    <Compile Include="Encodings\Potvin\Creators\IterativeInsertionCreator.cs" />
    195196    <Compile Include="Encodings\Potvin\Crossovers\PotvinCrossover.cs" />
     197    <Compile Include="Encodings\Potvin\Crossovers\PotvinInsertionBasedCrossover.cs" />
    196198    <Compile Include="Encodings\Potvin\Crossovers\PotvinRouteBasedCrossover.cs" />
    197199    <Compile Include="Encodings\Potvin\Crossovers\PotvinSequenceBasedCrossover.cs" />
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Interfaces/IVRPProblemInstance.cs

    r5867 r6607  
    2727using HeuristicLab.Core;
    2828using HeuristicLab.Data;
     29using HeuristicLab.Problems.VehicleRouting.ProblemInstances;
    2930
    3031namespace HeuristicLab.Problems.VehicleRouting.Interfaces {
     
    5051    bool Feasible(IVRPEncoding solution);
    5152    bool Feasible(Tour tour);
    52     double Evaluate(IVRPEncoding solution);
    53     double Evaluate(Tour tour);
     53    VRPEvaluation Evaluate(IVRPEncoding solution);
     54    VRPEvaluation Evaluate(Tour tour);
     55    bool Feasible(VRPEvaluation eval);
    5456  }
    5557}
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/ProblemInstances/VRPProblemInstance.cs

    r5867 r6607  
    187187      return distanceMatrix;
    188188    }
    189    
     189
     190    //cache for performance improvement
     191    private DoubleMatrix distanceMatrix = null;
     192    private IVRPEvaluator evaluator = null;
     193
    190194    public double GetDistance(int start, int end) {
    191195      double distance = 0.0;
    192       DoubleMatrix distanceMatrix = DistanceMatrix;
    193 
    194196      if (distanceMatrix == null && UseDistanceMatrix.Value) {
    195197        distanceMatrix = DistanceMatrix = CreateDistanceMatrix();
     
    205207
    206208    public bool Feasible(IVRPEncoding solution) {
    207       return EvaluatorParameter.Value.Feasible(
    208         EvaluatorParameter.Value.Evaluate(
     209      return evaluator.Feasible(
     210        evaluator.Evaluate(
    209211          this, solution));
    210212    }
    211213
    212214    public bool Feasible(Tour tour) {
    213       return EvaluatorParameter.Value.Feasible(
    214         EvaluatorParameter.Value.Evaluate(
     215      return evaluator.Feasible(
     216        evaluator.Evaluate(
    215217        this, tour));
    216218    }
    217219
    218     public double Evaluate(IVRPEncoding solution) {
    219       return EvaluatorParameter.Value.Evaluate(this, solution).Quality;
    220     }
    221 
    222     public double Evaluate(Tour tour) {
    223       return EvaluatorParameter.Value.Evaluate(this, tour).Quality;
     220    public VRPEvaluation Evaluate(IVRPEncoding solution) {
     221      return evaluator.Evaluate(this, solution);
     222    }
     223
     224    public VRPEvaluation Evaluate(Tour tour) {
     225      return evaluator.Evaluate(this, tour);
     226    }
     227
     228    public bool Feasible(VRPEvaluation eval) {
     229      return evaluator.Feasible(eval);
    224230    }
    225231
     
    227233      if (BestKnownSolution != null) {
    228234        //call evaluator
    229         BestKnownQuality = new DoubleValue(Evaluate(BestKnownSolution.Solution));
     235        BestKnownQuality = new DoubleValue(Evaluate(BestKnownSolution.Solution).Quality);
    230236        BestKnownSolution.Quality = BestKnownQuality;
    231237      } else {
     
    275281      }
    276282      #endregion
    277      
     283
    278284      AttachEventHandlers();
    279285    }
    280286
    281287    private void AttachEventHandlers() {
     288      evaluator = EvaluatorParameter.Value;
    282289      EvaluatorParameter.ValueChanged += new EventHandler(EvaluatorParameter_ValueChanged);
    283290      BestKnownSolutionParameter.ValueChanged += new EventHandler(BestKnownSolutionParameter_ValueChanged);
     
    298305    void EvaluatorParameter_ValueChanged(object sender, EventArgs e) {
    299306      moveEvaluator = null;
     307      evaluator = EvaluatorParameter.Value;
    300308    }
    301309
     
    322330        DistanceMatrix.Reset += new EventHandler(DistanceMatrix_Reset);
    323331      }
     332      distanceMatrix = DistanceMatrix;
    324333      EvalBestKnownSolution();
    325334    }
     
    328337    }
    329338    void DistanceMatrix_ItemChanged(object sender, EventArgs<int, int> e) {
     339      distanceMatrix = DistanceMatrix;
    330340      EvalBestKnownSolution();
    331341    }
    332342    void UseDistanceMatrixParameter_ValueChanged(object sender, EventArgs e) {
    333343      UseDistanceMatrix.ValueChanged += new EventHandler(UseDistanceMatrix_ValueChanged);
     344      if (!UseDistanceMatrix.Value)
     345        distanceMatrix = null;
    334346      EvalBestKnownSolution();
    335347    }
    336348    void UseDistanceMatrix_ValueChanged(object sender, EventArgs e) {
     349      if (!UseDistanceMatrix.Value)
     350        distanceMatrix = null;
    337351      EvalBestKnownSolution();
    338352    }
Note: See TracChangeset for help on using the changeset viewer.