def weighted_random_sample_no_replacement(population, weights,
                                              num_samples):
        """
        Samples num_samples from population given the weights

        :param population: a list of things to sample from
        :param weights: weights that bias the sampling from the population
        :param num_samples: how many objects to sample
        :return: a list containing num_samples sampled objects
        """

        elt = \
            [(math.log(random.random()) / weights[i], i)
             for i in range(len(weights))]
        return [population[i[1]] for i in heapq.nlargest(num_samples, elt)]

        Samples num_samples from population given the weights

        :param population: a list of things to sample from
        :param weights: weights that bias the sampling from the population
        :param num_samples: how many objects to sample
        :return: a list containing num_samples sampled objects
        
plato/agent/component/user_simulator/goal.py