def _generate_min_degree(gamma, average_degree, max_degree, tolerance, max_iters): """Returns a minimum degree from the given average degree.""" # Defines zeta function whether or not Scipy is available try: from scipy.special import zeta except ImportError: def zeta(x, q): return _hurwitz_zeta(x, q, tolerance) min_deg_top = max_degree min_deg_bot = 1 min_deg_mid = (min_deg_top - min_deg_bot) / 2 + min_deg_bot itrs = 0 mid_avg_deg = 0 while abs(mid_avg_deg - average_degree) > tolerance: if itrs > max_iters: raise nx.ExceededMaxIterations("Could not match average_degree") mid_avg_deg = 0 for x in range(int(min_deg_mid), max_degree + 1): mid_avg_deg += (x ** (-gamma + 1)) / zeta(gamma, min_deg_mid) if mid_avg_deg > average_degree: min_deg_top = min_deg_mid min_deg_mid = (min_deg_top - min_deg_bot) / 2 + min_deg_bot else: min_deg_bot = min_deg_mid min_deg_mid = (min_deg_top - min_deg_bot) / 2 + min_deg_bot itrs += 1 # return int(min_deg_mid + 0.5) return round(min_deg_mid)
def _powerlaw_sequence(gamma, low, high, condition, length, max_iters, seed): """Returns a list of numbers obeying a constrained power law distribution. ``gamma`` and ``low`` are the parameters for the Zipf distribution. ``high`` is the maximum allowed value for values draw from the Zipf distribution. For more information, see :func:`_zipf_rv_below`. ``condition`` and ``length`` are Boolean-valued functions on lists. While generating the list, random values are drawn and appended to the list until ``length`` is satisfied by the created list. Once ``condition`` is satisfied, the sequence generated in this way is returned. ``max_iters`` indicates the number of times to generate a list satisfying ``length``. If the number of iterations exceeds this value, :exc:`~networkx.exception.ExceededMaxIterations` is raised. seed : integer, random_state, or None (default) Indicator of random number generation state. See :ref:`Randomness<randomness>`. """ for i in range(max_iters): seq = [] while not length(seq): seq.append(_zipf_rv_below(gamma, low, high, seed)) if condition(seq): return seq raise nx.ExceededMaxIterations("Could not create power law sequence")
def generateConnexe(longueur, largeur, probarete, limite, fonctionpoids, parampoids): i = 0 g = generate(longueur, largeur, probarete, fonctionpoids, parampoids) while not (nx.is_connected(g)) and i < limite: i += 1 g = generate(longueur, largeur, probarete, fonctionpoids, parampoids) if nx.is_connected(g): return g else: raise nx.ExceededMaxIterations('Pas de graphe connexe généré avant ' + str(limite) + ' itérations') return
def _generate_communities(degree_seq, community_sizes, mu, max_iters, seed): """Returns a list of sets, each of which represents a community in the graph. ``degree_seq`` is the degree sequence that must be met by the graph. ``community_sizes`` is the community size distribution that must be met by the generated list of sets. ``mu`` is a float in the interval [0, 1] indicating the fraction of intra-community edges incident to each node. ``max_iters`` is the number of times to try to add a node to a community. This must be greater than the length of ``degree_seq``, otherwise this function will always fail. If the number of iterations exceeds this value, :exc:`~networkx.exception.ExceededMaxIterations` is raised. seed : integer, random_state, or None (default) Indicator of random number generation state. See :ref:`Randomness<randomness>`. The communities returned by this are sets of integers in the set {0, ..., *n* - 1}, where *n* is the length of ``degree_seq``. """ # This assumes the nodes in the graph will be natural numbers. result = [set() for _ in community_sizes] n = len(degree_seq) free = list(range(n)) for i in range(max_iters): v = free.pop() c = seed.choice(range(len(community_sizes))) # s = int(degree_seq[v] * (1 - mu) + 0.5) s = round(degree_seq[v] * (1 - mu)) # If the community is large enough, add the node to the chosen # community. Otherwise, return it to the list of unaffiliated # nodes. if s < community_sizes[c]: result[c].add(v) else: free.append(v) # If the community is too big, remove a node from it. if len(result[c]) > community_sizes[c]: free.append(result[c].pop()) if not free: return result msg = 'Could not assign communities; try increasing min_community' raise nx.ExceededMaxIterations(msg)
def _generate_min_degree(gamma, average_degree, max_degree, tolerance, max_iters): """Returns a minimum degree from the given average degree.""" min_deg_top = max_degree min_deg_bot = 1 min_deg_mid = (min_deg_top - min_deg_bot) / 2 + min_deg_bot itrs = 0 mid_avg_deg = 0 while abs(mid_avg_deg - average_degree) > tolerance: if itrs > max_iters: raise nx.ExceededMaxIterations("Could not match average_degree") mid_avg_deg = 0 for x in range(int(min_deg_mid), max_degree + 1): mid_avg_deg += (x ** (-gamma + 1)) / zeta(gamma, min_deg_mid, tolerance) if mid_avg_deg > average_degree: min_deg_top = min_deg_mid min_deg_mid = (min_deg_top - min_deg_bot) / 2 + min_deg_bot else: min_deg_bot = min_deg_mid min_deg_mid = (min_deg_top - min_deg_bot) / 2 + min_deg_bot itrs += 1 return round(min_deg_mid)
def _generate_communities(degree_seq, community_sizes, lab_coms, mu, labels, noise, std, max_iters, seed, type_attr): """Returns a list of sets, each of which represents a community. ``degree_seq`` is the degree sequence that must be met by the graph. ``community_sizes`` is the community size distribution that must be met by the generated list of sets. ``mu`` is a float in the interval [0, 1] indicating the fraction of intra-community edges incident to each node. ``max_iters`` is the number of times to try to add a node to a community. This must be greater than the length of ``degree_seq``, otherwise this function will always fail. If the number of iterations exceeds this value, :exc:`~networkx.exception.ExceededMaxIterations` is raised. seed : integer, random_state, or None (default) Indicator of random number generation state. See :ref:`Randomness<randomness>`. The communities returned by this are sets of integers in the set {0, ..., *n* - 1}, where *n* is the length of ``degree_seq``. """ card_lab = [] for lb in labels: if lb == "auto": # number of labels equal to the number of communities card_lab.append([i for i in range(1, len(community_sizes) + 1)]) else: card_lab.append([i for i in range(1, lb + 1)]) # This assumes the nodes in the graph will be natural numbers. result = [set() for _ in community_sizes] n = len(degree_seq) lab_nodes = [list(range(n)) for i in range(len(card_lab))] free = list(range(n)) for i in range(max_iters): v = free.pop() c = random.choice(range(len(community_sizes))) # s = int(degree_seq[v] * (1 - mu) + 0.5) s = round(degree_seq[v] * (1 - mu)) # If the community is large enough, add the node to the chosen # community. Otherwise, return it to the list of unaffiliated nodes. if s < community_sizes[c]: result[c].add(v) if type_attr == "continuous": for j, attr in enumerate(lab_coms): lab_nodes[j][v] = float(np.random.normal(attr[c], std, 1)) #lab_nodes[j][v] = round(float(np.random.normal(attr[c], std, 1))) #if categorical else: for j, attr in enumerate(lab_coms): if random.uniform(0, 1) < 1 - noise: lab_nodes[j][v] = attr[c] else: l = random.choice(card_lab[j]) lab_nodes[j][v] = l # copy_card_lab = copy.copy(card_lab) # copy_card_lab.remove(lab_coms[c]) # l = random.choice(copy_card_lab) else: free.append(v) # If the community is too big, remove a node from it. if len(result[c]) > community_sizes[c]: free.append(result[c].pop()) if not free: return lab_nodes, result msg = 'Could not assign communities' raise nx.ExceededMaxIterations(msg)