using System; using System.IO; using System.Linq; using CommandLine; using HeuristicLab.Algorithms.ALPS; using HeuristicLab.Data; using HeuristicLab.Optimization; using HeuristicLab.Persistence.Default.Xml; using HeuristicLab.Problems.GeneralizedQuadraticAssignment; using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms.CPLEX; using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms.Evolutionary; using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms.GRASP; using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms.LAHC; using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms.LocalSearch; using HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms.LocalSolverNet; using HeuristicLab.Problems.Instances.CordeauGQAP; using HeuristicLab.Selection; namespace GQAPSolver { public enum AlgorithmType { ALPS = 0, OSGA = 1, ES = 2, ILS = 3, MLS = 4, GRASP = 5, PLAHCS = 6, CPLEX_FY = 7, CPLEX_KB = 8, LOSOL_01 = 9, LOSOL_N = 10 } class CLOptions { [Value(0, HelpText = "Configuration ID, set by irace.")] public int ConfigId { get; set; } [Value(1, HelpText = "Instance ID, set by irace.")] public int InstanceId { get; set; } [Value(2, HelpText = "Seed, set by irace.")] public long Seed { get; set; } [Value(3, Default = "20-15-35", HelpText = "Name of the problem instance.", Required = true)] public string ProblemInstance { get; set; } [Option('a', "alg", Required = true, HelpText = "Algorithm: ALPS, OSGA, ES, ILS, MLS, GRASP, PLAHCS, CPLEX_FY, CPLEX_KB, LOSOL_01, LOSOL_N")] public AlgorithmType Algorithm { get; set; } [Option('t', "tries", Default = 1, HelpText = "Number of repetitions to perform.")] public int Tries { get; set; } [Option('r', "maxrt", Default = 60, HelpText = "Maximum runtime in seconds.")] public int MaxRuntime { get; set; } [Option('i', "maxiter", Default = 0, HelpText = "Maximum number of iterations.")] public int MaxIterations { get; set; } [Option('e', "maxeval", Default = 0, HelpText = "Maximum number of evaluations.")] public int MaxEvaluations { get; set; } [Option("agegap", Default = 20, HelpText = "Age gap (ALPS)")] public int AgeGap { get; set; } [Option("agescheme", Default = AgingScheme.Polynomial, HelpText = "Aging Scheme: Linear, Polynomial, Fibonacci, Exponentional (ALPS)")] public AgingScheme AgingScheme { get; set; } [Option("elites", Default = 1, HelpText = "Elite solutions (ALPS)")] public int Elites { get; set; } [Option("layers", Default = 10, HelpText = "Number of layers (ALPS)")] public int NumberOfLayers { get; set; } [Option("selpress", Default = 4, HelpText = "Selection pressure (ALPS)")] public double SelectionPressure { get; set; } [Option("popsize", Default = 500, HelpText = "Population size (OSGA, ALPS)")] public int PopulationSize { get; set; } [Option("mutprob", Default = 0.05, HelpText = "Mutation probability (OSGA, ALPS)")] public double MutationProbability { get; set; } [Option("mu", Default = 10, HelpText = "Parent population size (ES)")] public int Mu { get; set; } [Option("lambda", Default = 10, HelpText = "Offspring population size (ES)")] public int Lambda { get; set; } [Option("evosel", Default = ESSelection.Plus, HelpText = "Selection strategy + or , (ES, ALPS)")] public ESSelection Selection { get; set; } [Option("recomb", Default = 0, HelpText = "Use recombination 0 or 1 (ES)")] public int Recombination { get; set; } [Option("pertstr", Default = 0.5, HelpText = "Perturbation strength (ILS)")] public double PerturbationStrength { get; set; } [Option("eliteset", Default = 10, HelpText = "Size of the elite set (GRASP)")] public int EliteSetSize { get; set; } [Option("mineliteset", Default = 2, HelpText = "Minimum size of the elite set (GRASP)")] public int MinimumEliteSetSize { get; set; } [Option("lsiters", Default = 100, HelpText = "Maximum local search iterations (GRASP)")] public int MaximumLocalSearchIterations { get; set; } [Option("candidatesize", Default = 0.5, HelpText = "Candidate Size Factor (GRASP)")] public double CandidateSizeFactor { get; set; } [Option("maxcandsize", Default = 10, HelpText = "Maximum candidate list size (GRASP)")] public int MaximumCandidateListSize { get; set; } [Option("onemoveprob", Default = 0.5, HelpText = "Probability for performing a 1-move (GRASP)")] public double OneMoveProbability { get; set; } [Option("mindiff", Default = 4, HelpText = "Minimum difference (GRASP)")] public int MinimumDifference { get; set; } } class Program { static void Main(string[] args) { var parsed = CommandLine.Parser.Default.ParseArguments(args) .WithParsed(x => Run(x)); } private static void Run(CLOptions opts) { var provider = new CordeauGQAPInstanceProvider(); var descriptors = provider.GetDataDescriptors().ToList(); var avgBest = 0.0; var gqapInstance = provider.LoadData(descriptors.Single(x => x.Name == opts.ProblemInstance)); for (var t = 0; t < opts.Tries; t++) { IAlgorithm alg = null; switch (opts.Algorithm) { case AlgorithmType.ALPS: using (var stream = new MemoryStream(Properties.Resources.ALPS)) { var alps = (AlpsGeneticAlgorithm)XmlParser.Deserialize(stream, CompressionType.Zip); alps.Seed.Value = (int)opts.Seed; alps.SetSeedRandomly.Value = true; #region Termination var execTimeTerm = alps.Terminators.Operators.OfType().SingleOrDefault(); if (execTimeTerm != null) { alps.Terminators.Operators.SetItemCheckedState(execTimeTerm, opts.MaxRuntime > 0); execTimeTerm.Threshold.Value = TimeSpan.FromSeconds(opts.MaxRuntime); } var compTerm = alps.Terminators.Operators.OfType>().SingleOrDefault(x => x.Name == "Generations"); if (compTerm != null) { alps.Terminators.Operators.SetItemCheckedState(compTerm, opts.MaxIterations > 0); compTerm.Threshold.Value = opts.MaxIterations; } compTerm = alps.Terminators.Operators.OfType>().SingleOrDefault(x => x.Name == "Evaluations"); if (compTerm != null) { alps.Terminators.Operators.SetItemCheckedState(compTerm, opts.MaxEvaluations > 0); compTerm.Threshold.Value = opts.MaxEvaluations; } var fitTerm = alps.Terminators.Operators.OfType().SingleOrDefault(); if (fitTerm != null) { alps.Terminators.Operators.SetItemCheckedState(fitTerm, gqapInstance.BestKnownQuality.HasValue); fitTerm.Threshold.Value = gqapInstance.BestKnownQuality.GetValueOrDefault(); } if (alps.Terminators.Operators.CheckedItems.Count() == 0) throw new InvalidOperationException("No termination criteria defined for ALPS"); #endregion alps.AgeGap.Value = opts.AgeGap; alps.AgingScheme.Value = opts.AgingScheme; alps.Elites.Value = opts.Elites; alps.NumberOfLayers.Value = opts.NumberOfLayers; if (!(alps.Selector is GeneralizedRankSelector)) alps.Selector = alps.SelectorParameter.ValidValues.OfType().Single(); var sel = alps.Selector as GeneralizedRankSelector; sel.PressureParameter.Value.Value = opts.SelectionPressure; alps.PopulationSize.Value = opts.PopulationSize; alps.MutationProbability.Value = opts.MutationProbability; alps.PlusSelection = opts.Selection == ESSelection.Plus; alg = alps; } break; case AlgorithmType.OSGA: alg = new OSGA() { MaximumEvaluations = opts.MaxEvaluations, MaximumIterations = opts.MaxIterations, MaximumRuntime = TimeSpan.FromSeconds(opts.MaxRuntime), PopulationSize = opts.PopulationSize, MutationProbability = opts.MutationProbability, StopAtBestKnownQuality = true, Seed = (int)opts.Seed, SetSeedRandomly = false }; break; case AlgorithmType.ES: alg = new EvolutionStrategy() { MaximumEvaluations = opts.MaxEvaluations, MaximumIterations = opts.MaxIterations, MaximumRuntime = TimeSpan.FromSeconds(opts.MaxRuntime), Mu = opts.Mu, Lambda = opts.Lambda, Selection = opts.Selection, UseRecombination = opts.Recombination > 0, StopAtBestKnownQuality = true, Seed = (int)opts.Seed, SetSeedRandomly = false }; break; case AlgorithmType.ILS: alg = new IteratedLS() { MaximumEvaluations = opts.MaxEvaluations, MaximumIterations = opts.MaxIterations, MaximumRuntime = TimeSpan.FromSeconds(opts.MaxRuntime), PerturbationStrength = opts.PerturbationStrength, StopAtBestKnownQuality = true, Seed = (int)opts.Seed, SetSeedRandomly = false }; break; case AlgorithmType.MLS: alg = new MultistartLS() { MaximumEvaluations = opts.MaxEvaluations, MaximumIterations = opts.MaxIterations, MaximumRuntime = TimeSpan.FromSeconds(opts.MaxRuntime), StopAtBestKnownQuality = true, Seed = (int)opts.Seed, SetSeedRandomly = false }; break; case AlgorithmType.GRASP: alg = new GRASP() { MaximumEvaluations = opts.MaxEvaluations, MaximumIterations = opts.MaxIterations, MaximumRuntime = TimeSpan.FromSeconds(opts.MaxRuntime), EliteSetSize = opts.EliteSetSize, MinimumEliteSetSize = opts.MinimumEliteSetSize, MaximumLocalSearchIterations = opts.MaximumLocalSearchIterations, CandidateSizeFactor = opts.CandidateSizeFactor, MaximumCandidateListSize = opts.MaximumCandidateListSize, OneMoveProbability = opts.OneMoveProbability, MinimumDifference = opts.MinimumDifference, StopAtBestKnownQuality = true, Seed = (int)opts.Seed, SetSeedRandomly = false }; break; case AlgorithmType.PLAHCS: alg = new PLAHCS() { MaximumEvaluations = opts.MaxEvaluations, MaximumIterations = opts.MaxIterations, MaximumRuntime = TimeSpan.FromSeconds(opts.MaxRuntime), MaximumExponent = 20, StopAtBestKnownQuality = true, Seed = (int)opts.Seed, SetSeedRandomly = false }; break; case AlgorithmType.CPLEX_FY: alg = new GQAP_FY() { MaximumEvaluations = opts.MaxEvaluations, MaximumIterations = opts.MaxIterations, MaximumRuntime = TimeSpan.FromSeconds(opts.MaxRuntime), StopAtBestKnownQuality = true }; break; case AlgorithmType.CPLEX_KB: alg = new GQAP_KB() { MaximumEvaluations = opts.MaxEvaluations, MaximumIterations = opts.MaxIterations, MaximumRuntime = TimeSpan.FromSeconds(opts.MaxRuntime), StopAtBestKnownQuality = true }; break; case AlgorithmType.LOSOL_01: alg = new GQAPBinarySolver() { MaximumEvaluations = opts.MaxEvaluations, MaximumIterations = opts.MaxIterations, MaximumRuntime = TimeSpan.FromSeconds(opts.MaxRuntime), StopAtBestKnownQuality = true }; break; case AlgorithmType.LOSOL_N: alg = new GQAPIntegerSolver() { MaximumEvaluations = opts.MaxEvaluations, MaximumIterations = opts.MaxIterations, MaximumRuntime = TimeSpan.FromSeconds(opts.MaxRuntime), StopAtBestKnownQuality = true }; break; } if (alg == null) throw new InvalidOperationException("Unknown algorithm " + opts.Algorithm + "."); var prob = alg.Problem as GQAP; if (prob == null) alg.Problem = prob = new GQAP(); prob.Load(gqapInstance); alg.Start(); avgBest += ((DoubleValue)alg.Results["BestQuality"].Value).Value; } Console.WriteLine(avgBest / opts.Tries); } } }