Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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());
        }
Example #4
0
        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());
        }
Example #5
0
        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);
        }
Example #6
0
        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;
        }
Example #7
0
        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");
        }
Example #8
0
 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);
 }
Example #9
0
        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));
        }