Source code for cereeberus.data.ex_mergetrees


import networkx as nx
import numpy as np
import warnings

from networkx.generators import random_tree

from cereeberus import MergeTree




[docs] def randomMergeTree(n = 10, func_randomizer = None, range = [0,10], seed = None): """ Generates a random tree with n nodes + 1 root. If `func_randomizer` is None, the function defined is inverted edge count distance from root node. Otherwise, func_randomizer should be an input to type the randomizeMergeFunction function. For example, this could be 'uniform' or 'exp'. """ warnings.filterwarnings('ignore') # Generate a random tree T = nx.random_tree(n, seed = seed) np.random.seed(seed) root = np.random.randint(n) MT = MergeTree(T, root, seed = seed) if func_randomizer is not None: MT = randomizeMergeFunction(MT, type = func_randomizer, range = range, seed = seed) return MT
[docs] def randomizeMergeFunction(MT, range = [0,10], type = 'exp', seed = None): """ Returns a merge tree with the same underlying tree, but randomized function values in the given range. """ np.random.seed(seed) f = {'v_inf':np.inf} for e in nx.edge_bfs(MT.to_undirected(), 'v_inf'): u = e[0] v = e[1] bot_f = range[0] if u == 'v_inf': top_f = range[1] else: top_f = f[u] # Here's the main thing. # We pull a random number that's lower than the upper # neighbor's funciton value. # Doing this with uniform repeatedly makes for a squashed merge tree. # The expoenential function is a bit better. if type == 'uniform': f[v] = np.random.uniform(bot_f, top_f) elif type == 'exp': f[v] = top_f-np.random.exponential(.1*(top_f-bot_f)) if f[v] <bot_f: f[v] = bot_f MT.f = f MT.set_pos_from_f() return MT