1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)


4  *


5  * This file is part of HeuristicLab.


6  *


7  * HeuristicLab is free software: you can redistribute it and/or modify


8  * it under the terms of the GNU General Public License as published by


9  * the Free Software Foundation, either version 3 of the License, or


10  * (at your option) any later version.


11  *


12  * HeuristicLab is distributed in the hope that it will be useful,


13  * but WITHOUT ANY WARRANTY; without even the implied warranty of


14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the


15  * GNU General Public License for more details.


16  *


17  * You should have received a copy of the GNU General Public License


18  * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.


19  */


20  #endregion


21 


22  using System;


23  using System.Threading;


24  using HeuristicLab.Analysis;


25  using HeuristicLab.Common;


26  using HeuristicLab.Core;


27  using HeuristicLab.Data;


28  using HeuristicLab.Encodings.IntegerVectorEncoding;


29  using HeuristicLab.Optimization;


30  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;


31  using ILOG.CPLEX;


32  using ILOG.OPL;


33 


34  namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms.CPLEX {


35  [Item("CPLEX Solver (GQAP)", "Base class")]


36  [StorableClass]


37  public abstract class CplexSolver : ContextAlgorithm<CplexContext, IntegerVectorEncoding> {


38  public override bool SupportsPause {


39  get { return false; }


40  }


41 


42  public override Type ProblemType {


43  get { return typeof(GQAP); }


44  }


45 


46  public new GQAP Problem {


47  get { return (GQAP)base.Problem; }


48  set { base.Problem = value; }


49  }


50 


51  [StorableConstructor]


52  protected CplexSolver(bool deserializing) : base(deserializing) { }


53  protected CplexSolver(CplexSolver original, Cloner cloner)


54  : base(original, cloner) {


55  }


56  public CplexSolver() {


57  Problem = new GQAP();


58  ((MultiAnalyzer)Analyzer).AddOperator(new QualityPerClockAnalyzer());


59  }


60 


61  protected override void Run(CancellationToken cancellationToken) {


62  var factory = new OplFactory();


63  var cplex = factory.CreateCplex();


64  cplex.Use(new LogCallback(this, cancellationToken));


65  cplex.SetParam(Cplex.DoubleParam.TiLim, MaximumRuntime.TotalSeconds);


66  var dataSource = new GQAPDataSource(factory, Problem.ProblemInstance);


67  using (var settings = factory.CreateOplSettings(factory.CreateOplErrorHandler()))


68  using (var opl = GetModel(factory, settings, cplex)) {


69  opl.AddDataSource(dataSource);


70  opl.Generate();


71  cplex.Solve();


72  cplex.End();


73  }


74  Context.RunOperator(Analyzer, CancellationToken.None);


75  }


76 


77  protected abstract OplModel GetModel(OplFactory factory, OplSettings settings, Cplex cplex);


78  }


79 


80  public class LogCallback : Cplex.MIPInfoCallback {


81  private CplexSolver algorithm;


82  private CancellationToken token;


83  private double prev;


84 


85 


86  public LogCallback(CplexSolver algorithm, CancellationToken token) {


87  this.algorithm = algorithm;


88  this.token = token;


89  prev = double.NaN;


90  }


91 


92  protected override void Main() {


93  if (HasIncumbent()) {


94  var val = GetIncumbentObjValue();


95  if (val >= prev) return;


96  algorithm.Context.Iterations++;


97  algorithm.Context.BestQuality = val;


98  IResult result;


99  if (algorithm.Results.TryGetValue("Iterations", out result))


100  ((IntValue)result.Value).Value = algorithm.Context.Iterations;


101  else algorithm.Results.Add(new Result("Iterations", new IntValue(algorithm.Context.Iterations)));


102  if (algorithm.Results.TryGetValue("BestQuality", out result))


103  ((DoubleValue)result.Value).Value = algorithm.Context.BestQuality;


104  else algorithm.Results.Add(new Result("BestQuality", new DoubleValue(algorithm.Context.BestQuality)));


105  algorithm.Context.RunOperator(algorithm.Analyzer, CancellationToken.None);


106  prev = val;


107  if (val.IsAlmost(algorithm.Problem.BestKnownQuality))


108  Abort();


109  }


110  if (token.IsCancellationRequested) Abort();


111  }


112  }


113  }

