2

I am trying to group all values together that share common elements across tuples - essentially find groups of numbers that for any combination of them (no order required) - I have the tuple. For example, if I have the following set of tuples:

(1,2),(1,3),(1,5),(1,6),(2,3),(2,5),(2,7),(3,5),(3,7),(3,9)

I want to understand all the elements that are in common. For this example, this would be:

1, 2, 3, 5  (since I have any combination of 1,2,3 and 5)
2, 3, 7 (since I have any combination of 2,3 and 7)
1, 6 (since I have any combination of 1 and 6)
3, 9 (since I have any combination of 3 and 9)

Any thoughts on how to solve this?

soundslikeodd
  • 1,078
  • 3
  • 19
  • 32
mcfly
  • 1,151
  • 4
  • 33
  • 55
  • 3
    The requirements aren't clear each line just says *since I have any combination of*. – MrJLP Jul 26 '17 at 19:54
  • I believe mcfly means that there could be a `(1,2)` or a `(2,1)` and they'd be treated the same – dashiell Jul 26 '17 at 19:55
  • Why isn't `1,6` on the first line then? It's not clear to me what *since I have any combination* means. – MrJLP Jul 26 '17 at 19:56
  • yes - exactly. I don't care if it is (1,2) or (2,1) - these are the same in my example. (1,6) isn't on the first line because I don't have (2,6) or (3,6) or (5,6). – mcfly Jul 26 '17 at 19:56
  • 5
    This problem is called: "Finding All Cliques of an Undirected Graph". In this instance every tuple is an edge that connects two nodes. – Nir Alfasi Jul 26 '17 at 19:57
  • 1
    @mcfly so this is a graph problem? How about rephrase this so it's clear what you're trying to do. – MrJLP Jul 26 '17 at 19:58
  • Please refer to pseudo code in https://stackoverflow.com/questions/37999282/finding-all-cliques-of-an-undirected-graph – Rohan Jul 26 '17 at 20:00
  • I didn't realize it was a graph problem until mentioned - thanks - I will look at the cliques of an undirected graph. – mcfly Jul 26 '17 at 20:01
  • @alfasin: It's probably called "Finding all maximal cliques", since any subgraph of a clique is a clique. ;) – Eric Duminil Jul 26 '17 at 20:01
  • @anon: Because they're cliques, but they're not "maximal cliques". They are included in larger cliques. See https://en.wikipedia.org/wiki/Clique_(graph_theory)#Definitions – Eric Duminil Jul 26 '17 at 20:08

1 Answers1

4

As mentioned by @alfasin, you're looking for the maximal cliques in your graph.

A clique, C, in an undirected graph G = (V, E) is a subset of the vertices, C ⊆ V, such that every two distinct vertices are adjacent.

A maximal clique is a clique that cannot be extended by including one more adjacent vertex, that is, a clique which does not exist exclusively within the vertex set of a larger clique.

NetworkX with find_cliques is your friend:

>>> import networkx as nx
>>> G = nx.Graph([(1,2),(1,3),(1,5),(1,6),(2,3),(2,5),(2,7),(3,5),(3,7),(3,9)])
>>> list(nx.find_cliques(G))
[[3, 9], [3, 2, 1, 5], [3, 2, 7], [6, 1]]

If you want to define your graph as the union of small cliques and see if they merge to larger cliques, you can use itertools.combinations to iterate over all the edges of your input cliques and add them to the graph:

import networkx as nx
from itertools import combinations

G = nx.Graph()

cliques = [(1,2,3),(1,2,4),(1,3,4),(2,3,4)]

for clique in cliques:
  for vertices in combinations(clique, r=2):
    G.add_edge(*vertices)

print(list(nx.find_cliques(G)))
# [[1, 2, 3, 4]]
Eric Duminil
  • 52,989
  • 9
  • 71
  • 124
  • well - this is fantastic - thanks to all for steering me toward graphs! – mcfly Jul 26 '17 at 20:11
  • @mcfly: That's what I love most about Python. Have a problem? Someone at Google, NASA or MIT probably had it too and wrote some cool library to solve it. :) – Eric Duminil Jul 26 '17 at 20:12
  • @EricDuminil thanks for posting this solution, I was not aware of this library! – Nir Alfasi Jul 26 '17 at 20:13
  • @EricDuminil: couldn't agree more! this is a great library - look forward to seeing what else it can do! – mcfly Jul 26 '17 at 20:15
  • @EricDuminil - is it possible to extend this to larger tuples? For example, can i have (1,2,3),(1,2,4),(1,3,4),(2,3,4) and get a single clique of (1,2,3,4)? – mcfly Jul 26 '17 at 20:29
  • @mcfly I wouldn't expect it to work since `(2,5)` represents an edge between nodes 2 and 5. But how would one interpret: `(2,5,9)` ? – Nir Alfasi Jul 26 '17 at 20:31
  • @alfasin - are there any other theories you may know of that consider this question? – mcfly Jul 26 '17 at 20:34
  • 1
    @alfasin: An edge is a 2-vertex clique and a graph can be designed as a collection of edges, so why not define a graph as a collection of 3-vertex cliques? `(2,5,9)` can be interpreted as 3 edges `(2,5)`, `(5,9)` and `(2,9)`. You just need to iterate over the vertex combinations. – Eric Duminil Jul 26 '17 at 20:40