class ZipfEvenDriver(ArbitraryDriver):
    def __init__(self,
                 severity=2.0,
                 perturbate=0,
                 zipf_param=1.0001,
                 **kwargs):
        super(ZipfEvenDriver, self).__init__(**kwargs)
        self.zipf_item_gen = Zipfian_Generator(self.max_item, zipf_param)

        self.cost_power = severity * self.zipf_item_gen.theta

        self.perturbate = perturbate
        self.perturbed = []
        self.inner_max_cost = self.max_item**self.cost_power

    def get_cost(self, r_float, item):
        cost = (item**self.cost_power) / self.inner_max_cost

        if self.perturbate > 0:
            if len(self.perturbed) == 0:
                r = RandomState(self.permute_seed)
                self.perturbed = (
                    1.0 - (r.random_sample(self.max_item) * self.perturbate))

                #            item = float(self.perturbed[item] * item)
                cost *= float(self.perturbed[item])
        return cost

    def get_item(self, r_float):
        item, _ = self.zipf_item_gen.get_next(r_float)
        return item

    def get_item_pop(self, item):
        return self.zipf_item_gen.get_popularity(item)
class ZipfZipfDriver(ArbitraryDriver):
    def __init__(self, zipf_param=1.0001, **kwargs):
        super(ZipfZipfDriver, self).__init__(**kwargs)
        self.zipf_cost_gen = Zipfian_Generator(self.max_item, 1.0001)
        self.zipf_item_gen = Zipfian_Generator(self.max_item, zipf_param)

    def get_item(self, r_float):
        zipf_out, _ = self.zipf_item_gen.get_next(r_float)
        return zipf_out

    def get_item_pop(self, item):
        return self.zipf_item_gen.get_popularity(item)

    def get_cost(self, r_float, item_num):
        zipf_out, _ = self.zipf_cost_gen.get_next(r_float)
        return float(zipf_out) / self.max_item
class ZipfUniformDriver(ArbitraryDriver):
    def __init__(self, zipf_param=1.0001, **kwargs):
        super(ZipfUniformDriver, self).__init__(**kwargs)
        self.zipf_gen = Zipfian_Generator(self.max_item, zipf_param)
        self.costs = []

    def get_cost(self, r_float, item_num):
        if len(self.costs) == 0:
            r = RandomState(self.permute_seed)
            self.costs = r.random_sample(self.max_item)
        return float(self.costs[item_num])

    def get_item(self, r_float):
        zipf_out, _ = self.zipf_gen.get_next(r_float)
        return zipf_out

    def get_item_pop(self, item):
        return self.zipf_gen.get_popularity(item)
    def __init__(self,
                 severity=2.0,
                 perturbate=0,
                 zipf_param=1.0001,
                 **kwargs):
        super(ZipfEvenDriver, self).__init__(**kwargs)
        self.zipf_item_gen = Zipfian_Generator(self.max_item, zipf_param)

        self.cost_power = severity * self.zipf_item_gen.theta

        self.perturbate = perturbate
        self.perturbed = []
        self.inner_max_cost = self.max_item**self.cost_power
class UniformZipfDriver(ArbitraryDriver):
    def __init__(self, **kwargs):
        super(UniformZipfDriver, self).__init__(**kwargs)
        self.zipf_cost_gen = Zipfian_Generator(self.max_item, 1.0001)

    def get_item(self, r_float):
        return int(r_float * self.max_item)

    def get_cost(self, r_float, item):
        zipf_out, _ = self.zipf_cost_gen.get_next(r_float)
        return float(zipf_out) / self.max_item

    def get_item_pop(self, item):
        return 1.0 / self.max_item
 def __init__(self, zipf_param=1.0001, **kwargs):
     super(ZipfZipfDriver, self).__init__(**kwargs)
     self.zipf_cost_gen = Zipfian_Generator(self.max_item, 1.0001)
     self.zipf_item_gen = Zipfian_Generator(self.max_item, zipf_param)
 def __init__(self, zipf_param=1.0001, **kwargs):
     super(ZipfUniformDriver, self).__init__(**kwargs)
     self.zipf_gen = Zipfian_Generator(self.max_item, zipf_param)
     self.costs = []
 def __init__(self, **kwargs):
     super(UniformZipfDriver, self).__init__(**kwargs)
     self.zipf_cost_gen = Zipfian_Generator(self.max_item, 1.0001)