0

I've been searching this all over the internet for about two or three consecutive days, but no luck so far.

I know that there are lots of libraries and implementation for subgraph isomorphism in the wild, but they all work for unweighted graphs. For instance, two of the most prevalent algorithms are VF2 and Uleman's algorithm. Here, my question is: Are there any methods that given a graph (G) and a query graph (g), can one find whether g is a subgraph (and isomorphic) to G or not? (Please note that the following is the edge list representation of the graphs.)

G
1 2 c
1 3 d
1 4 c
2 3 a
...
g
1 3 d
2 3 a

In this case, g is a subgraph and is isomorphic to G, but if we have something like this:

g
1 3 t
2 3 a

Now g is no longer a subgraph of G and is not isomorphic.

UPDATE: Both graphs are undirected.

rAntonioH
  • 129
  • 2
  • 12
Yaser Kenesh
  • 81
  • 1
  • 9
  • Just to be clear, g={(1 2 a)} is isomorphic to a subgraph of G (namely, {(2 3 a)}). Is this the result you want? Also, is G directed (i.e. should output be 'no' for g={(1 3 d), (3 2 a)})? – Abstraction Dec 06 '13 at 06:55
  • g={(1 2 a)} is not isomorphic to G, since the weight of this edge in G is "c" not "a". For the second case, i.e. g={(1 3 d), (3 2 a)}), it should return TRUE. Simply put, both graphs are undirected, here. – Yaser Kenesh Dec 08 '13 at 04:20

1 Answers1

1

g={(1 2 a)} is not isomorphic to G, since the weight of this edge in G is "c" not "a".

This is weird. Simply put, graphs G, G' (actually, any algebraic structures) are isomorphic if there exists some function f from {G<->G'} so that for any relation R(g1, g2) (g1, g2 in G), R'(f(g1), f(g2)) also holds for G' and vice versa. So any graph G' gained from G by renaming (permutation) of vertexes is isomorphic to G.

As it seems, you are instead interested in figuring out whether for any marked edge of g there exists edge connecting the same vertexes and bearing the same mark in G. Most simple way to do this is duplicating edges of G and sorting them by component. Then for each edge of query g it will take O(log(|G|)) to check whether G has the same edge (and it has the same mark). Thus, total time is O(|G|*log(|G|)) to prepare graph G and O(|g|*log(|G|)) to process each subsequent query.

Upd: By "sorting edges of G by component" I meant the following: build an array (or binary tree) of edges, sorted by first vertex then by second vertex. To search for an edge easily, it should be duplicated. For example, edge (1, 2, c) should be present as (1, 2, c) and (2, 1, c). So that, in array form, G from example above becomes

(1, 2, c)
(1, 3, d)
(1, 4, c)
(2, 1, c)
(2, 3, a)
(3, 1, d)
(3, 2, a)
(4, 1, c)

On the afterthought, it may be better to write both edges of G and g with vertex with lesser number first - this way, no duplication is needed.

Abstraction
  • 1,108
  • 11
  • 25
  • Thanks for the answer. That was concise and precise. I almost got what is the solution. However, there is one point that I didn't understand. What do you mean by sorting the edges by component? and why do I need to duplicate the edges in G? I'm sure the complexity of O(log(|G|) is related to the component, however I didn't get the idea behind it. – Yaser Kenesh Dec 17 '13 at 03:59
  • @YaserKenesh Made an update. You make sorted array of edges of G to use binary search. Easiest way to sort is this: for edges E1=(a, b, mark1), E2=(c, d, mark2), E1 – Abstraction Dec 17 '13 at 06:58
  • Thanks man, I knew that using lexicographic order will do the job. I was hoping to get a better and optimal way for it. Though, it seems there is no optimal solution for it right now. – Yaser Kenesh Dec 17 '13 at 18:49