diff --git a/greedy_qclq_mining.py b/greedy_qclq_mining.py
new file mode 100644
index 0000000000000000000000000000000000000000..f2a0d874003cec57ca7179a6e6a765b3b5cefc12
--- /dev/null
+++ b/greedy_qclq_mining.py
@@ -0,0 +1,122 @@
+from math import ceil
+
+def greedy_qclq(G,gamma,min_size):
+    
+    def is_quasi_clique(X):
+        "verify that X is a gamma quasi-clique of G"    
+
+        if len(X) < min_size:
+            return False
+        
+        threshold = ceil(gamma*(len(X)-1))
+        
+        for u in X:
+            d_X_u = len(set(X) & set(G[u]))
+            if d_X_u < threshold:
+                return False
+        
+        return True
+
+    def neighbourhood(v, k):
+        "compute the list of vertices k hops a far from v"
+        
+        dist = {}
+        
+        for u in G.nodes:
+            dist[u] = -1
+        dist[v] = 0
+        l = [v]
+        N_k_v = []
+        
+        while len(l)>0:
+            
+            u = l.pop(0)
+            N_k_v.append(u)
+            
+            if dist[u]<k:
+                for u2 in G[u]:
+                    if dist[u2] == -1:
+                        l.append(u2)
+                        dist[u2] = dist[u]+1
+        
+        return N_k_v
+    
+    def new_node(K, cand_exts, n_K, m_K):
+    
+        flag = False
+        v = 0
+        ngb_v_in_K = []
+        max_unmarked_edges = 0
+        
+        for i in cand_exts:
+            
+            ngb_i_in_K = set(G[i]) & set(K)
+            #m_i_K = len(ngb_i_in_K)
+            
+            nb_new_unmarked_edges = 0
+            for k in ngb_i_in_K:
+                if G.edges[(i,k)]['unmarked']:
+                    nb_new_unmarked_edges += 1
+    
+            if (is_quasi_clique(K+[i])) and (nb_new_unmarked_edges > max_unmarked_edges):    
+                flag = True
+                v = i
+                ngb_v_in_K = ngb_i_in_K
+                max_unmarked_edges = nb_new_unmarked_edges
+        
+        return flag, v, ngb_v_in_K
+    
+    Quasi_Cliques = []
+    
+    for (u,v) in G.edges:
+        w_abs = len(set(G[u]) & set(G[v]))
+        G.edges[(u,v)]['unmarked'] = True
+        G.edges[(u,v)]['w_abs'] = w_abs
+    
+    unmarked_edges = list(G.edges)
+    unmarked_edges.sort(key=lambda e: G.edges[e]['w_abs'], reverse=True)
+    
+    while len(unmarked_edges)>0:
+        (u,v) = unmarked_edges.pop(0)
+        
+        cand_exts = set(neighbourhood(u,2))
+        cand_exts.remove(u)
+        K = [u]
+        n_K = 1
+        m_K = 0
+        
+        flag = True
+        ngb_v_in_K = [u]
+        
+        while flag:
+            cand_exts = cand_exts & set(neighbourhood(v,2))
+            #print(u,v,cand_exts)
+            cand_exts.remove(v)
+            K.append(v)
+            n_K += 1
+            m_K += len(ngb_v_in_K)
+            
+            for u in ngb_v_in_K:
+                try:
+                    G.edges[u,v]['unmarked'] = False
+                except:
+                    pass
+                try:
+                    unmarked_edges.remove((v,u))
+                except:
+                    try:
+                        unmarked_edges.remove((u,v))
+                    except:
+                        pass
+            
+            flag, v, ngb_v_in_K = new_node(K, cand_exts, n_K, m_K)
+        
+        if len(K) >= min_size:
+            Quasi_Cliques.append(K)
+    
+    return Quasi_Cliques
+    
+            
+            
+            
+            
\ No newline at end of file