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.Common;


25  using HeuristicLab.Core;


26  using HeuristicLab.Data;


27  using HeuristicLab.Encodings.IntegerVectorEncoding;


28  using HeuristicLab.Optimization;


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


30  using ILOG.CPLEX;


31  using ILOG.OPL;


32 


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


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


35  [StorableClass]


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


37  public override bool SupportsPause {


38  get { return false; }


39  }


40 


41  public override Type ProblemType {


42  get { return typeof(GQAP); }


43  }


44 


45  public new GQAP Problem {


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


47  set { base.Problem = value; }


48  }


49 


50  [StorableConstructor]


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


52  protected CplexSolver(CplexSolver original, Cloner cloner)


53  : base(original, cloner) {


54  }


55  public CplexSolver() {


56  Problem = new GQAP();


57  }


58 


59  protected override void Run(CancellationToken cancellationToken) {


60  base.Run(cancellationToken);


61  var factory = new OplFactory();


62  var cplex = factory.CreateCplex();


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


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


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


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


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


68  opl.AddDataSource(dataSource);


69  opl.Generate();


70  cplex.Solve();


71  cplex.End();


72  }


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


74  }


75 


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


77  }


78 


79  public class LogCallback : Cplex.MIPInfoCallback {


80  private CplexSolver algorithm;


81  private CancellationToken token;


82  private double prev;


83 


84 


85  public LogCallback(CplexSolver algorithm, CancellationToken token) {


86  this.algorithm = algorithm;


87  this.token = token;


88  prev = double.NaN;


89  }


90 


91  protected override void Main() {


92  if (HasIncumbent()) {


93  var val = GetIncumbentObjValue();


94  if (val >= prev) return;


95  algorithm.Context.Iterations++;


96  algorithm.Context.BestQuality = val;


97  IResult result;


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


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


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


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


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


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


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


105  prev = val;


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


107  Abort();


108  }


109  if (token.IsCancellationRequested) Abort();


110  }


111  }


112  }

