Beispiel #1
0
 /// <summary>
 /// Add a vertex into the graph being built.
 /// </summary>
 /// <param name="name"></param>
 /// <param name="label"></param>
 /// <returns></returns>
 public Vertex AddVertex(string name, string label)
 {
     VertexData vData = new VertexData();
     int vId = getNextId(name);
     Vertex v = idCounter++;//new ObjectId(new Symbol(name), vId);
     vData.vertex = v;
     vData.label = vData.label.Add(new Pair<CompoundTerm, IComparable>(new CompoundTerm(new Symbol(name), new Sequence<Term>()), label));
     vertexRecords.Add(v, vData);
     return v;
 }
 /// <summary>
 /// Make sure that a vertexData record has been initialized for the vertex.
 /// </summary>
 /// <param name="vertex"></param>
 /// <returns>VertexData record corresponding to the argument.</returns>
 VertexData EnsureVertex(Vertex vertex)
 {
     VertexData result;
     if (!this.vertexRecords.TryGetValue(vertex, out result))
     {
         result = new VertexData(vertex, Set<Pair<CompoundTerm, IComparable>>.EmptySet,
                                 Map<EdgeLabel, Vertex>.EmptyMap, Map<EdgeLabel, Set<Vertex>>.EmptyMap);
         this.vertexRecords.Add(vertex, result);
     }
     return result;
 }
