Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
02/28/20 16:23:01 (4 years ago)
Author:
abeham
Message:

#2521: worked on scheduling problem

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.Scheduling/3.3/JobShopSchedulingProblem.cs

    r17226 r17461  
    11#region License Information
    22/* HeuristicLab
    3  * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    44 *
    55 * This file is part of HeuristicLab.
     
    2121
    2222using System;
     23using System.ComponentModel;
    2324using System.Drawing;
    2425using System.Linq;
     26using System.Threading;
     27using HEAL.Attic;
    2528using HeuristicLab.Common;
    2629using HeuristicLab.Core;
     
    2831using HeuristicLab.Encodings.PermutationEncoding;
    2932using HeuristicLab.Encodings.ScheduleEncoding;
    30 using HeuristicLab.Encodings.ScheduleEncoding.JobSequenceMatrix;
    31 using HeuristicLab.Encodings.ScheduleEncoding.PermutationWithRepetition;
    32 using HeuristicLab.Encodings.ScheduleEncoding.PriorityRulesVector;
     33using HeuristicLab.Optimization;
    3334using HeuristicLab.Parameters;
    34 using HEAL.Attic;
    35 using HeuristicLab.PluginInfrastructure;
    3635using HeuristicLab.Problems.Instances;
    3736
    3837namespace HeuristicLab.Problems.Scheduling {
     38  public enum JSSPObjective { Makespan, Tardiness }
     39
    3940  [Item("Job Shop Scheduling Problem (JSSP)", "Represents a standard Job Shop Scheduling Problem")]
    4041  [Creatable(CreatableAttribute.Categories.CombinatorialProblems, Priority = 120)]
    41   [StorableType("BB12CCEC-A109-4A26-A1C7-5A0703AB7687")]
    42   public sealed class JobShopSchedulingProblem : SchedulingProblem, IProblemInstanceConsumer<JSSPData>, IProblemInstanceExporter<JSSPData>, IStorableContent {
     42  [StorableType("d6c72bd1-c6cc-4efb-9cc5-b73bb3845799")]
     43  public sealed class JobShopSchedulingProblem : SingleObjectiveProblem<IScheduleEncoding, IScheduleSolution>, IProblemInstanceConsumer<JSSPData>, IProblemInstanceExporter<JSSPData>, IStorableContent {
    4344    #region Default Instance
    4445    private static readonly JSSPData DefaultInstance = new JSSPData() {
    45       Name = "Job Shop Scheduling Problem (JSSP)",
    46       Description = "The default instance of the JSSP problem in HeuristicLab",
    4746      Jobs = 10,
    4847      Resources = 10,
     
    7574    #endregion
    7675
    77     public string Filename { get; set; }
    7876    public override Image ItemImage {
    7977      get { return HeuristicLab.Common.Resources.VSImageLibrary.Type; }
    8078    }
    81 
     79   
    8280    #region Parameter Properties
    83     public IValueParameter<ItemList<Job>> JobDataParameter {
    84       get { return (IValueParameter<ItemList<Job>>)Parameters["JobData"]; }
    85     }
    86     public OptionalValueParameter<Schedule> BestKnownSolutionParameter {
    87       get { return (OptionalValueParameter<Schedule>)Parameters["BestKnownSolution"]; }
    88     }
    89 
    90     public IFixedValueParameter<IntValue> JobsParameter {
    91       get { return (IFixedValueParameter<IntValue>)Parameters["Jobs"]; }
    92     }
    93     public IFixedValueParameter<IntValue> ResourcesParameter {
    94       get { return (IFixedValueParameter<IntValue>)Parameters["Resources"]; }
    95     }
    96     public IValueParameter<IScheduleEvaluator> ScheduleEvaluatorParameter {
    97       get { return (IValueParameter<IScheduleEvaluator>)Parameters["ScheduleEvaluator"]; }
    98     }
    99     public OptionalValueParameter<IScheduleDecoder> ScheduleDecoderParameter {
    100       get { return (OptionalValueParameter<IScheduleDecoder>)Parameters["ScheduleDecoder"]; }
    101     }
     81    [Storable] public IValueParameter<ItemList<Job>> JobDataParameter { get; private set; }
     82    [Storable] public OptionalValueParameter<Schedule> BestKnownSolutionParameter { get; private set; }
     83    [Storable] public IFixedValueParameter<IntValue> JobsParameter { get; private set; }
     84    [Storable] public IFixedValueParameter<IntValue> ResourcesParameter { get; private set; }
     85    [Storable] public IFixedValueParameter<EnumValue<JSSPObjective>> ObjectiveParameter { get; private set; }
    10286    #endregion
    10387
     
    119103      set { ResourcesParameter.Value.Value = value; }
    120104    }
    121     public IScheduleEvaluator ScheduleEvaluator {
    122       get { return ScheduleEvaluatorParameter.Value; }
    123       set { ScheduleEvaluatorParameter.Value = value; }
    124     }
    125     public IScheduleDecoder ScheduleDecoder {
    126       get { return ScheduleDecoderParameter.Value; }
    127       set { ScheduleDecoderParameter.Value = value; }
     105    public JSSPObjective Objective {
     106      get { return ObjectiveParameter.Value.Value; }
     107      set { ObjectiveParameter.Value.Value = value; }
    128108    }
    129109    #endregion
     
    131111    [StorableConstructor]
    132112    private JobShopSchedulingProblem(StorableConstructorFlag _) : base(_) { }
    133     private JobShopSchedulingProblem(JobShopSchedulingProblem original, Cloner cloner)
    134       : base(original, cloner) {
    135       RegisterEventHandlers();
    136     }
    137     public JobShopSchedulingProblem()
    138       : base(new SchedulingEvaluator(), new JSMRandomCreator()) {
    139       Parameters.Add(new ValueParameter<ItemList<Job>>("JobData", "Jobdata defining the precedence relationships and the duration of the tasks in this JSSP-Instance.", new ItemList<Job>()));
    140       Parameters.Add(new OptionalValueParameter<Schedule>("BestKnownSolution", "The best known solution of this JSSP instance."));
    141 
    142       Parameters.Add(new FixedValueParameter<IntValue>("Jobs", "The number of jobs used in this JSSP instance.", new IntValue()));
    143       Parameters.Add(new FixedValueParameter<IntValue>("Resources", "The number of resources used in this JSSP instance.", new IntValue()));
    144       Parameters.Add(new ValueParameter<IScheduleEvaluator>("ScheduleEvaluator", "The evaluator used to determine the quality of a solution.", new MakespanEvaluator()));
    145       Parameters.Add(new OptionalValueParameter<IScheduleDecoder>("ScheduleDecoder", "The operator that decodes the representation and creates a schedule.", new JSMDecoder()));
    146 
    147       EvaluatorParameter.GetsCollected = false;
    148       EvaluatorParameter.Hidden = true;
    149       ScheduleDecoderParameter.Hidden = true;
    150 
    151       InitializeOperators();
    152       Load(DefaultInstance);
    153       RegisterEventHandlers();
    154     }
    155 
    156     public override IDeepCloneable Clone(Cloner cloner) {
    157       return new JobShopSchedulingProblem(this, cloner);
    158     }
    159 
    160113    [StorableHook(HookType.AfterDeserialization)]
    161114    private void AfterDeserialization() {
     
    163116    }
    164117
     118    private JobShopSchedulingProblem(JobShopSchedulingProblem original, Cloner cloner)
     119      : base(original, cloner) {
     120      JobDataParameter = cloner.Clone(original.JobDataParameter);
     121      BestKnownSolutionParameter = cloner.Clone(original.BestKnownSolutionParameter);
     122      JobsParameter = cloner.Clone(original.JobsParameter);
     123      ResourcesParameter = cloner.Clone(original.ResourcesParameter);
     124      ObjectiveParameter = cloner.Clone(original.ObjectiveParameter);
     125
     126      RegisterEventHandlers();
     127    }
     128    public override IDeepCloneable Clone(Cloner cloner) {
     129      return new JobShopSchedulingProblem(this, cloner);
     130    }
     131
     132    public JobShopSchedulingProblem()
     133      : base(new JobSequenceMatrixEncoding()) {
     134      Parameters.Add(JobDataParameter = new ValueParameter<ItemList<Job>>("JobData", "Jobdata defining the precedence relationships and the duration of the tasks in this JSSP-Instance.", new ItemList<Job>()));
     135      Parameters.Add(BestKnownSolutionParameter = new OptionalValueParameter<Schedule>("BestKnownSolution", "The best known solution of this JSSP instance."));
     136      Parameters.Add(JobsParameter = new FixedValueParameter<IntValue>("Jobs", "The number of jobs used in this JSSP instance.", new IntValue()));
     137      Parameters.Add(ResourcesParameter = new FixedValueParameter<IntValue>("Resources", "The number of resources used in this JSSP instance.", new IntValue()));
     138      Parameters.Add(ObjectiveParameter = new FixedValueParameter<EnumValue<JSSPObjective>>("Objective", "The objective to use in the evaluation of a schedule.", new EnumValue<JSSPObjective>(JSSPObjective.Makespan)));
     139      EncodingParameter.Hidden = false;
     140
     141      Encoding.ResourcesParameter = ResourcesParameter;
     142      Encoding.JobsParameter = JobsParameter;
     143      Encoding.JobDataParameter = JobDataParameter;
     144
     145      Load(DefaultInstance);
     146      RegisterEventHandlers();
     147    }
     148
     149    public override ISingleObjectiveEvaluationResult Evaluate(IScheduleSolution solution, IRandom random, CancellationToken cancellationToken) {
     150      var schedule = Encoding.Decode(solution, JobData);
     151      switch (Objective) {
     152        case JSSPObjective.Makespan:
     153          return new SingleObjectiveEvaluationResult(Makespan.Calculate(schedule));
     154        case JSSPObjective.Tardiness:
     155          return new SingleObjectiveEvaluationResult(MeanTardiness.Calculate(schedule, JobData));
     156        default:
     157          throw new InvalidOperationException("Objective " + Objective + " unknown");
     158      }
     159    }
     160
     161    public override void Analyze(IScheduleSolution[] solutions, double[] qualities, ResultCollection results, IRandom random) {
     162      base.Analyze(solutions, qualities, results, random);
     163
     164      bool max = Maximization;
     165
     166      int i = -1;
     167      if (!max)
     168        i = qualities.Select((x, index) => new { index, x }).OrderBy(x => x.x).First().index;
     169      else i = qualities.Select((x, index) => new { index, x }).OrderByDescending(x => x.x).First().index;
     170
     171      if (double.IsNaN(BestKnownQuality) ||
     172          max && qualities[i] > BestKnownQuality ||
     173          !max && qualities[i] < BestKnownQuality) {
     174        BestKnownQuality = qualities[i];
     175        BestKnownSolution = Encoding.Decode(solutions[i], JobData);
     176      }
     177      Schedule bestSolution;
     178      if (results.TryGetValue("Best Scheduling Solution", out var result)) {
     179        bestSolution = result.Value as Schedule;
     180      } else bestSolution = null;
     181
     182      if (bestSolution == null || IsBetter(bestSolution.Quality, qualities[i]))
     183        results.AddOrUpdateResult("Best Scheduling Solution", Encoding.Decode(solutions[i], JobData));
     184    }
     185
     186    protected override void OnEncodingChanged() {
     187      base.OnEncodingChanged();
     188      Encoding.ResourcesParameter = ResourcesParameter;
     189      Encoding.JobsParameter = JobsParameter;
     190      Encoding.JobDataParameter = JobDataParameter;
     191    }
     192
     193
    165194    private void RegisterEventHandlers() {
    166       ScheduleEvaluatorParameter.ValueChanged += ScheduleEvaluatorParameter_ValueChanged;
    167       ScheduleEvaluator.QualityParameter.ActualNameChanged += ScheduleEvaluator_QualityParameter_ActualNameChanged;
    168       SolutionCreator.ScheduleEncodingParameter.ActualNameChanged += SolutionCreator_SchedulingEncodingParameter_ActualNameChanged;
    169       ScheduleDecoderParameter.ValueChanged += ScheduleDecoderParameter_ValueChanged;
    170       if (ScheduleDecoder != null) ScheduleDecoder.ScheduleParameter.ActualNameChanged += ScheduleDecoder_ScheduleParameter_ActualNameChanged;
    171     }
    172 
    173     #region Events
    174     protected override void OnSolutionCreatorChanged() {
    175       base.OnSolutionCreatorChanged();
    176       SolutionCreator.ScheduleEncodingParameter.ActualNameChanged += SolutionCreator_SchedulingEncodingParameter_ActualNameChanged;
    177       InitializeOperators();
    178     }
    179     protected override void OnEvaluatorChanged() {
    180       base.OnEvaluatorChanged();
    181       ParameterizeOperators();
    182     }
    183     private void ScheduleEvaluatorParameter_ValueChanged(object sender, EventArgs eventArgs) {
    184       ScheduleEvaluator.QualityParameter.ActualNameChanged += ScheduleEvaluator_QualityParameter_ActualNameChanged;
    185       ParameterizeOperators();
    186     }
    187     private void ScheduleEvaluator_QualityParameter_ActualNameChanged(object sender, EventArgs eventArgs) {
    188       ParameterizeOperators();
    189     }
    190 
    191     private void SolutionCreator_SchedulingEncodingParameter_ActualNameChanged(object sender, EventArgs eventArgs) {
    192       ParameterizeOperators();
    193     }
    194     private void ScheduleDecoderParameter_ValueChanged(object sender, EventArgs eventArgs) {
    195       if (ScheduleDecoder != null) ScheduleDecoder.ScheduleParameter.ActualNameChanged += ScheduleDecoder_ScheduleParameter_ActualNameChanged;
    196       ParameterizeOperators();
    197     }
    198     private void ScheduleDecoder_ScheduleParameter_ActualNameChanged(object sender, EventArgs eventArgs) {
    199       ParameterizeOperators();
    200     }
    201     #endregion
     195      JobDataParameter.ValueChanged += JobDataParameterOnValueChanged;
     196      JobData.PropertyChanged += JobDataOnPropertyChanged;
     197    }
     198
     199    private void JobDataParameterOnValueChanged(object sender, EventArgs e) {
     200      JobData.PropertyChanged += JobDataOnPropertyChanged;
     201      Jobs = JobData.Count;
     202    }
     203
     204    private void JobDataOnPropertyChanged(object sender, PropertyChangedEventArgs e) {
     205      if (e.PropertyName == nameof(JobData.Count)) {
     206        Jobs = JobData.Count;
     207      }
     208    }
    202209
    203210    #region Problem Instance Handling
     
    212219      }
    213220
    214       BestKnownQuality = data.BestKnownQuality.HasValue ? new DoubleValue(data.BestKnownQuality.Value) : null;
     221      BestKnownQuality = data.BestKnownQuality ?? double.NaN;
    215222      if (data.BestKnownSchedule != null) {
    216         var enc = new JSMEncoding();
    217         enc.JobSequenceMatrix = new ItemList<Permutation>(data.Resources);
     223        var enc = new JSM(0);
    218224        for (int i = 0; i < data.Resources; i++) {
    219           enc.JobSequenceMatrix[i] = new Permutation(PermutationTypes.Absolute, new int[data.Jobs]);
     225          enc.JobSequenceMatrix.Add(new Permutation(PermutationTypes.Absolute, new int[data.Jobs]));
    220226          for (int j = 0; j < data.Jobs; j++) {
    221227            enc.JobSequenceMatrix[i][j] = data.BestKnownSchedule[i, j];
    222228          }
    223229        }
    224         BestKnownSolution = new JSMDecoder().CreateScheduleFromEncoding(enc, jobData);
    225         if (ScheduleEvaluator is MeanTardinessEvaluator)
    226           BestKnownQuality = new DoubleValue(MeanTardinessEvaluator.GetMeanTardiness(BestKnownSolution, jobData));
    227         else if (ScheduleEvaluator is MakespanEvaluator)
    228           BestKnownQuality = new DoubleValue(MakespanEvaluator.GetMakespan(BestKnownSolution));
    229       }
    230       Name = data.Name;
    231       Description = data.Description;
     230        BestKnownSolution = JSMDecoder.Decode(enc, jobData, JSMDecodingErrorPolicy.RandomPolicy, JSMForcingStrategy.SwapForcing);
     231        switch (Objective) {
     232          case JSSPObjective.Makespan:
     233            BestKnownQuality = Makespan.Calculate(BestKnownSolution);
     234            break;
     235          case JSSPObjective.Tardiness:
     236            BestKnownQuality = MeanTardiness.Calculate(BestKnownSolution, jobData);
     237            break;
     238        }
     239      }
     240
    232241      JobData = jobData;
    233       Jobs = data.Jobs;
    234242      Resources = data.Resources;
    235243    }
     
    259267    #endregion
    260268
    261     #region Helpers
    262     private void InitializeOperators() {
    263       Operators.Clear();
    264       ApplyEncoding();
    265       Operators.Add(new BestSchedulingSolutionAnalyzer());
    266       ParameterizeOperators();
    267     }
    268 
    269     private void ApplyEncoding() {
    270       if (SolutionCreator.GetType() == typeof(JSMRandomCreator)) {
    271         Operators.AddRange(ApplicationManager.Manager.GetInstances<IJSMOperator>());
    272         ScheduleDecoder = new JSMDecoder();
    273       } else if (SolutionCreator.GetType() == typeof(PRVRandomCreator)) {
    274         Operators.AddRange(ApplicationManager.Manager.GetInstances<IPRVOperator>());
    275         ScheduleDecoder = new PRVDecoder();
    276       } else if (SolutionCreator.GetType() == typeof(PWRRandomCreator)) {
    277         Operators.AddRange(ApplicationManager.Manager.GetInstances<IPWROperator>());
    278         ScheduleDecoder = new PWRDecoder();
    279       } else if (SolutionCreator.GetType() == typeof(DirectScheduleRandomCreator)) {
    280         Operators.AddRange(ApplicationManager.Manager.GetInstances<IDirectScheduleOperator>());
    281         ScheduleDecoder = null;
    282       }
    283     }
    284 
    285     private void ParameterizeOperators() {
    286       Evaluator.ScheduleDecoderParameter.ActualName = ScheduleDecoderParameter.Name;
    287       Evaluator.ScheduleDecoderParameter.Hidden = true;
    288       Evaluator.ScheduleEvaluatorParameter.ActualName = ScheduleEvaluatorParameter.Name;
    289       Evaluator.ScheduleEvaluatorParameter.Hidden = true;
    290       Evaluator.QualityParameter.ActualName = ScheduleEvaluator.QualityParameter.ActualName;
    291       Evaluator.QualityParameter.Hidden = true;
    292 
    293       if (ScheduleDecoder != null)
    294         ScheduleDecoder.ScheduleEncodingParameter.ActualName = SolutionCreator.ScheduleEncodingParameter.ActualName;
    295 
    296       if (ScheduleDecoder != null) {
    297         ScheduleEvaluator.ScheduleParameter.ActualName = ScheduleDecoder.ScheduleParameter.ActualName;
    298         ScheduleEvaluator.ScheduleParameter.Hidden = true;
    299       } else if (SolutionCreator is DirectScheduleRandomCreator) {
    300         var directEvaluator = (DirectScheduleRandomCreator)SolutionCreator;
    301         ScheduleEvaluator.ScheduleParameter.ActualName = directEvaluator.ScheduleEncodingParameter.ActualName;
    302         ScheduleEvaluator.ScheduleParameter.Hidden = true;
    303       } else {
    304         ScheduleEvaluator.ScheduleParameter.ActualName = ScheduleEvaluator.ScheduleParameter.Name;
    305         ScheduleEvaluator.ScheduleParameter.Hidden = false;
    306       }
    307 
    308       foreach (var op in Operators.OfType<IScheduleManipulator>()) {
    309         op.ScheduleEncodingParameter.ActualName = SolutionCreator.ScheduleEncodingParameter.ActualName;
    310         op.ScheduleEncodingParameter.Hidden = true;
    311       }
    312 
    313       foreach (var op in Operators.OfType<IScheduleCrossover>()) {
    314         op.ChildParameter.ActualName = SolutionCreator.ScheduleEncodingParameter.ActualName;
    315         op.ChildParameter.Hidden = true;
    316         op.ParentsParameter.ActualName = SolutionCreator.ScheduleEncodingParameter.ActualName;
    317         op.ParentsParameter.Hidden = true;
    318       }
    319 
    320       foreach (var op in Operators.OfType<BestSchedulingSolutionAnalyzer>()) {
    321         op.QualityParameter.ActualName = ScheduleEvaluator.QualityParameter.ActualName;
    322         if (ScheduleDecoder != null) {
    323           op.ScheduleParameter.ActualName = ScheduleDecoder.ScheduleParameter.ActualName;
    324           op.ScheduleParameter.Hidden = true;
    325         } else if (SolutionCreator is DirectScheduleRandomCreator) {
    326           op.ScheduleParameter.ActualName = ((DirectScheduleRandomCreator)SolutionCreator).ScheduleEncodingParameter.ActualName;
    327           op.ScheduleParameter.Hidden = true;
    328         } else {
    329           op.ScheduleParameter.ActualName = op.ScheduleParameter.Name;
    330           op.ScheduleParameter.Hidden = false;
    331         }
    332       }
    333     }
    334     #endregion
    335 
    336269  }
    337270}
Note: See TracChangeset for help on using the changeset viewer.