def random_almost_equi_partitions_with_walk(graph, num_partitions, num_blocks, delta, step = "Basis", jump_size = 50):
    '''This produces a delta almost equi partition... it keeps looping until it finds
    the required amounts
    
    '''
#    print("am here")
#    print(step)
    found_partitions = []
    counter = 0
    tree = random_spanning_tree_wilson(graph)
    while len(found_partitions) < num_partitions:
        counter += 1
        if step == "Basis":
            for i in range(jump_size):
                tree, edge_to_remove, edge_to_add = propose_step(graph, tree)
        if step == "Broder":
            for i in range(jump_size):
                tree, edge_to_remove, edge_to_add = propose_Broder_step(graph, tree)
        edge_list = almost_equi_split(tree, num_blocks, delta)
        #If the almost equi split was not a delta split, then it returns none...
        if edge_list != None:
            blocks = remove_edges_map(graph, tree, edge_list)
            found_partitions.append(blocks)
            print(len(found_partitions), "waiting time:", counter)
            counter = 0
    return found_partitions
def random_equi_partitions(graph, num_partitions, num_blocks, algorithm = "Wilson"):
    '''
    Here is the code that makes equi partitions.
    
    :graph:
    :num_partitions:
    :num_blocks: Number of blocks in each partition
    
    
    
    '''
    found_partitions = []
    counter = 0
    while len(found_partitions) < num_partitions:
        counter += 1
        if algorithm == "Broder":
            tree = random_spanning_tree(graph)    
        if algorithm == "Wilson":
            tree = random_spanning_tree_wilson(graph)
        if algorithm == "MST":
            for edge in graph.edges():
                graph.edges[edge]["weight"] = np.random.uniform(0,1)
            #Do we need to reset this each time?
            tree = nx.minimum_spanning_tree(graph)
        edge_list = equi_split(tree, num_blocks)
        #edge_list will return None if there is no equi_split
        if edge_list != None:
            found_partitions.append(remove_edges_map(graph, tree, edge_list))
            print(len(found_partitions), "waiting time:", counter)
            counter = 0
            #keeps track of how many trees it went through to find the one
            #that could be equi split
    return found_partitions
def random_almost_equi_partitions(graph, num_partitions, num_blocks, delta):
    '''This produces a delta almost equi partition... it keeps looping until it finds
    the required amounts
    
    '''
    found_partitions = []
    counter = 0
    while len(found_partitions) < num_partitions:
        counter += 1
        tree = random_spanning_tree_wilson(graph)
        edge_list = almost_equi_split(tree, num_blocks, delta)
        #If the almost equi split was not a delta split, then it returns none...
        if edge_list != None:
            blocks = remove_edges_map(graph, tree, edge_list)
            found_partitions.append(blocks)
            print(len(found_partitions), "waiting time:", counter)
            counter = 0
    return found_partitions
                    M[index_2, index_1] = -1
                #th

    return M


def geq(tree, a, b):
    '''
    tests whether a > b in the directedtree tree
    maybe we just use this?
    '''
    while list(tree.out_edges(a)) != []:
        '''
        this is the right direction to set this up in, because our tree have only one outgoing edge per vertex
        '''
        a = list(tree.out_edges(a))[0][1]
        if a == b:
            return True
    return False


graph = nx.grid_graph([160, 160])
for vertex in graph:
    graph.node[vertex]["POP10"] = 1

for i in range(15):
    tree = random_spanning_tree_wilson(graph)
    print(random_split_fast(graph, tree, 16, .2, 50))

#They get super rare... which is why it's important to use the divide and conquer algorithm. Divide and conquer biases the distribution on spanning trees towards those which can be split. Can we analyze the way in which it does so?