Beispiel #3
0
            internal Map<Node, Node> ComputeIsomorphism()
            {
                // We start with a functional pass.
                ControlState c = ControlState.InitialFunctionalPass;
                while (true)
                {

                    switch (c)
                    {
                        # region Find all reachable functional matches of current active nodes x and y.
                        case ControlState.InitialFunctionalPass:
                            c = ExtendForOnlyFunctionalEdges(x, y);

                            break;
                        # endregion

                        #region Find all relational matches after one or more functional pass.
                        case ControlState.RelationalPass:
                            if (xPartitions.Count > 0)
                                goto case ControlState.NextPartition;
                            if (relationalPassIndex >= index)
                            {
                                if (relationalPassIndex == numberOfNodes)
                                    c = ControlState.Done;
                                else
                                    goto case ControlState.Fail; // c = ControlState.Fail;
                                break;

                            }
                            x = bijection[relationalPassIndex,X];
                            y = bijection[relationalPassIndex,Y];
                            xData = g1.vertexRecords[x];
                            yData = g2.vertexRecords[y];
                            if (relationalEdgeEnumerator == default(IEnumerator<CompoundTerm>))
                            {

                                relationalEdgeLabels = Set<CompoundTerm>.EmptySet;
                                foreach (Pair<CompoundTerm, Set<Node>> pair in xData.unorderedOutgoingEdges) {
                                    relationalEdgeLabels = relationalEdgeLabels.Add(pair.First);
                                }
                                relationalEdgeEnumerator = relationalEdgeLabels.GetEnumerator();
                            }
                            if (relationalEdgeEnumerator.MoveNext())
                            {
                                xEdgeLabel = relationalEdgeEnumerator.Current;
                                //xtoNodes = xData.unorderedOutgoingEdges[xEdgeLabel];
                                if (yData.unorderedOutgoingEdges.ContainsKey(xEdgeLabel)) // Perhaps this check can be assumed true for all graphs?
                                {
                                    //ytoNodes = yData.unorderedOutgoingEdges[xEdgeLabel];
                                    xPartitions = GetPartitions(g1, x, xEdgeLabel);
                                    yPartitions = GetPartitions(g2, y, xEdgeLabel);

                                    //Console.WriteLine("Partitions: " + x + " has " + xPartitions.Count + "elements.");
                                    if (PartitionsAreConsistent(xPartitions,yPartitions))
                                        goto case ControlState.NextPartition;
                                    else
                                        goto case ControlState.Fail;
                                    ////c = ControlState.NextRelationalEdge;
                                    //goto case ControlState.NextRelationalEdge;
                                }
                                else
                                    goto case ControlState.Fail; // c = ControlState.Fail;

                            }
                            else
                            {
                                relationalPassIndex++;
                                relationalEdgeEnumerator = default(IEnumerator<CompoundTerm>);
                                relationalEdgeLabels = default(Set<CompoundTerm>);
                                if (relationalPassIndex == numberOfNodes)
                                    c = ControlState.Done;
                            }
                            break;

                        case ControlState.NextPartition:
                            if (xPartitions.Count > 0) // the other constraints have been implied by PartitionsAreConsistent
                            {
                                Pair<IComparable, bool> label = xPartitions.Keys.Choose(0);
                                xtoNodes = xPartitions[label];
                                xPartitions = xPartitions.RemoveKey(label);
                                ytoNodes = yPartitions[label];
                                yPartitions = yPartitions.RemoveKey(label);
                                goto case ControlState.ProcessPartition;
                            }
                            else
                                c = ControlState.RelationalPass;
                            break;
                        // It is possible that we have multiple sets of relational edges from a node. The following is done for each set.
                        case ControlState.ProcessPartition:

                                // xEdgeLabel has been set
                                // xtoNodes has been set;
                                // ytoNodes has been set;
                                Node x1, y1;
                                // remove all nodes that have already been matched. (previously implemented as PruneCandidates)
                                Set<Node> xtoNodesTmp = xtoNodes;
                                int count = xtoNodesTmp.Count;
                                for (int i = 0; i < count; i++)
                                {
                                    x1 = xtoNodesTmp.Choose(i);
                                    if (indexDict.ContainsKey(x1))
                                    {
                                        y1 = bijection[indexDict[x1], Y];
                                        if (ytoNodes.Contains(y1))
                                        {
                                            xtoNodes = xtoNodes.Remove(x1);
                                            ytoNodes = ytoNodes.Remove(y1);
                                        }
                                        else
                                        {
                                            goto case ControlState.Fail;// c = ControlState.Fail;
                                            //goto EndOfNextRelationalEdge;
                                            //break;
                                        }
                                    }
                                    //else if (IsOrderIndependent(x1,g1))
                                    //{
                                    //    xtoNodesOrderIndependent = xtoNodesOrderIndependent.Add(x1);
                                    //    bucketOf[g1.LabelOf(x1)].g2Nodes
                                    //    xtoNodes = xtoNodes.Remove(x1);
                                    //    //ytoNodesOrderIndependent = ytoNodesOrderIndependent.Add(x1);
                                    //}
                                }
                                if (xtoNodes.Count == 0)
                                {
                                    //c = ControlState.RelationalPass;
                                    c = ControlState.NextPartition;
                                    break; // out of the switch statement
                                }// we do not need to check as all nodes contained in xtoNodes were already contained.

                                //if (IsOrderIndependent(xtoNodes.Choose(0),g1))
                                //{
                                //    goto case ControlState.ChooseOne;
                                //}
                                //else
                                //{
                                    btp = new BacktrackPointWithPartitions(indexDict, rangeDict, xEdgeLabel, index, relationalPassIndex, relationalEdgeLabels.Remove(xEdgeLabel), xtoNodes, ytoNodes, xPartitions, yPartitions);
                                    goto case ControlState.Choose;
                                //}
                                //break;

                        #endregion

                        #region Choose one combination of matching relational edges and add a backtrackpoint if necessary
                        case ControlState.Choose:
                            if (btp == null) // check used to stop when backtracking.
                            {
                                c = ControlState.Fail;
                                break;
                            }
                            c = Choose();
                            break;

                        #endregion

                        #region Choose one combination of matching relational edges and do not add backtrackpoint
                        case ControlState.ChooseOne:
                            c = ChooseOne();
                            break;

                        #endregion

                        # region Process a backtrack request.

                        case ControlState.Fail:
                            if (backtrackStack.Count == 0)
                                return null;
                            else
                            {
                                // Reset environment to topmost backtrackpoint and continue
                                // with the relevant Choose.
                                btp = backtrackStack.Pop();

                                // Restore program state from the BacktrackPoint.
                                index = btp.index;
                                relationalPassIndex = btp.relationalPassIndex;
                                indexDict = BacktrackPointWithPartitions.getCopy(btp.indexDict);
                                xEdgeLabel = btp.outLabel;
                                rangeDict = BacktrackPointWithPartitions.getCopy(btp.rangeDict);
                                x = bijection[relationalPassIndex, X];
                                y = bijection[relationalPassIndex, Y];
                                xData = g1.vertexRecords[x];
                                yData = g2.vertexRecords[y];
                                xtoNodes = btp.xtoNodes;
                                ytoNodes = btp.ytoNodes;
                                relationalEdgeLabels = btp.relationalEdgeLabels;
                                relationalEdgeEnumerator = btp.relationalEdgeLabels.GetEnumerator();
                                xPartitions = btp.xPartitions;
                                yPartitions = btp.yPartitions;

                                c = ControlState.Choose;
                            }
                            break;
                        # endregion

                        case ControlState.Done:
                            goto Success;

                        default:
                            break;
                    }
                }
                #region Prepare result map and return.
                Success:

                    Map<Node, Node> iso = Map<Node, Node>.EmptyMap;
                    for (int i = 0; i < numberOfNodes; i++)
                    {
                        iso = iso.Add(bijection[i, X], bijection[i, Y]);
                    }
                    return iso;
                #endregion
            }
