using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace HeuristicLab.Problems.Instances.QAPLIB { public class OneSizeInstanceProvider : ProblemInstanceProvider { public override IEnumerable GetDataDescriptors() { var drezner = new DreznerQAPInstanceProvider(); foreach (var desc in drezner.GetDataDescriptors()) yield return new OneSizeDataDescriptor(desc.Name + "-25", desc.Description, drezner, desc); var microarray = new MicroarrayQAPInstanceProvider(); foreach (var desc in microarray.GetDataDescriptors()) yield return new OneSizeDataDescriptor(desc.Name + "-25", desc.Description, microarray, desc); var qaplib = new QAPLIBInstanceProvider(); foreach (var desc in qaplib.GetDataDescriptors()) yield return new OneSizeDataDescriptor(desc.Name + "-25", desc.Description, qaplib, desc); var taillard = new TaillardQAPInstanceProvider(); foreach (var desc in taillard.GetDataDescriptors()) yield return new OneSizeDataDescriptor(desc.Name + "-25", desc.Description, taillard, desc); } public override QAPData LoadData(IDataDescriptor descriptor) { var desc = (OneSizeDataDescriptor)descriptor; var data = desc.ActualProvider.LoadData(desc.ActualDescriptor); data.BestKnownAssignment = null; data.BestKnownQuality = null; if (data.Dimension <= 25) { return data; } var rand = new Random(data.Dimension); var tmp = Enumerable.Range(0, data.Dimension).ToArray(); Shuffle(tmp, rand); var throwAway = new bool[data.Dimension]; foreach (var t in tmp.Take(data.Dimension - 25)) throwAway[t] = true; var weights = new double[25, 25]; var distances = new double[25, 25]; var k = 0; for (var i = 0; i < data.Dimension; i++) { if (throwAway[i]) continue; var h = 0; for (var j = 0; j < data.Dimension; j++) { if (throwAway[j]) continue; weights[k, h] = data.Weights[i, j]; distances[k, h] = data.Distances[i, j]; h++; } k++; } data.Weights = weights; data.Distances = distances; data.BestKnownAssignment = null; data.BestKnownQuality = null; data.Dimension = 25; data.Name += "-25"; data.Description += " (reduced or enlarged to 25 dimensions)"; return data; } public override string Name { get { return "One Size"; } } public override string Description { get { return string.Empty; } } public override Uri WebLink { get { return null; } } public override string ReferencePublication { get { return string.Empty; } } // permutation must be strictly different in every position private static void Shuffle(int[] p, Random random) { for (var i = p.Length - 1; i > 0; i--) { // Swap element "i" with a random earlier element (excluding itself) var swapIndex = random.Next(i + 1); var h = p[swapIndex]; p[swapIndex] = p[i]; p[i] = h; } } } }