How to avoid unhashable type 'list' when checking to see if maximal cliques are contained in another graph in NetworkX Library? - graph

I would like to be able to compare the maximal cliques of two graphs G and H, in the networkX library, and store the maximal cliques of G which are not maximal cliques in H as a set (i.e., having no duplicates).
This is the code I am working with, but when running this I get an error
max_cliques_H = set(nx.find_cliques(H)) ^^^^^^^^^^^^^^^^^^^^^^^ TypeError: unhashable type: 'list'
Any help is appreciated!
import networkx as nx
# Create graph G and H
G = nx.complete_graph(5)
H = nx.complete_graph(7)
# Find all maximal cliques in G
max_cliques_G = list(nx.find_cliques(G))
# Find all maximal cliques in H
max_cliques_H = set(nx.find_cliques(H))
# Initialize an empty set to store cliques that are not in H
not_in_H = set()
# Iterate over all maximal cliques in G
for clique_G in max_cliques_G:
# Check if the clique from G is not a maximal clique in H
if clique_G not in max_cliques_H:
not_in_H.add(clique_G)
print(f"Cliques that are not in H : {not_in_H}")
I've tried to write a program that will perform the specified operation, and I was expecting to get a set (i.e., with no duplicates) of maximal cliques in G which are not maximal cliques in H, but instead I got an error.
EDIT I realized my example is not good, since the complete graph on 5 vertices is a subgraph of the complete graph on 7 vertices. I think if you swap G and H then my question makes more sense, though in general I want to compare graphs with the same vertex set but different edges. At amy rate, I still get the unhashable list error.

Related

Trying to pad adjacency matrix of networkx graph with 0's

I have a list of networkX graphs gSet that are of varying sizes. I want to add isolated nodes to all of them such that they all have the same number of nodes thereby padding their adjacency matrices on the right and bottom with 0's. This is what I have tried thus far, maxNodes is the number of nodes in the largest graph from the list:
for i in range(0, len( gSet )):
numOfNodes = nx.to_numpy_array( gSet[i] ).shape[0]
for j in range(maxNodes - numOfNodes, maxNodes ):
gSet[i].add_node(j)
This doesn't seem to change all the graphs to be the same size however.
# collection of dummy graphs:
gSet = []
for _ in range(10):
size = np.random.randint(1,8)
G = nx.from_numpy_array(np.random.rand(size,size)>0.8)
gSet.append(G)
# check number of nodes in each graph:
print('before:')
for g in gSet:
print(len(g))
# find number of nodes in graph with most nodes:
max_nodes = max([len(g) for g in gSet])
# networkx numbers nodes from 0 to the number of nodes -1 (=length of the graph -1)
# so len(g) gives the smallest positive integer that can be used as a node name.
for g in gSet:
while len(g) < max_nodes:
g.add_node(len(g))
# check number of nodes in each graph:
print('after:')
for g in gSet:
print(len(g))
gSet.add_node(j)
This looks to be incorrect. You want to add the extra node to ONE of the graphs in gSet.

Subgraph in LightGraphs - Julia

Say that I have a big network with 10^4 nodes. And then I want to analyse the neighbourhood associated with a random node, say node 10. I can see which are the nodes connected to that node by looking at the 10th row entries of the adjacency matrix, and then I can repeat this if I want to look at the neighbours of those neighbours (second shell) and so on and so forth.
Is there an efficient way to do this - or even an inefficient but better than writing the whole thing from the scratch-? The actual network that I have is a Random Regular Graph and I am interested on the tree-like local structure for large networks.
If I understand your use case, there is a good way of doing this: the egonet function. You give it a graph, a starting vertex, and number of hops, and it will return an induced subgraph of the graph starting at the vertex and going out that number of hops. Here's the docstring:
egonet(g, v, d, distmx=weights(g))
Return the subgraph of g induced by the neighbors of v up to distance d, using weights (optionally) provided by distmx. This is equivalent to
induced_subgraph(g, neighborhood(g, v, d, dir=dir))[1].
Optional Arguments
––––––––––––––––––––
• dir=:out: if g is directed, this argument specifies the edge direction
with respect to v (i.e. :in or :out).
Edited to add: if all you need are the vertex indices, then neighborhood() is what you want:
neighborhood(g, v, d, distmx=weights(g))
Return a vector of each vertex in g at a geodesic distance less than or equal to d, where distances may be specified by distmx.
Optional Arguments
––––––––––––––––––––
• dir=:out: If g is directed, this argument specifies the edge direction
with respect to v of the edges to be considered. Possible values: :in or :out.

