def molloy_reed(degree_sequence, node_names=None, self_loops=True): """ Generates a random undirected network with a given degree sequence. The generated network is guaranteed to have the given degree sequence. Multiple edges are forbidden in the network generation. Raises an exception if the given degree sequence is not graphic, i.e. if no possible simple graph exisits with the desired degree sequence. Parameters: ----------- degree_sequence: list or tuple The degree sequence of the randomly generated network. The degree sequence must have at least two entries. The sequence must be graphic, or an exception will be raised. node_names: list or tuple Node names to be used in the network creation. If None (default) nodes will be numbered from 0 to n-1, where n is the length of the degree sequence. self_loops: bol Whether or not to allow the generation of self_loops. Default is True. """ assert is_graphic_sequence( degree_sequence, directed=False), 'Error: degree sequence is not graphic' n = len(degree_sequence) if node_names is None: node_names = [str(x) for x in range(n)] assert len( node_names ) >= n, 'Error: Number of node names not matching degree sequence length' network = Network(directed=False) # generate a list with node stubs stubs = [] for i in range(n): for j in range(degree_sequence[i]): stubs.append(str(node_names[i])) while len(stubs) > 1: random_nodes = _np.random.choice(stubs, size=2, replace=False) (v, w) = (random_nodes[0], random_nodes[1]) if (v, w) not in network.edges and (self_loops or v != w): network.add_edge(v, w) stubs.remove(v) if v != w: # ensures that self-loops are counted as degree 1 stubs.remove(w) elif network.ecount() > 0: # randomly remove edge edges = list(network.edges) edge = edges[_np.random.choice(len(edges))] network.remove_edge(edge[0], edge[1]) stubs.append(edge[0]) stubs.append(edge[1]) return network
def erdoes_renyi_gnm(n, m, node_names=None, self_loops=True, directed=False, temporal=False): """ """ if node_names is None: node_names = [str(x) for x in range(n)] assert len( node_names ) >= n, 'Error: Number of node names not matching degree sequence length' if not temporal: network = Network(directed=directed) else: network = TemporalNetwork() # generate nodes if not temporal: for i in range(n): network.add_node(str(node_names[i])) time = -1 m_current = 0 edges = defaultdict(lambda: False) # add edges while m_current < m: edge = _np.random.choice(n, size=2, replace=self_loops) edge = [node_names[edge[0]], node_names[edge[1]]] if not edges[(edge[0], edge[1])]: edges[(edge[0], edge[1])] = True if not directed: edges[(edge[1], edge[0])] = True if not temporal: m_current += 1 network.add_edge(edge[0], edge[1]) else: time += 1 m_current += 1 network.add_edge(edge[0], edge[1], time, directed=directed) return network
def __next__(self): if self.current_time+self.window_size <= self.max_time: time_window = [self.current_time, self.current_time+self.window_size] n = Network.from_temporal_network(self.temporal_network, min_time=self.current_time, max_time=self.current_time+self.window_size, directed=self.directed) self.current_time += self.step_size if self.return_window: return n, time_window else: return n else: raise StopIteration()
def erdoes_renyi_gnp(n, p, node_names=None, self_loops=True, directed=False, temporal=False): """ """ if node_names is None: node_names = [str(x) for x in range(n)] assert len( node_names ) >= n, 'Error: Number of node names not matching degree sequence length' if not temporal: network = Network(directed=directed) else: network = TemporalNetwork() # make sure that isolated nodes exist if not temporal: for i in range(n): network.add_node(str(node_names[i])) time = -1 # add edges for i in range(n): for j in range(i + 1): if i != j or self_loops: if _np.random.rand() <= p: if not temporal: network.add_edge(node_names[i], node_names[j]) else: time += 1 network.add_edge(node_names[i], node_names[j], time, directed=directed) return network
def barabasi_albert(n, n_init, k=1, node_names=None, directed=False, temporal=False): """ """ if node_names is None: node_names = [str(x) for x in range(n)] assert len( node_names ) >= n, 'Error: Number of node names not matching degree sequence length' if not temporal: network = Network(directed=directed) else: network = TemporalNetwork() endpoints = [] time = 0 # initial network for i in range(n_init): for j in range(n_init): if i < j: if not temporal: network.add_edge(str(node_names[i]), str(node_names[j])) else: network.add_edge(str(node_names[i]), str(node_names[j]), time, directed=directed) endpoints.append(str(node_names[i])) endpoints.append(str(node_names[j])) for i in range(n_init, n): time += 1 # TODO: for k>1 we can choose different stubs of the same node in one step! targets = _np.random.choice(endpoints, size=k, replace=False) for t in targets: if not temporal: network.add_edge(str(node_names[i]), t) else: network.add_edge(str(node_names[i]), t, time, directed=directed) endpoints.append(str(node_names[i])) endpoints.append(t) return network