Esempio n. 1
0
        /// <summary>
        /// Creates a random graph that takes two parameters: the number of nodes,
        /// and the average degree. Note: that there is no guarantee that the graph
        /// will be connected.
        /// </summary>
        /// <param name = "numNodes">The number of nodes.</param>
        /// <param name = "aveDegree">The average degree.</param>
        /// <returns></returns>
        public static designGraph CreateRandomGraph(int numNodes, int aveDegree)
        {
            var randomGraph = new designGraph
            {
                name = "RandomGraph_with_" + numNodes + "_nodes_and_degree_of_" + aveDegree
            };
            var arcProb = (double)aveDegree / (numNodes + 1);
            var rnd     = new Random();

            for (var i = 0; i != numNodes; i++)
            {
                randomGraph.addNode();
            }

            for (var i = 0; i != numNodes; i++)
            {
                for (var j = i + 1; j != numNodes; j++)
                {
                    if ((double)rnd.Next(1000) / 1000 <= arcProb)
                    {
                        randomGraph.addArc(randomGraph.nodes[i], randomGraph.nodes[j]);
                    }
                }
            }
            return(randomGraph);
        }
Esempio n. 2
0
        /// <summary>
        ///   Creates a complete graph where every node is connected to every
        ///   other node by an arc.
        /// </summary>
        /// <param name="numNodes">The number of nodes.</param>
        /// <returns></returns>
        public static designGraph CreateCompleteGraph(int numNodes)
        {
            var numArcs       = numNodes * (numNodes - 1) / 2;
            var completeGraph = new designGraph
            {
                name = "CompleteGraph_with_" + numNodes + "_nodes_and_" + numArcs + "_arcs"
            };

            for (var i = 0; i != numNodes; i++)
            {
                completeGraph.addNode();
            }
            for (var i = 0; i != numNodes; i++)
            {
                for (var j = i + 1; j != numNodes; j++)
                {
                    completeGraph.addArc(completeGraph.nodes[i], completeGraph.nodes[j]);
                }
            }
            return(completeGraph);
        }
Esempio n. 3
0
        /// <summary>
        ///   Copies the specified make deep copy.
        /// </summary>
        /// <param name = "MakeDeepCopy">if set to <c>true</c> [make deep copy].</param>
        /// <returns></returns>
        public designGraph copy(Boolean MakeDeepCopy = true)
        {
            /* at times we want to copy a graph and not refer to the same objects. This happens mainly
             * (rather initially what inspired this function) when the seed graph is copied into a candidate.*/
            var copyOfGraph = new designGraph {
                name = name
            };

            foreach (var label in globalLabels)
            {
                copyOfGraph.globalLabels.Add(label);
            }
            foreach (var v in globalVariables)
            {
                copyOfGraph.globalVariables.Add(v);
            }
            foreach (var origNode in nodes)
            {
                copyOfGraph.addNode(MakeDeepCopy ? origNode.copy() : origNode);
            }
            foreach (var origArc in arcs)
            {
                if (MakeDeepCopy)
                {
                    var  copyOfArc = origArc.copy();
                    var  toIndex   = nodes.FindIndex(a => (a == origArc.To));
                    var  fromIndex = nodes.FindIndex(b => (b == origArc.From));
                    node fromNode  = null;
                    if (fromIndex > -1)
                    {
                        fromNode = copyOfGraph.nodes[fromIndex];
                    }
                    node toNode = null;
                    if (toIndex > -1)
                    {
                        toNode = copyOfGraph.nodes[toIndex];
                    }
                    copyOfGraph.addArc(copyOfArc, fromNode, toNode);
                }
                else
                {
                    copyOfGraph.arcs.Add(origArc);
                }
            }
            foreach (var origHyperArc in hyperarcs)
            {
                if (MakeDeepCopy)
                {
                    var copyOfHyperArc = origHyperArc.copy();
                    var attachedNodes  = new List <node>();
                    foreach (var n in origHyperArc.nodes)
                    {
                        var index = nodes.FindIndex(a => (a == n));
                        attachedNodes.Add(copyOfGraph.nodes[index]);
                    }
                    copyOfGraph.addHyperArc(copyOfHyperArc, attachedNodes);
                }
                else
                {
                    copyOfGraph.hyperarcs.Add(origHyperArc);
                }
            }
            return(copyOfGraph);
        }
