//initialize memoization with 2-Component (i.e., arc) subassemblies so heuristic works protected static void InitializeMemo() { foreach (Connection arc in Graph.arcs.Where(a => a is Connection)) { var Asm = new HashSet <Component>(new Component[] { (Component)arc.From, (Component)arc.To }); var Fr = new List <Component>(new Component[] { (Component)arc.From }); var dirs = new HashSet <int>(arc.InfiniteDirections); SubAssembly sa; if (AssemblyEvaluator.EvaluateSub(Graph, Asm, Fr, dirs, out sa) > 0) { HashSet <Component> A = new HashSet <Component>(Asm); MemoData D = new MemoData(sa.Install.Time, sa); Memo.Add(A, D); } } foreach (var node in Graph.nodes) { var component = (Component)node; var N = new HashSet <Component>(new[] { component }); var sa = new SubAssembly(N, EvaluationForBinaryTree.ConvexHullsForParts[component.name], component.Mass, component.Volume, new Vertex(component.CenterOfMass)); MemoData D = new MemoData(0, sa); Memo.Add(N, D); } }
protected static double F(out SubAssembly tree, HashSet <Component> A) { Count[A.Count]++; TimeEstmCounter++; TimeEstm++; if (Memo.ContainsKey(A) /*|| * Memo.Keys.Any(k => k.Count == A.Count && k.All(kk => A.Any(a => a.name == kk.name)))*/) { tree = Memo[A].sa; return(Memo[A].Value); } var candidates = GetCandidates(A); candidates.Sort(); var best = double.PositiveInfinity; SubAssembly bestsa = null, bestReference = null, bestMoving = null; foreach (var tc in candidates) { if (tc.H >= best) { break; } SubAssembly reference, moving; var refTime = F(out reference, tc.RefNodes); var movTime = F(out moving, tc.MovNodes); var maxT = Math.Max(refTime, movTime); var evaluation = tc.sa.Install.Time + maxT; if (evaluation < best) { best = evaluation; bestsa = tc.sa; bestReference = reference; bestMoving = moving; } if (Estimate) { break; } } tree = bestsa; tree.Install.Reference = bestReference; tree.Install.Moving = bestMoving; if (!Estimate) { var d = new MemoData(best, bestsa); Memo.Add(A, d); } return(best); }
protected static void InitializeMemoBoosted() { var newMemo = new List <HashSet <HashSet <Component> > >(); for (var i = 1; i <= Graph.nodes.Count; i++) { var combinations = CombinationFinder(i); var column = new HashSet <HashSet <Component> >(); if (!combinations.Any()) { foreach (var node in Graph.nodes) { var component = (Component)node; var N = new HashSet <Component>(new[] { component }); var sa = new SubAssembly(N, EvaluationForBinaryTree.ConvexHullsForParts[component.name], component.Mass, component.Volume, new Vertex(component.CenterOfMass)); var D = new MemoData(0, sa); column.Add(N); Memo.Add(N, D); } newMemo.Add(column); } else { Parallel.ForEach(combinations, comb => { foreach (var subAssem1 in newMemo[comb[0] - 1]) { foreach (var subAssem2 in newMemo[comb[1] - 1]) { if (subAssem1.Any(subAssem2.Contains)) { continue; } var connections = new HashSet <Connection>( subAssem1.SelectMany( n => n.arcs.Where(c => c is Connection).Cast <Connection>().Where(c => (subAssem1.Contains(c.From) && subAssem2.Contains(c.To)) || (subAssem1.Contains(c.To) && subAssem2.Contains(c.From))))); var secConnections = new HashSet <SecondaryConnection>( subAssem1.SelectMany( n => n.arcs.Where(a => a is SecondaryConnection) .Cast <SecondaryConnection>() .Where(c => (subAssem1.Contains(c.From) && subAssem2.Contains(c.To)) || (subAssem1.Contains(c.To) && subAssem2.Contains(c.From))))); if (!connections.Any()) { continue; } var dirs = ValidDirectionsFinder(subAssem1, subAssem2, connections); ApplySecondaryConnections(dirs, subAssem1, subAssem2, secConnections); if (!dirs.Any()) { continue; } var asm = new HashSet <Component>(subAssem1); asm.UnionWith(subAssem2); SubAssembly sa; if (AssemblyEvaluator.EvaluateSub(Graph, asm, subAssem1.ToList(), dirs, out sa) > 0) { if (!Memo.ContainsKey(asm)) { var D = new MemoData(sa.Install.Time, sa); lock (Memo) Memo.Add(asm, D); lock (column) column.Add(asm); continue; } if (sa.Install.Time < Memo[asm].Value) { lock (Memo) Memo[asm] = new MemoData(sa.Install.Time, sa); } } } } }); newMemo.Add(column); if (newMemo.Count == 3) { break; } } } }