Beispiel #4
0
 public void IsoSingleNodeUllmann()
 {
     Vertex root1 = 1;// new ObjectId(new Symbol("Root"), 1);
     VertexData vd1 = new VertexData();
     Vertex root2 = 1;// new ObjectId(new Symbol("Root"), 1);
     VertexData vd2 = new VertexData();
     Dictionary<Vertex, VertexData> vr1 = new Dictionary<Vertex, VertexData>();
     vr1.Add(root1, vd1);
     Dictionary<Vertex, VertexData> vr2 = new Dictionary<Vertex, VertexData>();
     vr2.Add(root1, vd2);
     RootedLabeledDirectedGraph g1 = new RootedLabeledDirectedGraph(root1, vr1);
     RootedLabeledDirectedGraph g2 = new RootedLabeledDirectedGraph(root2, vr2);
     Map<Vertex, Vertex> iso = GraphIsomorphism.ComputeIsomorphismUllmann(g1, g2);
     Assert.AreEqual(1, iso.Count);
 }
Beispiel #5
0
            internal Map<Node, Node> ComputeIsomorphism()
            {
                // We start with a functional pass.
                ControlState c = ControlState.InitialFunctionalPass;
                while (true)
                {

                    switch (c)
                    {
                        # region Find all reachable functional matches of current active nodes x and y.
                        case ControlState.InitialFunctionalPass:
                            c = ExtendForOnlyFunctionalEdges(x, y);

                            break;
                        # endregion

                        #region Find all relational matches after one or more functional pass.
                        case ControlState.RelationalPass:
                            if (relationalPassIndex >= index)
                            {
                                if (relationalPassIndex == numberOfNodes)
                                    c = ControlState.Done;
                                else
                                    c = ControlState.Fail;
                                break;

                            }
                            x = bijection[relationalPassIndex, X];
                            y = bijection[relationalPassIndex, Y];
                            xData = g1.vertexRecords[x];
                            yData = g2.vertexRecords[y];
                            if (relationalEdgeEnumerator == default(IEnumerator<CompoundTerm>))
                            {

                                relationalEdgeLabels = Set<CompoundTerm>.EmptySet;
                                foreach (Pair<CompoundTerm, Set<Node>> pair in xData.unorderedOutgoingEdges)
                                {
                                    relationalEdgeLabels = relationalEdgeLabels.Add(pair.First);
                                }
                                relationalEdgeEnumerator = relationalEdgeLabels.GetEnumerator();
                            }
                            if (relationalEdgeEnumerator.MoveNext())
                            {
                                xEdgeLabel = relationalEdgeEnumerator.Current;
                                xtoNodes = xData.unorderedOutgoingEdges[xEdgeLabel];
                                if (yData.unorderedOutgoingEdges.ContainsKey(xEdgeLabel)) // Perhaps this check can be assumed true for all graphs?
                                {
                                    ytoNodes = yData.unorderedOutgoingEdges[xEdgeLabel];
                                    c = ControlState.NextRelationalEdge;
                                }
                                else
                                    c = ControlState.Fail;

                            }
                            else
                            {
                                relationalPassIndex++;
                                relationalEdgeEnumerator = default(IEnumerator<CompoundTerm>);
                                relationalEdgeLabels = default(Set<CompoundTerm>);
                                if (relationalPassIndex == numberOfNodes)
                                    c = ControlState.Done;
                            }
                            break;

                        // It is possible that we have multiple sets of relational edges from a node. The following is done for each set.
                        case ControlState.NextRelationalEdge:

                            // xEdgeLabel has been set
                            // xtoNodes has been set;
                            // ytoNodes has been set;
                            Node x1, y1;
                            // remove all nodes that have already been matched.
                            for (int i = 0; i < xtoNodes.Count; i++)
                            {
                                x1 = xtoNodes.Choose(i);
                                if (indexDict.ContainsKey(x1))
                                {
                                    y1 = bijection[indexDict[x1], Y];
                                    if (ytoNodes.Contains(y1))
                                    {
                                        xtoNodes = xtoNodes.Remove(x1);
                                        ytoNodes = ytoNodes.Remove(y1);
                                    }
                                    else
                                    {
                                        c = ControlState.Fail;
                                        goto EndOfNextRelationalEdge;
                                    }
                                }
                            }
                            if (xtoNodes.Count == 0)
                            {
                                c = ControlState.RelationalPass;
                                break; // out of the switch statement
                            }// we do not need to check as all nodes contained in xtoNodes were already contained.
                            //isoExt = ExtendIsomorphism4(backtrackBuckets, backtrackStack, isoExt, xtoNodes.Choose(), ytoNodes.Choose());

                            btp = new BacktrackPoint(indexDict, rangeDict, xEdgeLabel, index, relationalPassIndex, relationalEdgeLabels.Remove(xEdgeLabel), xtoNodes, ytoNodes);
                            c = ControlState.Choose;

                        //goto case ControlState.Choose;
                        EndOfNextRelationalEdge:
                            break;

                        #endregion

                        #region Choose one combination of matching relational edges
                        case ControlState.Choose:
                            if (btp == null) // check used to stop when backtracking.
                            {
                                c = ControlState.Fail;
                                break;
                            }
                            c = Choose();
                            break;

                        #endregion

                        # region Process a backtrack request.

                        case ControlState.Fail:
                            if (backtrackStack.Count == 0)
                                return null;
                            else
                            {
                                // Reset environment to topmost backtrackpoint and continue
                                // with the relevant Choose from where we left off last time.
                                btp = backtrackStack.Pop();

                                // Restore program state from the BacktrackPoint.
                                index = btp.index;
                                relationalPassIndex = btp.relationalPassIndex;
                                indexDict = BacktrackPoint.getCopy(btp.indexDict);
                                xEdgeLabel = btp.outLabel;
                                rangeDict = BacktrackPoint.getCopy(btp.rangeDict);
                                x = bijection[relationalPassIndex, X];
                                y = bijection[relationalPassIndex, Y];
                                xData = g1.vertexRecords[x];
                                yData = g2.vertexRecords[y];
                                xtoNodes = btp.xtoNodes;
                                ytoNodes = btp.ytoNodes;
                                relationalEdgeLabels = btp.relationalEdgeLabels;
                                relationalEdgeEnumerator = btp.relationalEdgeLabels.GetEnumerator();

                                c = ControlState.Choose;
                            }
                            break;
                        # endregion

                        case ControlState.Done:
                            goto Success;

                        default:
                            break;
                    }
                }
                #region Prepare result map and return.
                Success:

                Map<Node, Node> iso = Map<Node, Node>.EmptyMap;
                for (int i = 0; i < numberOfNodes; i++)
                {
                    iso = iso.Add(bijection[i, X], bijection[i, Y]);
                }
                return iso;
                #endregion
            }