from matplotlib import pyplot as plt import random import math import itertools def generate_hypergraph(n=6, number_of_edges=None, k=3): vertices = range(1, n + 1) if number_of_edges is None: number_of_edges = int(math.sqrt(n)) hyper_edges = random.sample(list(itertools.combinations(vertices, k)), number_of_edges) return (vertices, hyper_edges) g = generate_hypergraph(number_of_edges=8) import networkx as nx def convert_to_nx_biparty_graph(vertices, hyper_edges): G = nx.Graph() G.add_nodes_from(vertices) G.add_nodes_from(hyper_edges) for e in hyper_edges: for n in e: G.add_edge(n, e) return G G = convert_to_nx_biparty_graph(*g) %matplotlib inline nx.draw(G) nx.draw(G,pos=nx.spring_layout(G, iterations=200)) from networkx.algorithms import bipartite def draw_bipartite_graph(G, group_1, group_2): pos = {x:(0 , float(i % 20) * 2) for i, x in enumerate(group_1)} pos.update({node: (18.3, 0 + float(i % 20) * 2) for i, node in enumerate(group_2)}) nx.draw(G, pos, node_color='m', node_size=800, with_labels=True, width=1.3, alpha=0.4) def hipergraph_to_bipartite_parts(G): group_1 = (node for node in G.nodes() if not isinstance(node, tuple)) group_2 = (node for node in G.nodes() if isinstance(node, tuple)) return group_1, group_2 draw_bipartite_graph(G, *hipergraph_to_bipartite_parts(G)) hyper_edges = g[1] hyper_edges from itertools import chain def convert_to_custom_hyper_G(nodes, edges): nodes = [node for node in edges if isinstance(node, tuple)] edges = list(chain(*[[(node_1, node_2) for x in range(len(set(node_1) & set(node_2)))] for node_1, node_2 in itertools.combinations(edges, 2) if set(node_1) & set(node_2)])) hyper_G = nx.Graph() hyper_G.add_nodes_from(nodes) hyper_G.add_edges_from(edges) return hyper_G %matplotlib inline hyper_G = convert_to_custom_hyper_G(*g) nx.draw(hyper_G, layout=nx.circular_layout(G), node_size=3000, node_color='g', alpha=0.5) nx.degree(hyper_G) nx.adjacency_matrix(hyper_G) nx.incidence_matrix(hyper_G) import numpy as np from matplotlib import pyplot as plt from collections import Counter def show_different_hipergraphs(n=10, k=3, parts=10): for fraction in np.linspace(0, 1, parts)[1:]: plt.figure(figsize=(6, 6)) g = generate_hypergraph(n=n, k=k, number_of_edges=int(n * fraction)) G = convert_to_nx_biparty_graph(*g) draw_bipartite_graph(G, *hipergraph_to_bipartite_parts(G)) hyper_G = convert_to_custom_hyper_G(*g) p=nx.degree(hyper_G) plt.figure(figsize=(6, 6)) nx.draw( hyper_G, node_color=p.values(), node_size=3000, cmap=plt.cm.Blues, alpha=0.6 ) show_different_hipergraphs(10, 3, 4) A = np.array([[1, 2], [2, 0]]) min(A.sum(axis=0)) def create_balanced_markov_matrix(edges): a_matrix = np.zeros([len(edges), len(edges)]) * 10 for i, edge_1 in enumerate(edges): for j, edge_2 in enumerate(edges): a_matrix[i][j] = len(set(edge_1) & set(edge_2)) a_matrix[j][i] = a_matrix[i][j] sums = a_matrix.sum(axis=0) min_sum = min(sums) for i, col_sum in enumerate(sums): a_matrix[i][i] -= col_sum - min_sum a_matrix *= 1.0 /min_sum return a_matrix def create_markov_matrix(edges): a_matrix = np.eye(len(edges)) for i, edge_1 in enumerate(edges): for j, edge_2 in enumerate(edges): a_matrix[i][j] = len(set(edge_1) & set(edge_2)) a_matrix[j][i] = a_matrix[i][j] for i, edge_1 in enumerate(edges): a_matrix[i] = a_matrix[i] / sum(a_matrix[i]) * 1.1 return a_matrix create_markov_matrix(g[1]) import numpy as np from numpy.random import random_sample def weighted_values(values, probabilities, size): bins = np.add.accumulate(probabilities) bins[-1] = max(1, bins[-1]) index = np.digitize(random_sample(size), bins) return values[index] def step_diffusion(current_state, markov_matrix): values_size = len(current_state) values = range(values_size) probs = markov_matrix.dot(current_state) next_state = np.zeros(values_size) next_state[weighted_values(values, probs, 1)] = 1 return next_state markov_matrix = create_markov_matrix(g[1]) current_state = np.zeros(markov_matrix.shape[0]) current_state[0] = 1 print(current_state) print(markov_matrix) current_state[0] = 1 from collections import Counter c = Counter() states = [] t_max = 30 for _ in range(t_max): current_state = step_diffusion(current_state, markov_matrix) visited_hyperedge = current_state.tolist().index(1) c[visited_hyperedge] += 1 states.append(visited_hyperedge) c.most_common() y, x = c.keys(), c.values() print(list(x), y) from matplotlib import pyplot as plt plt.hist(states, normed=True) g[1][3] n = 20 k = 3 fraction = 1.0 / 2 g = generate_hypergraph(n=n, k=k, number_of_edges=int(n * fraction)) G = convert_to_nx_biparty_graph(*g) draw_bipartite_graph(G, *hipergraph_to_bipartite_parts(G)) hyper_G = convert_to_custom_hyper_G(*g) print("Hyperg") print(hyper_G) p=nx.degree(hyper_G) plt.figure(figsize=(6, 6)) markov_matrix = create_markov_matrix(g[1]) print markov_matrix print g[1] from collections import Counter current_state = np.zeros(markov_matrix.shape[0]) t_max = 100000 current_state[2] = 1 def simulate(current_state, markov_matrix, t_max): c = Counter() states = [] for _ in xrange(t_max): current_state = step_diffusion(current_state, markov_matrix) visited_hyperedge = current_state.tolist().index(1) c[visited_hyperedge] += 1 states.append(visited_hyperedge) return c.most_common(), states most_common, states = simulate(current_state, markov_matrix, t_max) print markov_matrix print most_common plt.hist(states, alpha=.5); def count_nodes(nodes, edges, occurences): c = Counter() for index, count in occurences: for edge in edges[index]: c[edge] += count for node in nodes: if node not in c: c[node] = 0 return c most_common_nodes = count_nodes(g[0], g[1], most_common) plt.plot( most_common_nodes.keys(), most_common_nodes.values(), 'm:o', alpha=0.7, linewidth=5 )