def solve(Xs_info, C, aa, f_cost, epsilon):
    """
    Args:
        Xs_info: map from distribution to tuple of type (probe cost, p_ij)
        C: the cost budget
        aa: the values taken on by the distribution
        epsilon: the epsilon 
    """
    # Compute interval lengths. Note that I_i = [a_j, a_{j + 1}].
    assert len(set(aa)) == len(aa), \
        'The values taken on by the distribution must be distinct'
    assert all(itertools.imap(lambda a: a >= 0, aa)), \
        'The values taken on by the distribution must be nonnegative'

    
    ls = [t - s for s, t in zip(aa, aa[1:])]
    cs, ps = zip(*Xs_info.itervalues())
    z, ys, problem = lp(cs, C, ls, ps)

    print problem

    problem.solve()

    print 'z = {}, ys = {}'.format(z.value(), [y.value() for y in ys])

    # The subset S corresponding to i s.t. y_i = 1 is feasible
    s0 = [x for x, y in zip(Xs_info.iterkeys(), ys) if y.value() == 1]
    # new cost budget C(log log m + log 1/e)
    m = len(aa)
    C_relaxed = C * (math.log(math.log(m)) + math.log(1.0 / epsilon))

    X_cost = {k: c for k, (c, _) in Xs_info.iteritems()}
    return minimum_element.minimum_element(X_cost, C_relaxed, f_cost, S_0=s0)
def do_uniform(C, n, m, sims):
    """
    Args:
        C: the cost budget
        n: the number of random variables
        m: the number of elements taken on by the distributions
    """
    with open(OUTPUT_FILE, 'w') as f:
        ties = 0
        cip_victories = 0
        basic_victories = 0
        for _ in xrange(sims):
            Xs_info = {}
            elements = range(0, 500 * int(math.pow(m, 2)), 500)
            for i in xrange(n):
                x = stats.rv_discrete(
                    values=(elements,
                            [1.0 / len(elements) for _ in xrange(len(elements))]))
                # x = stats.randint(0, m + 1)
                # x = stats.geom(1. / 17)
                # x = stats.poisson(0.6)
                c = random.randint(1, C / (n / 2))
                Xs_info['x' + str(i)] = (x, c, lambda a: x.sf(a))

            f_cost = lambda S: len(S) + 1

            Xs_dist = {k: d for k, (d, _, _) in Xs_info.iteritems()}
            xs = simulate(Xs_dist)

            Xs_cip_info = {k: (c, p) for k, (_, c, p) in Xs_info.iteritems()}
            cip_result = cip_greedy.solve(Xs_cip_info, C, elements, f_cost, 0.01)
            cip_cost = sum(map(lambda x: xs[x], cip_result))
            print 'cip =', cip_cost,

            X_cost = {k: c for k, (_, c, _) in Xs_info.iteritems()}
            basic_result = minimum_element.minimum_element(X_cost, C, f_cost)
            basic_cost = sum(map(lambda x: xs[x], basic_result))
            print ', basic =', basic_cost

            if cip_cost < basic_cost:
                f.write('cip\n')
                cip_victories += 1
            elif cip_cost == basic_cost:
                f.write('tie\n')
                ties += 1
            else:
                f.write('basic\n')
                basic_victories += 1

        f.write('cip: {}, basic: {}, ties: {}\n'.format(
            cip_victories, basic_victories, ties))
 def test_general_case(self):
     arr = [4, 3, 5, 2, 1, 6]
     self.assertEqual(minimum_element(arr), 4)
 def test_empty_list(self):
     arr = []
     with self.assertRaises(ValueError):
         minimum_element(arr)
 def test_singleton_list(self):
     arr = [5]
     self.assertEqual(minimum_element(arr), 0)
 def test_duplicate_minimum_elements(self):
     arr = [3, 4, 2, 5, 2, 6]
     self.assertEqual(minimum_element(arr), 2)
 def test_first_element_is_minimum(self):
     arr = [1, 3, 6, 5, 3, 4]
     self.assertEqual(minimum_element(arr), 0)