def rbo_score(ground_truth, simulation, p=0.95):
    """
    Rank biased overlap (RBO) implementation
    http://codalism.com/research/papers/wmz10_tois.pdf
    A ranked list comparison metric which allows non-overlapping lists

    Inputs:
    ground_truth - ground truth data
    simulation - simulation data
    p - RBO parameter ranging from 0 to 1 that determines how much to overweight the the upper portion of the list
        p = 0 means only the first element is considered
        p = 1 means all ranks are weighted equally
    """


    if simulation is None:
        return None

    try:
        ground_truth = ground_truth.index.tolist()
        simulation = simulation.index.tolist()
    except:
        ''

    sl, ll = sorted([(len(ground_truth), ground_truth), (len(simulation), simulation)])
    s, S = sl
    l, L = ll
    if s == 0: return 0

    # Calculate the overlaps at ranks 1 through s
    # (the shorter of the two lists)

    x_d = {}
    rbo_score = 0.0

    for i in range(1, s + 1):
        x = L[:i]
        y = S[:i]

        x_d[i] = len(set(x).intersection(set(y)))


    for i in range(1,s+1):
        rbo_score += (float(x_d[i])/float(i)) * pow(p, (i-1))


    rbo_score = rbo_score * (1 - p)

    return rbo_score