Esempio n. 4
0
        private void addRdiffKtoD(designGraph Lmapping, designGraph D, designGraph Rmapping)
        {
            /* in this adding and gluing function, we are careful to distinguish
             * the Lmapping or recognized subgraph of L in the host - heretofore
             * known as Lmapping - from the mapping of new nodes and arcs of the
             * graph, which we call Rmapping. This is a complex function that goes
             * through 4 key steps:
             * 1. add the new nodes that are in R but not in L.
             * 2. update the remaining nodes common to L&R (aka K nodes) that might
             *    have had some label changes.
             * 3. add the new arcs that are in R but not in L. These may connect to
             *    either the newly connected nodes from step 1 or from the updated nodes
             *    of step 2.
             * 4. update the arcs common to L&R (aka K arcs) which might now be connected
             *    to new nodes created in step 1 (they are already connected to 
             *    nodes in K). Also make sure to update their labels just as K nodes were
             *    updated in step 2.

            /* here are some placeholders used in this bookeeping. Many are used multiple times
             * so we might as well declare them just once at the start. */
            int index1, index2;
            node from, to, KNode;
            arc KArc;

            for (int i = 0; i != R.nodes.Count; i++)
            {
                ruleNode rNode = (ruleNode)R.nodes[i];
                #region Step 1. add new nodes to D
                if (!L.nodes.Exists(delegate(node b)
                    { return (b.name == rNode.name); }))
                {
                    D.addNode(rNode.nodeType);         /* create a new node. */
                    Rmapping.nodes[i] = D.nodes[D.lastNode];          /* make sure it's referenced in Rmapping. */
                    /* labels cannot be set equal, since that merely sets the reference of this list
                     * to the same value. So, we need to make a complete copy. */
                    rNode.copy(D.nodes[D.lastNode]);
                    /* give that new node a name and labels to match with the R. */
                }
                #endregion
                #region Step 2. update K nodes
                else
                {
                    /* else, we may need to modify or update the node. In the pure graph
                     * grammar sense this is merely changing the local labels. In a way, 
                     * this is a like a set grammar. We need to find the labels in L that 
                     * are no longer in R and delete them, and we need to add the new labels
                     * that are in R but not already in L. The ones common to both are left
                     * alone. */
                    index1 = L.nodes.FindIndex(delegate(node b)
                        { return (rNode.name == b.name); });          /* find index of the common node in L...*/
                    KNode = Lmapping.nodes[index1];          /*...and then set Knode to the actual node in D.*/
                    Rmapping.nodes[i] = KNode;               /*also, make sure that the Rmapping is to this same node.*/
                    foreach (string a in L.nodes[index1].localLabels)
                        if (!rNode.localLabels.Contains(a))
                            KNode.localLabels.Remove(a);          /* removing the labels in L but not in R...*/
                    foreach (string a in rNode.localLabels)
                        if (!L.nodes[index1].localLabels.Contains(a))
                            KNode.localLabels.Add(a.ToString());          /*...and adding the label in R but not in L.*/
                    foreach (double a in L.nodes[index1].localVariables)         /* do the same now, for the variables. */
                        if (!rNode.localVariables.Contains(a))
                            KNode.localVariables.Remove(a);          /* removing the labels in L but not in R...*/
                    foreach (double a in rNode.localVariables)
                        if (!L.nodes[index1].localVariables.Contains(a))
                            KNode.localVariables.Add(a);          /*...and adding the label in R but not in L.*/
                    KNode.shapekey = rNode.shapekey;
                }
            }
                #endregion

            /* now moving onto the arcs (a little more challenging actually). */
            for (int i = 0; i != R.arcs.Count; i++)
            {
                ruleArc rArc = (ruleArc)R.arcs[i];
                #region Step 3. add new arcs to D
                if (!L.arcs.Exists(delegate(arc b)
                    { return (b.name == rArc.name); }))
                {
                    #region setting up where arc comes from
                    if (rArc.From == null)
                        from = null;
                    else if (L.nodes.Exists(delegate(node b)
                         { return (b.name == rArc.From.name); }))
                    /* if the arc is coming from a node that is in K, then it must've been
                     * part of the location (or Lmapping) that was originally recognized.*/
                    {
                        index1 = L.nodes.FindIndex(delegate(node b)
                        {
                            return (rArc.From.name == b.name);
                        });  /* therefore we need to find the position/index of that node in L. */

                        from = Lmapping.nodes[index1];
                        /* and that index1 will correspond to its image in Lmapping. Following,
                         * the Lmapping reference, we get to the proper node reference in D. */
                    }
                    else
                    /* if not in K then the arc connects to one of the new nodes that were 
                     * created at the beginning of this function (see step 1) and is now
                     * one of the references in Rmapping. */
                    {
                        index1 = R.nodes.FindIndex(delegate(node b)
                        {
                            return (rArc.From.name == b.name);
                        });
                        from = Rmapping.nodes[index1];
                    }
                    #endregion
                    #region setting up where arc goes to
                    /* this code is the same of "setting up where arc comes from - except here
                     * we do the same for the to connection of the arc. */
                    if (rArc.To == null)
                        to = null;
                    else if (L.nodes.Exists(delegate(node b) { return (b.name == rArc.To.name); }))
                    {
                        index1 = L.nodes.FindIndex(delegate(node b)
                        {
                            return (rArc.To.name == b.name);
                        });
                        to = Lmapping.nodes[index1];
                    }
                    else
                    {
                        index1 = R.nodes.FindIndex(delegate(node b)
                        {
                            return (rArc.To.name == b.name);
                        });
                        to = Rmapping.nodes[index1];
                    }
                    #endregion

                    D.addArc(rArc.name, rArc.arcType, from, to);
                    Rmapping.arcs[i] = D.arcs[D.lastArc];
                    rArc.copy(D.arcs[D.lastArc]);
                }
                #endregion
                #region Step 4. update K arcs
                else
                {
                    index2 = L.arcs.FindIndex(delegate(arc b)
                        { return (rArc.name == b.name); });
                    /* first find the position of the same arc in L. */
                    ruleArc currentLArc = (ruleArc)L.arcs[index2];
                    KArc = Lmapping.arcs[index2];    /* then find the actual arc in D that is to be changed.*/
                    /* one very subtle thing just happend here! (07/06/06) if the direction is reversed, then
                     * you might mess-up this Karc. We need to establish a boolean so that references 
                     * incorrectly altered. */
                    Boolean KArcIsReversed = false;
                    if ((Lmapping.nodes.IndexOf(KArc.From) != L.nodes.IndexOf(currentLArc.From)) &&
                        (Lmapping.nodes.IndexOf(KArc.To) != L.nodes.IndexOf(currentLArc.To)))
                        KArcIsReversed = true;

                    Rmapping.arcs[i] = KArc;
                    /*similar to Step 3., we first find how to update the from and to. */
                    if ((currentLArc.From != null) && (rArc.From == null))
                    {
                        /* this is a rare case in which you actually want to break an arc from its attached 
                         * node. If the corresponding L arc is not null only! if it is null then it may be 
                         * actually connected to something in the host, and we are in no place to remove it. */
                        if (KArcIsReversed) KArc.To = null;
                        else KArc.From = null;
                    }
                    else if (rArc.From != null)
                    {
                        index1 = R.nodes.FindIndex(delegate(node b) { return (rArc.From.name == b.name); });
                        /* find the position of node that this arc is supposed to connect to in R */
                        if (KArcIsReversed) KArc.To = Rmapping.nodes[index1];
                        else KArc.From = Rmapping.nodes[index1];
                    }
                    /* now do the same for the To connection. */
                    if ((currentLArc.To != null) && (rArc.To == null))
                    {
                        if (KArcIsReversed) KArc.From = null;
                        else KArc.To = null;
                    }
                    else if (rArc.To != null)
                    {
                        index1 = R.nodes.FindIndex(delegate(node b) { return (rArc.To.name == b.name); });
                        if (KArcIsReversed) KArc.From = Rmapping.nodes[index1];
                        else KArc.To = Rmapping.nodes[index1];
                    }
                    /* just like in Step 2, we may need to update the labels of the arc. */
                    foreach (string a in currentLArc.localLabels)
                        if (!rArc.localLabels.Contains(a))
                            KArc.localLabels.Remove(a);
                    foreach (string a in rArc.localLabels)
                        if (!currentLArc.localLabels.Contains(a))
                            KArc.localLabels.Add(a.ToString());
                    foreach (double a in currentLArc.localVariables)
                        if (!rArc.localVariables.Contains(a))
                            KArc.localVariables.Remove(a);
                    foreach (double a in rArc.localVariables)
                        if (!currentLArc.localVariables.Contains(a))
                            KArc.localVariables.Add(a);
                    KArc.curveStyle = rArc.curveStyle;
                    if (!KArc.directed || (KArc.directed && currentLArc.directionIsEqual))
                        KArc.directed = rArc.directed;
                    /* if the KArc is currently undirected or if it is and direction is equal
                     * then the directed should be inherited from R. */
                    if (!KArc.doublyDirected || (KArc.doublyDirected && currentLArc.directionIsEqual))
                        KArc.doublyDirected = rArc.doublyDirected;
                    KArc.fromConnector = rArc.fromConnector;
                    KArc.toConnector = rArc.toConnector;
                }
                #endregion
            }
        }