Пример #1
0
def test_simple_strings():

    criteria = [['bad', 'good'], ['expensive', 'cheap']]
    alts = [('bad', 'cheap'), ('good', 'expensive'), ('bad', 'expensive')]

    def asker(a, b):
        # We prefer good to bad, but when that criterion is the same,
        # we prefer cheap to expensive.
        if a[0] == b[0]:
            if a[1] == b[1]:
                return EQ
            elif a[1] == 'cheap':
                return GT
            else:
                return LT
        elif a[0] == 'good':
            return GT
        else:
            return LT

    for find_best in (1, 2, None):
        prefs = vda(criteria=criteria,
                    alts=alts if find_best else None,
                    asker=asker,
                    find_best=find_best)
        assert prefs.maxes(among=alts) == {('good', 'expensive')}
        if find_best == 2:
            assert prefs.extreme(2, among=alts) == {('good', 'expensive'),
                                                    ('bad', 'cheap')}
        elif not find_best:
            assert prefs.maxes() == {('good', 'cheap')}
            ranking = (('bad', 'expensive'), ('bad', 'cheap'),
                       ('good', 'expensive'), ('good', 'cheap'))
            for (ai, a), (bi, b) in choose2(enumerate(ranking)):
                assert prefs.cmp(a, b) == Relation.cmp(ai, bi)
Пример #2
0
def test_appendixD():
    '''Appendix D of Larichev and Moshkovich (1995).'''

    criteria = [(3, 2, 1)] * 3
    # 3 is worst and 1 is best.
    alts = [(1, 2, 3), (2, 3, 1), (3, 1, 2)]
    dm_ranking = [(2, 1, 1), (1, 1, 2), (1, 2, 1), (1, 3, 1), (3, 1, 1),
                  (1, 1, 3)]

    # The first element is the best, so we negate `cmp` in the
    # asker.
    def asker(a, b):
        return -Relation.cmp(dm_ranking.index(a), dm_ranking.index(b))

    Proposal1, Proposal2, Proposal3 = alts

    for goal in ('find_best', 'rank_alts', 'rank_space'):
        prefs = vda(criteria=criteria,
                    alts=(None if goal == 'rank_alts' else alts),
                    asker=asker,
                    find_best=goal == 'find_best' and 1)
        assert prefs.maxes(among=alts) == {Proposal2}
        if goal == 'rank_alts':
            for v1, v2 in choose2(dm_ranking):
                assert prefs.cmp(v1, v2) == -Relation.cmp(
                    dm_ranking.index(v1), dm_ranking.index(v2))
        if goal != 'find_best':
            assert prefs.cmp(Proposal2, Proposal1) == GT
            assert prefs.cmp(Proposal2, Proposal3) == GT
            assert prefs.cmp(Proposal3, Proposal1) == GT
Пример #3
0
def test_one_criterion():
    '''When there's only one criterion, we should never need to ask
    questions, because the rule of dominance suffices to infer all
    preferences.'''

    for criterion_length in range(2, 10):
        prefs = artiruno.vda(criteria=[tuple(range(criterion_length))],
                             asker=asker_stub)
        for i, j in choose2(range(criterion_length)):
            assert prefs.cmp((i, ), (j, )) == LT
Пример #4
0
def test_extreme_n():
    x = PreorderedSet(l + str(i)
        for l in "wxyz"
        for i in range(3))
    for a, b in choose2(x.elements):
        x.learn(a, b, Relation.cmp(a[0], b[0]))

    assert (x.maxes() == x.extreme(2) == x.extreme(3) ==
        {"z0", "z1", "z2"})
    assert (x.extreme(4) == x.extreme(5) == x.extreme(6) ==
        {"z0", "z1", "z2", "y0", "y1", "y2"})
    def xb(n):
        return x.extreme(n, bottom = True)
    assert (x.mins() == xb(2) == xb(3) ==
        {"w0", "w1", "w2"})
    assert (xb(4) == xb(5) == xb(6) ==
        {"w0", "w1", "w2", "x0", "x1", "x2"})
Пример #5
0
    def out(criteria, run_slow_tests):
        if criteria in criteria_slow and not run_slow_tests:
            pytest.skip()

        questions_asked = 0
        expect_questions_asked = (inspect.signature(
            f).parameters['n_questions'].default)[criteria_all.index(criteria)]

        criteria = tuple(tuple(range(n)) for n in criteria)
        item_space = tuple(itertools.product(*criteria))

        for trial in range(trials):
            R = random.Random((criteria, trial))
            alts = R.sample(item_space, min(len(item_space), R.randint(2, 8)))
            find_best = R.choice([True, None])
            if find_best is True:
                find_best = R.choice([i for i in [1, 2, 3] if i < len(alts)])
            asker = f(criteria, R)

            def counting_asker(a, b):
                nonlocal questions_asked
                questions_asked += 1
                return asker(a, b)

            prefs = vda(criteria,
                        alts,
                        counting_asker,
                        find_best,
                        max_dev=2 * len(criteria))
            if find_best:
                assert prefs.extreme(find_best, among=alts) == {
                    a
                    for a in alts
                    for cmps in [Counter(asker(a, b) for b in alts)]
                    if cmps[IC] == 0 and cmps[LT] < find_best
                }
            else:
                for a, b in choose2(alts):
                    assert prefs.cmp(a, b) == asker(a, b)

        assert questions_asked == expect_questions_asked