Given a graph G = (V, E) prove e <= n(n-1)/2 for all n

I'm trying to figure out to solve this problem: Given a graph G = (V, E) prove e <= n(n-1)/2 for all n, where e is the number of edges and n is the number of vertices.
I'm thinking that I should somehow be using math induction to figure out the correct answer and use n = 1 or 0 for my hypothesis, but I'm getting a little stuck on what to do after -- if I assume n = k, then: e <= (k+1)k/2. and if n = k+1 then e <= k(k-1)/2.
As I understand it, each vertex has n-1 possible edges coming out, and there are n total vertices, which is where n(n-1) comes from and dividing by 2 gets rid of the repeats. But I am unsure how I am to prove this.
The statement is false for multi-graphs. Take the graph:
/---\
O-----O
There are two vertices (O) and two edges; therefore n=2,e=2 and substituting into n(n-1)/2 <= e gives 1 <= 2 which is false.
However, if you restrict the graph to be simple - disallowing looping edges (where both ends of the edge terminate at the same vertex), multi-edges (where two edges connect the same pair of vertices) and that the graph is undirected - then the property holds.
Consider a complete graph K_n (with n vertices): each of the n vertices is incident to the other n-1 vertices via a connecting edge therefore there are n(n-1) connections from one vertex to another; given that edges are undirected then this will count each edge twice (i.e counting from vertex A to vertex B and vice versa) then the total number of edges will be n(n-1)/2.
Any graph G_n (with n vertices) will be a sub-graph of K_n (since you cannot add any more edges to K_n without creating multi- or looping edges) then there must be equal or fewer edges in G_n than in K_n.
Thus e <= n(n-1)/2 for all simple graphs.
If you further restrict the graph to be planar then you can state that e <= 3n - 6 (when n > 2).

Reducing independent set to clique?

Show that given a graph G and a number k, there is some way to transform it to a graph H such that G has an independent set of size of size at least k if and only if H has a clique of size at least k.
An independent set is a group of nodes where for any pair of nodes in the set, there is not an edge between those nodes. A clique is a group of nodes where for any pair of nodes in the set, there is an edge between those nodes. Therefore, an independent set in a graph G is a clique in the complement of G and vice-versa.
Given this, a simple transformation would be given G and k to produce Gc (the complement of G) and k. Then, G has an independent set of size k if and only if Gc has a clique of size k.
Hope this helps!

Proof that Dominating Set is NP-Complete

here is the question. I am wondering if there is a clear and efficient proof:
Vertex Cover: input undirected G, integer k > 0. Is there a subset of
vertices S, |S|<=k, that covers all edges?
Dominating Set: input undirected G, integer k > 0. Is there a subset of
vertices S, |S|<= k, that dominates all vertices?
A vertex covers it's incident edges and dominates it's neighbors and itself.
Assuming that VC is NPC, prove that DS is NPC.
There is a quite nice and well known reduction:
Given an instance (G,k) of Vertex Cover build an instance of Dominating Set (H,k), where for H you take G, remove all isolated vertices, and for every edge (u,v) add an additional vertex x connected to u and v.
First realize that a Vertex Cover of G is a Dominating Set of H: it's a DS of G (after removing isolated vertices), and the new vertices are also dominated. So if G has a VC smaller k, then H has a DS smaller k.
For the converse, consider D, a Dominating Set of H.
Notice that if one of the new vertices is in D, we can replace it with one of it's two neighbors and still get an Dominating Set: it's only neighbors are are the two original vertices and they are also connected - everything x can possible dominate is also dominated by u or v.
So we can assume that D contains only vertices from G. Now for every edge (u,v) in G the new vertex x is dominated by D, so either u or v is in D. But this means D is a Vertex Cover of G.
And there we have it: G has a Vertex Cover smaller k if and only if H has a Dominating Set smaller k.
Taken from :
CMSC 651 Advanced Algorithms , Lecturer Samir Khuller
I think that second problem is not NP.
Let's try the following algorithm.
1. Get the original Graph
2. Run any algorithm which checks if a graph is connected or not.
3. mark all used edges of step 2
4. if the graph is connected then return the set of marked edges otherwise there is no such a set.
If I understood correctly your problem then it is not NP Complete.

Resources