Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
03/28/12 15:47:26 (12 years ago)
Author:
spimming
Message:

#1680: merged changes from trunk into branch

Location:
branches/HeuristicLab.Hive.Azure
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.Hive.Azure

  • branches/HeuristicLab.Hive.Azure/HeuristicLab.Problems.QuadraticAssignment

  • branches/HeuristicLab.Hive.Azure/HeuristicLab.Problems.QuadraticAssignment/3.3/QuadraticAssignmentProblem.cs

    r7270 r7669  
    2323using System.Collections.Generic;
    2424using System.Drawing;
    25 using System.IO;
    2625using System.Linq;
    27 using System.Reflection;
    2826using HeuristicLab.Common;
    2927using HeuristicLab.Core;
     
    3432using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    3533using HeuristicLab.PluginInfrastructure;
     34using HeuristicLab.Problems.Instances;
    3635
    3736namespace HeuristicLab.Problems.QuadraticAssignment {
     
    3938  [Creatable("Problems")]
    4039  [StorableClass]
    41   public sealed class QuadraticAssignmentProblem : SingleObjectiveHeuristicOptimizationProblem<IQAPEvaluator, IPermutationCreator>, IStorableContent {
    42     private static string InstancePrefix = "HeuristicLab.Problems.QuadraticAssignment.Data.";
    43 
     40  public sealed class QuadraticAssignmentProblem : SingleObjectiveHeuristicOptimizationProblem<IQAPEvaluator, IPermutationCreator>, IStorableContent,
     41    IProblemInstanceConsumer<QAPData>,
     42    IProblemInstanceConsumer<TSPData> {
    4443    public string Filename { get; set; }
    4544
     
    9291      get { return Operators.OfType<QAPPopulationDiversityAnalyzer>().FirstOrDefault(); }
    9392    }
    94 
    95     public IEnumerable<string> Instances {
    96       get {
    97         return Assembly.GetExecutingAssembly()
    98           .GetManifestResourceNames()
    99           .Where(x => x.EndsWith(".dat"))
    100           .OrderBy(x => x)
    101           .Select(x => x.Replace(".dat", String.Empty))
    102           .Select(x => x.Replace(InstancePrefix, String.Empty));
    103       }
    104     }
    10593    #endregion
    10694
     
    10997    private QuadraticAssignmentProblem(QuadraticAssignmentProblem original, Cloner cloner)
    11098      : base(original, cloner) {
    111       AttachEventHandlers();
     99      RegisterEventHandlers();
    112100    }
    113101    public QuadraticAssignmentProblem()
     
    142130
    143131      InitializeOperators();
    144       AttachEventHandlers();
     132      RegisterEventHandlers();
    145133    }
    146134
     
    165153        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));
    166154      }
    167       AttachEventHandlers();
     155      RegisterEventHandlers();
    168156      #endregion
    169157    }
     
    254242
    255243    #region Helpers
    256     private void AttachEventHandlers() {
     244    private void RegisterEventHandlers() {
    257245      SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged);
    258246      Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
     
    266254
    267255    private void InitializeOperators() {
    268       Operators.AddRange(ApplicationManager.Manager.GetInstances<IPermutationOperator>());
     256      var defaultOperators = new HashSet<IPermutationOperator>(new IPermutationOperator[] {
     257        new PartiallyMatchedCrossover(),
     258        new Swap2Manipulator(),
     259        new ExhaustiveSwap2MoveGenerator()
     260      });
     261      Operators.AddRange(defaultOperators);
     262      Operators.AddRange(ApplicationManager.Manager.GetInstances<IPermutationOperator>().Except(defaultOperators, new TypeEqualityComparer<IPermutationOperator>()));
    269263      Operators.RemoveAll(x => x is ISingleObjectiveMoveEvaluator);
    270264      Operators.AddRange(ApplicationManager.Manager.GetInstances<IQAPMoveEvaluator>());
     
    365359    #endregion
    366360
    367     public void LoadInstanceFromFile(string filename) {
    368       QAPLIBParser parser = new QAPLIBParser();
    369       parser.Parse(filename);
    370       if (parser.Error != null) throw parser.Error;
    371       Distances = new DoubleMatrix(parser.Distances);
    372       Weights = new DoubleMatrix(parser.Weights);
    373       Name = "Quadratic Assignment Problem (imported from " + Path.GetFileNameWithoutExtension(filename) + ")";
    374       Description = "Imported problem data using QAPLIBParser " + Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyFileVersionAttribute), true).Cast<AssemblyFileVersionAttribute>().FirstOrDefault().Version + ".";
     361    public void Load(QAPData data) {
     362      var weights = new DoubleMatrix(data.Weights);
     363      var distances = new DoubleMatrix(data.Distances);
     364      Name = data.Name;
     365      Description = data.Description;
     366      Load(weights, distances);
     367      EvaluateAndLoadAssignment(data.BestKnownAssignment);
     368      OnReset();
     369    }
     370
     371    public void Load(TSPData data) {
     372      if (data.Dimension > 1000)
     373        throw new System.IO.InvalidDataException("Instances with more than 1000 customers are not supported by the QAP.");
     374      var weights = new DoubleMatrix(data.Dimension, data.Dimension);
     375      for (int i = 0; i < data.Dimension; i++)
     376        weights[i, (i + 1) % data.Dimension] = 1;
     377      var distances = new DoubleMatrix(data.GetDistanceMatrix());
     378      Name = data.Name;
     379      Description = data.Description;
     380      Load(weights, distances);
     381      EvaluateAndLoadAssignment(data.BestKnownTour);
     382      OnReset();
     383    }
     384
     385    public void Load(DoubleMatrix weights, DoubleMatrix distances) {
     386      if (weights == null || weights.Rows == 0)
     387        throw new System.IO.InvalidDataException("The given instance does not contain weights!");
     388      if (weights.Rows != weights.Columns)
     389        throw new System.IO.InvalidDataException("The weights matrix is not a square matrix!");
     390      if (distances == null || distances.Rows == 0)
     391        throw new System.IO.InvalidDataException("The given instance does not contain distances!");
     392      if (distances.Rows != distances.Columns)
     393        throw new System.IO.InvalidDataException("The distances matrix is not a square matrix!");
     394      if (weights.Rows != distances.Columns)
     395        throw new System.IO.InvalidDataException("The weights matrix and the distance matrix are not of equal size!");
     396
     397      Weights = weights;
     398      Distances = distances;
     399
    375400      BestKnownQuality = null;
    376401      BestKnownSolution = null;
    377402      BestKnownSolutions = null;
    378       OnReset();
    379     }
    380 
    381     public void LoadInstanceFromFile(string datFilename, string slnFilename) {
    382       QAPLIBParser datParser = new QAPLIBParser();
    383       datParser.Parse(datFilename);
    384       if (datParser.Error != null) throw datParser.Error;
    385       Distances = new DoubleMatrix(datParser.Distances);
    386       Weights = new DoubleMatrix(datParser.Weights);
    387       Name = "Quadratic Assignment Problem (imported from " + Path.GetFileNameWithoutExtension(datFilename) + ")";
    388       Description = "Imported problem data using QAPLIBParser " + Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyFileVersionAttribute), true).Cast<AssemblyFileVersionAttribute>().FirstOrDefault().Version + ".";
    389 
    390       QAPLIBSolutionParser slnParser = new QAPLIBSolutionParser();
    391       slnParser.Parse(slnFilename, true);
    392       if (slnParser.Error != null) throw slnParser.Error;
    393 
    394       BestKnownQuality = new DoubleValue(slnParser.Quality);
    395       BestKnownSolution = new Permutation(PermutationTypes.Absolute, slnParser.Assignment);
    396       BestKnownSolutions = new ItemSet<Permutation>(new PermutationEqualityComparer());
    397       BestKnownSolutions.Add((Permutation)BestKnownSolution.Clone());
    398 
    399       if (!BestKnownQuality.Value.IsAlmost(QAPEvaluator.Apply(BestKnownSolution, Weights, Distances))) {
    400         // the solution doesn't result in the given quality, maybe indices and values are inverted
    401         // try parsing again, this time inverting them
    402         slnParser.Reset();
    403         slnParser.Parse(slnFilename, false);
    404         if (slnParser.Error != null) throw slnParser.Error;
    405 
    406         BestKnownQuality = new DoubleValue(slnParser.Quality);
    407         BestKnownSolution = new Permutation(PermutationTypes.Absolute, slnParser.Assignment);
    408         BestKnownSolutions = new ItemSet<Permutation>(new PermutationEqualityComparer());
    409         BestKnownSolutions.Add((Permutation)BestKnownSolution.Clone());
    410 
    411         if (!BestKnownQuality.Value.IsAlmost(QAPEvaluator.Apply(BestKnownSolution, Weights, Distances))) {
    412           // if the solution still doesn't result in the given quality, remove it and only take the quality
    413           BestKnownSolution = null;
    414           BestKnownSolutions = new ItemSet<Permutation>(new PermutationEqualityComparer());
    415         }
    416       }
    417       OnReset();
    418     }
    419 
    420     public void LoadInstanceFromEmbeddedResource(string instance) {
    421       using (Stream stream = Assembly.GetExecutingAssembly()
    422         .GetManifestResourceStream(InstancePrefix + instance + ".dat")) {
    423         QAPLIBParser datParser = new QAPLIBParser();
    424         datParser.Parse(stream);
    425         if (datParser.Error != null) throw datParser.Error;
    426         Distances = new DoubleMatrix(datParser.Distances);
    427         Weights = new DoubleMatrix(datParser.Weights);
    428         Name = instance;
    429         Description = "Loaded embedded instance " + instance + " of plugin version " + Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyFileVersionAttribute), true).Cast<AssemblyFileVersionAttribute>().FirstOrDefault().Version + ".";
    430 
    431         bool solutionExists = Assembly.GetExecutingAssembly()
    432           .GetManifestResourceNames()
    433           .Where(x => x.EndsWith(instance + ".sln"))
    434           .Any();
    435 
    436         if (solutionExists) {
    437           using (Stream solStream = Assembly.GetExecutingAssembly()
    438             .GetManifestResourceStream(InstancePrefix + instance + ".sln")) {
    439             QAPLIBSolutionParser slnParser = new QAPLIBSolutionParser();
    440             slnParser.Parse(solStream, true);
    441             if (slnParser.Error != null) throw slnParser.Error;
    442 
    443             BestKnownQuality = new DoubleValue(slnParser.Quality);
    444             BestKnownSolution = new Permutation(PermutationTypes.Absolute, slnParser.Assignment);
    445             BestKnownSolutions = new ItemSet<Permutation>(new PermutationEqualityComparer());
    446             BestKnownSolutions.Add((Permutation)BestKnownSolution.Clone());
    447 
    448             if (!BestKnownQuality.Value.IsAlmost(QAPEvaluator.Apply(BestKnownSolution, Weights, Distances))) {
    449               // the solution doesn't result in the given quality, maybe indices and values are inverted
    450               // try parsing again, this time inverting them
    451               solStream.Seek(0, SeekOrigin.Begin);
    452               slnParser.Reset();
    453               slnParser.Parse(solStream, false);
    454               if (slnParser.Error != null) throw slnParser.Error;
    455 
    456               BestKnownQuality = new DoubleValue(slnParser.Quality);
    457               BestKnownSolution = new Permutation(PermutationTypes.Absolute, slnParser.Assignment);
    458               BestKnownSolutions = new ItemSet<Permutation>(new PermutationEqualityComparer());
    459               BestKnownSolutions.Add((Permutation)BestKnownSolution.Clone());
    460 
    461               if (!BestKnownQuality.Value.IsAlmost(QAPEvaluator.Apply(BestKnownSolution, Weights, Distances))) {
    462                 // if the solution still doesn't result in the given quality, remove it and only take the quality
    463                 BestKnownSolution = null;
    464                 BestKnownSolutions = new ItemSet<Permutation>(new PermutationEqualityComparer());
    465               }
    466             }
    467           }
    468         } else {  // no solution exists
    469           BestKnownSolution = null;
    470           BestKnownSolutions = new ItemSet<Permutation>(new PermutationEqualityComparer());
    471           BestKnownQuality = null;
    472         }
    473       }
    474       OnReset();
     403    }
     404
     405    public void EvaluateAndLoadAssignment(int[] assignment) {
     406      if (assignment == null || assignment.Length == 0) return;
     407      var vector = new Permutation(PermutationTypes.Absolute, assignment);
     408      var result = QAPEvaluator.Apply(vector, Weights, Distances);
     409      BestKnownQuality = new DoubleValue(result);
     410      BestKnownSolution = vector;
     411      BestKnownSolutions = new ItemSet<Permutation>();
     412      BestKnownSolutions.Add((Permutation)vector.Clone());
    475413    }
    476414  }
Note: See TracChangeset for help on using the changeset viewer.