Beispiel #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);
        }
Beispiel #2
0
        public designGraph copy()
        {
            /* 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.*/
            int         toIndex, fromIndex;
            designGraph copyOfGraph = new designGraph();

            copyOfGraph.name = name;
            foreach (string label in globalLabels)
            {
                copyOfGraph.globalLabels.Add(label.ToString());
            }
            foreach (double v in globalVariables)
            {
                copyOfGraph.globalVariables.Add(v);
            }
            foreach (node origNode in nodes)
            {
                copyOfGraph.nodes.Add(origNode.copy());
            }
            foreach (arc origArc in arcs)
            {
                arc copyOfArc = origArc.copy();
                toIndex   = nodes.FindIndex(delegate(node a) { return(a == origArc.To); });
                fromIndex = nodes.FindIndex(delegate(node b) { return(b == origArc.From); });
                copyOfGraph.addArc(copyOfArc, fromIndex, toIndex);
            }
            return(copyOfGraph);
        }
Beispiel #3
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);
        }
Beispiel #4
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);
        }
Beispiel #5
0
        private void freeArcEmbedding(designGraph Lmapping, designGraph host, designGraph Rmapping)
        {
            /* There are nodes in host which may have been left dangling due to the fact that their 
             * connected nodes were part of the L-R deletion. These now need to be either 1) connected
             * up to their new nodes, 2) their references to old nodes need to be changed to null if 
             * intentionally left dangling, or 3) the arcs are to be removed. In the function 
             * removeLdiffKfromHost we remove old nodes but leave their references intact on their 
             * connected arcs. This allows us to quickly find the list of freeArcs that are candidates 
             * for the embedding rules. Essentially, we are capturing the neighborhood within the host 
             * for the rule application, that is the arcs that are affected by the deletion of the L-R
             * subgraph. Should one check non-dangling non-neighborhood arcs? No, this would seem to 
             * cause a duplication of such an arc. Additionally, what node in host should the arc remain 
             * attached to?  There seems to be no rigor in applying these more global (non-neighborhood) 
             * changes within the literature as well for the general edNCE method. */
            sbyte freeEndIdentifier;
            node newNodeToConnect, nodeRemovedinLdiffRDeletion, toNode, fromNode;
            node  neighborNode = null;
            int numOfArcs = host.arcs.Count;

            for (int i = 0; i != numOfArcs; i++)
            {
                /* first, check to see if the arc is really a freeArc that needs updating. */
                if (embeddingRule.arcIsFree(host.arcs[i], host, out freeEndIdentifier, neighborNode))
                {
                    arc freeArc = host.arcs[i];
                    /* For each of the embedding rules, we see if it is applicable to the identified freeArc.
                     * The rule then modifies the arc by simply pointing it to the new node in R as indicated
                     * by the embedding Rule's RNodeName. NOTE: the order of the rules are important. If two
                     * rules are 'recognized' with the same freeArc only the first one will modify it, as it 
                     * will then remove it from the freeArc list. This is useful in that rules may have precedence
                     * to one another. There is an exception if the rule has allowArcDuplication set to true, 
                     * since this would simply create a copy of the arc. */
                    foreach (embeddingRule eRule in embeddingRules)
                    {
                        newNodeToConnect = eRule.findNewNodeToConnect(R, Rmapping);
                        nodeRemovedinLdiffRDeletion = eRule.findDeletedNode(L, Lmapping);

                        if (eRule.ruleIsRecognized(freeEndIdentifier, freeArc, 
                            neighborNode, nodeRemovedinLdiffRDeletion))
                        {
                            #region  set up new connection points
                            if (freeEndIdentifier >= 0)
                            {
                                if (eRule.newDirection >= 0)
                                {

                                    toNode = newNodeToConnect;
                                    fromNode = freeArc.From;
                                }
                                else
                                {
                                    toNode = freeArc.From;
                                    fromNode = newNodeToConnect;
                                }
                            }
                            else
                            {
                                if (eRule.newDirection <= 0)
                                {
                                    fromNode = newNodeToConnect;
                                    toNode = freeArc.To;
                                }
                                else
                                {
                                    fromNode = freeArc.To;
                                    toNode = newNodeToConnect;
                                }
                            }
                            #endregion

                            #region if making a copy of arc, duplicate it and all the characteristics
                            if (eRule.allowArcDuplication)
                            {
                                /* under the allowArcDuplication section, we will be making a copy of the 
                                 * freeArc. This seems a little error-prone at first, since if there is only
                                 * one rule that applies to freeArc then we will have good copy and the old
                                 * bad copy. However, at the end of this function, we go through the arcs again
                                 * and remove any arcs that still appear free. This also serves the purpose to 
                                 * delete any dangling nodes that were not recognized in any rules. */
                                host.addArc(freeArc.copy(), fromNode, toNode);
                            }
                            #endregion

                            #region else, just update the old freeArc
                            else
                            {
                                freeArc.From = fromNode;
                                freeArc.To = toNode;
                                break; /* skip to the next arc */
                                /* this is done so that no more embedding rules will be checked with this freeArc.*/
                            }
                            #endregion
                        }
                    }
                }
            }
            #region clean up (i.e. delete) any freeArcs that are still in host.arcs
            for (int i = host.arcs.Count - 1; i >= 0; i--)
            {
                /* this seems a little archaic to use this i-counter instead of foreach.
                 * the issue is that since we are removing nodes from the list as we go
                 * through it, we very well can't use foreach. The countdown allows us to 
                 * disregard problems with the deleting. */
                if ((host.arcs[i].From != null && !host.nodes.Contains(host.arcs[i].From)) ||
                    (host.arcs[i].To != null && !host.nodes.Contains(host.arcs[i].To)))
                    host.removeArc(host.arcs[i]);
            }
            #endregion
        }
Beispiel #6
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
            }
        }
Beispiel #7
0
        public designGraph copy()
        {
            /* 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.*/
            int toIndex, fromIndex;
            designGraph copyOfGraph = new designGraph();

            copyOfGraph.name = name;
            foreach (string label in globalLabels)
                copyOfGraph.globalLabels.Add(label.ToString());
            foreach (double v in globalVariables)
                copyOfGraph.globalVariables.Add(v);
            foreach (node origNode in nodes)
            {
                copyOfGraph.nodes.Add(origNode.copy());
            }
            foreach (arc origArc in arcs)
            {
                arc copyOfArc = origArc.copy();
                toIndex = nodes.FindIndex(delegate(node a) { return (a == origArc.To); });
                fromIndex = nodes.FindIndex(delegate(node b) { return (b == origArc.From); });
                copyOfGraph.addArc(copyOfArc, fromIndex, toIndex);
            }
            return copyOfGraph;
        }