public static List <List <int> > FindAllDiamonds(AlgorithmBlob blob, List <Vector> p) { var diamonds = new List <List <int> >(); var d = Choosability.Graphs.Diamond; var seq = new[] { 2, 2, 3, 3 }; foreach (var X in blob.AlgorithmGraph.Vertices.EnumerateSublists(4)) { if (!X.Select(v => blob.AlgorithmGraph.DegreeInSubgraph(v, X)).OrderBy(q => q).SequenceEqual(seq)) { continue; } if (blob.AlgorithmGraph.InducedSubgraph(X).ContainsInduced(d)) { var Y = X.OrderBy(x => blob.AlgorithmGraph.DegreeInSubgraph(x, X)).ToList(); diamonds.Add(Y); var Y2 = Y.ToList(); var temp = Y2[0]; Y2[0] = Y[1]; Y2[1] = temp; diamonds.Add(Y2); } } return(diamonds); }
public static List <List <int> > FindDiamonds(AlgorithmBlob blob, List <Vector> p) { var diamonds = new List <List <int> >(); var d = Choosability.Graphs.Diamond; foreach (var X in blob.AlgorithmGraph.Vertices.EnumerateSublists(4)) { if (blob.AlgorithmGraph.InducedSubgraph(X).ContainsInduced(d)) { var Y = X.OrderBy(x => p[x].X).OrderBy(x => blob.AlgorithmGraph.DegreeInSubgraph(x, X)).ToList(); var type = ClassifyDiamond(p, Y); if (type != DiamondType.U && type != DiamondType.DR && type != DiamondType.DL) { var temp = Y[0]; Y[0] = Y[1]; Y[1] = temp; } diamonds.Add(Y); } } return(diamonds); }
public static string GenerateGLPKCode(AlgorithmBlob blob, List <Vector> p, List <List <int> > diamonds, List <string> w) { var spindle = 3 * diamonds.Count; var variables = w.Distinct().OrderBy(x => x).ToList(); var DU = diamonds.Where(d => ClassifyDiamond(p, d) == DiamondType.U).ToList(); var HU = BuildSingleDirectionBitGraph(p, DU); var DDL = diamonds.Where(d => ClassifyDiamond(p, d) == DiamondType.DL).ToList(); var HDL = BuildSingleDirectionBitGraph(p, DDL); var DDR = diamonds.Where(d => ClassifyDiamond(p, d) == DiamondType.DR).ToList(); var HDR = BuildSingleDirectionBitGraph(p, DDR); var sb = new StringBuilder(); sb.AppendLine("maximize"); sb.AppendLine(string.Join(" + ", blob.AlgorithmGraph.Vertices.GroupBy(v => w[v]).OrderBy(x => x.Key).Select(x => (x.Count() > 1 ? x.Count().ToString() : "") + x.Key)) + " + " + spindle + "s"); sb.AppendLine(); sb.AppendLine("subject to"); var constraints = new HashSet <string>(); Task.WaitAll(blob.AlgorithmGraph.EnumerateMaximalIndependentSets().Select(Y => Task.Factory.StartNew((X) => { var constraint = GeneratePrettyConstraint((List <int>)X, w, diamonds.Count, HU, HDL, HDR, DU, DDL, DDR); lock (constraints) constraints.Add(constraint); }, Y)).ToArray()); sb.AppendLine(string.Join(Environment.NewLine, constraints)); sb.AppendLine(); sb.AppendLine("bounds"); foreach (var v in variables) { sb.AppendLine(v + " > 0"); } sb.AppendLine("s > 0"); sb.AppendLine(); sb.AppendLine("generals"); foreach (var v in variables) { sb.AppendLine(v); } sb.AppendLine("s"); sb.AppendLine(); sb.AppendLine("end"); return(sb.ToString()); }
public static List <string> FindSerendipitousEdges(AlgorithmBlob blob, List <Vector> p, List <List <int> > diamonds, out List <string> identifications) { var r = p[diamonds[0][0]].Distance(p[diamonds[0][2]]); var c = new int[8]; var rotatedDiamonds = new Dictionary <string, List <Vector> >(); foreach (var diamond in diamonds) { var t = ClassifyDiamond(p, diamond); var i = c[(int)t]++; rotatedDiamonds[Enum.GetName(typeof(DiamondType), t) + "_" + i] = RotateCoordinates(p, diamond); } var edges = new List <string>(); identifications = new List <string>(); foreach (var a in rotatedDiamonds) { foreach (var b in rotatedDiamonds) { if (a.Key.Substring(0, a.Key.IndexOf("_")) == b.Key.Substring(0, b.Key.IndexOf("_"))) { continue; } for (int i = 1; i < 4; i++) { for (int j = 1; j < 4; j++) { if (Math.Abs(a.Value[i].Distance(b.Value[j]) - r) < MinDelta) { var s = a.Key + "_" + GetKind(i) + " <--> " + b.Key + "_" + GetKind(j); edges.Add(s); } else if (a.Value[i].Distance(b.Value[j]) < MinDelta) { var s = a.Key + "_" + GetKind(i) + " == " + b.Key + "_" + GetKind(j); identifications.Add(s); } } } } } return(edges.Distinct((x, y) => x.Split(new[] { " <--> " }, StringSplitOptions.RemoveEmptyEntries).SequenceEqual(y.Split(new[] { " <--> " }, StringSplitOptions.RemoveEmptyEntries).Reverse())).ToList()); }
public static double ComputeBestWeight(AlgorithmBlob blob, List <Vector> p, List <List <int> > diamonds, List <double> w, out List <int> heaviestIndependentSet) { heaviestIndependentSet = new List <int>(); var maxWeight = 0.0; var DU = diamonds.Where(d => ClassifyDiamond(p, d) == DiamondType.U).ToList(); var HU = BuildSingleDirectionBitGraph(p, DU); var DDL = diamonds.Where(d => ClassifyDiamond(p, d) == DiamondType.DL).ToList(); var HDL = BuildSingleDirectionBitGraph(p, DDL); var DDR = diamonds.Where(d => ClassifyDiamond(p, d) == DiamondType.DR).ToList(); var HDR = BuildSingleDirectionBitGraph(p, DDR); foreach (var X in blob.AlgorithmGraph.EnumerateMaximalIndependentSets()) { var weight = X.Sum(v => w[v]) + diamonds.Count; if (weight <= maxWeight) { continue; } weight -= ComputeLostSpindles(X, HU, DU); if (weight <= maxWeight) { continue; } weight -= ComputeLostSpindles(X, HDL, DDL); if (weight <= maxWeight) { continue; } weight -= ComputeLostSpindles(X, HDR, DDR); if (weight > maxWeight) { maxWeight = weight; heaviestIndependentSet = X; } } return(maxWeight); }
public static void AddSpindle(AlgorithmBlob blob, bool clock) { var style = clock ? "clock_" : "cclock_"; var indices = blob.UIGraph.SelectedVertices.Select(v => blob.UIGraph.Vertices.IndexOf(v)).ToList(); var bottom = blob.UIGraph.Vertices.IndexOf(blob.UIGraph.SelectedVertices.First(vv => vv.Label != "")); var bottom_v = blob.UIGraph.Vertices[bottom]; var ll = bottom_v.Label; var g = blob.AlgorithmGraph; var mids = g.NeighborsInSubgraph(bottom, indices).ToList(); var top = indices.Except(new[] { bottom }.Union(mids)).First(); var top_v = blob.UIGraph.Vertices[top]; var p = blob.UIGraph.Vertices.Select(v => new Vector(v.X, v.Y)).ToList(); var top_r = Rotate(p[bottom], p[top], clock); var mid0_r = Rotate(p[bottom], p[mids[0]], clock); var mid1_r = Rotate(p[bottom], p[mids[1]], clock); var top_rv = new Vertex(top_r); var mid0_rv = new Vertex(mid0_r); var mid1_rv = new Vertex(mid1_r); blob.UIGraph.AddVertex(top_rv); blob.UIGraph.AddVertex(mid0_rv); blob.UIGraph.AddVertex(mid1_rv); blob.UIGraph.AddEdge(bottom_v, mid0_rv, Edge.Orientations.None, 1, 3, style + "edge" + "_" + ll); blob.UIGraph.AddEdge(bottom_v, mid1_rv, Edge.Orientations.None, 1, 3, style + "edge" + "_" + ll); blob.UIGraph.AddEdge(top_rv, mid0_rv, Edge.Orientations.None, 1, 3, style + "edge" + "_" + ll); blob.UIGraph.AddEdge(top_rv, mid1_rv, Edge.Orientations.None, 1, 3, style + "edge" + "_" + ll); blob.UIGraph.AddEdge(mid0_rv, mid1_rv, Edge.Orientations.None, 1, 3, style + "edge" + "_" + ll); blob.UIGraph.AddEdge(top_rv, top_v, Edge.Orientations.None, 1, 3, style + "edgetween" + "_" + ll); top_rv.Style = style + "vertex" + "_" + ll; mid0_rv.Style = style + "vertex" + "_" + ll; mid1_rv.Style = style + "vertex" + "_" + ll; }
public static string ComputeTotalWeightFormula(AlgorithmBlob blob, List <Vector> p, List <List <int> > diamonds, List <string> w) { var spindle = 3 * diamonds.Count; return(string.Join(" + ", blob.AlgorithmGraph.Vertices.GroupBy(v => w[v]).OrderBy(x => x.Key).Select(x => (x.Count() > 1 ? x.Count().ToString() : "") + x.Key)) + " + " + spindle + "s"); }
public static double ComputeTotalWeight(AlgorithmBlob blob, List <Vector> p, List <List <int> > diamonds, List <double> w) { return(blob.AlgorithmGraph.Vertices.Sum(v => w[v]) + 3 * diamonds.Count); }
public static Graphs.Graph BuildSerendipitousEdgeGraph(AlgorithmBlob blob, List <Vector> p, List <List <int> > diamonds, out Graphs.Graph rotatedGraph) { var dim = GraphicsLayer.ARGB.FromFractional(0.5, 0.5, 0.5, 0.5); var transparent = GraphicsLayer.ARGB.FromFractional(0.0, 0.5, 0.5, 0.5); var vertices = new List <Vertex>(); for (int i = 0; i < diamonds.Count; i++) { var v = new Vertex(diamonds[i].Select(t => p[t].X).Average(), diamonds[i].Select(t => p[t].Y).Average()); v.Label = Enum.GetName(typeof(DiamondType), ClassifyDiamond(p, diamonds[i])); vertices.Add(v); } var rotatedDiamonds = diamonds.Select(d => RotateCoordinates(p, d)).ToList(); var edges = new List <Edge>(); var r = p[diamonds[0][0]].Distance(p[diamonds[0][2]]); var rotatedVertices = new List <Vertex>(); var rotatedEdges = new List <Edge>(); var rotatedVertexLookup = new Vertex[diamonds.Count, 4]; for (int a = 0; a < diamonds.Count; a++) { for (int i = 0; i < 4; i++) { var v = new Vertex(rotatedDiamonds[a][i].X, rotatedDiamonds[a][i].Y); if (i == 0) { v.Padding = 0.02f; } rotatedVertices.Add(v); rotatedVertexLookup[a, i] = v; } var originals = new Vertex[4]; for (int i = 1; i < 4; i++) { var v = new Vertex(p[diamonds[a][i]].X, p[diamonds[a][i]].Y); v.Color = transparent; v.Padding = 0.02f; rotatedVertices.Add(v); originals[i] = v; } rotatedEdges.Add(new Edge(originals[2], originals[3]) { Color = dim }); rotatedEdges.Add(new Edge(originals[1], originals[2]) { Color = dim }); rotatedEdges.Add(new Edge(originals[1], originals[3]) { Color = dim }); rotatedEdges.Add(new Edge(rotatedVertexLookup[a, 0], originals[2]) { Color = dim }); rotatedEdges.Add(new Edge(rotatedVertexLookup[a, 0], originals[3]) { Color = dim }); rotatedEdges.Add(new Edge(rotatedVertexLookup[a, 0], rotatedVertexLookup[a, 2])); rotatedEdges.Add(new Edge(rotatedVertexLookup[a, 0], rotatedVertexLookup[a, 3])); rotatedEdges.Add(new Edge(rotatedVertexLookup[a, 1], rotatedVertexLookup[a, 2])); rotatedEdges.Add(new Edge(rotatedVertexLookup[a, 1], rotatedVertexLookup[a, 3])); rotatedEdges.Add(new Edge(rotatedVertexLookup[a, 2], rotatedVertexLookup[a, 3])); rotatedEdges.Add(new Edge(originals[1], rotatedVertexLookup[a, 1])); } for (int a = 0; a < diamonds.Count; a++) { for (int b = a + 1; b < diamonds.Count; b++) { if (ClassifyDiamond(p, diamonds[a]) == ClassifyDiamond(p, diamonds[b])) { continue; } for (int i = 1; i < 4; i++) { for (int j = 1; j < 4; j++) { var distance = rotatedDiamonds[a][i].Distance(rotatedDiamonds[b][j]); var offset = Math.Abs(distance - r); if (offset < MinDelta) { var e = new Edge(vertices[a], vertices[b]); e.Thickness = 6; edges.Add(e); var ee = new Edge(rotatedVertexLookup[a, i], rotatedVertexLookup[b, j]); ee.Thickness = 6; rotatedEdges.Add(ee); } } } } } rotatedGraph = new Graphs.Graph(rotatedVertices, rotatedEdges); return(new Graphs.Graph(vertices, edges)); }