Какие категории комбинаторных задач появляются в разделе логических игр LSAT?

ИЗМЕНИТЬ: см. Решение проблемы, кому принадлежит Zebra программно? для аналогичного класса задач

В LSAT есть категория логических проблем, которая выглядит следующим образом:

Семь последовательных временных интервалов для трансляции, пронумерованных в хронологическом порядке от I до 7, будут заполнены шестью лентами с песнями - G, H, L, O, P, S - и ровно одной лентой новостей. Каждой ленте назначается отдельный временной интервал, и ни одна лента не длиннее любой другой ленты. Трансляция подчиняется следующим ограничениям:
L должна воспроизводиться непосредственно перед O.
Лента новостей должна воспроизводиться через некоторое время после L.
Должно быть ровно два временных интервала между G и P, независимо от того, идет ли G до P или G после P.

Я заинтересован в создании списка перестановок, удовлетворяющих условиям, как способ подготовки к тесту и как задача программирования. Однако я не уверен, что это за класс проблемы перестановки. Я обобщил проблему типов следующим образом:

Для массива A длиной n:

  1. Сколькими способами можно расположить набор из n уникальных элементов в пределах A? Например. Сколько существует способов переставить ABCDEFG?
  2. Если длина набора уникальных элементов меньше длины A, сколькими способами можно расположить набор внутри A, если элементы в наборе могут встречаться более одного раза? Например. ABCDEF => AABCDEF; ABBCDEF и др.
  3. Какими способами можно расположить набор уникальных элементов в пределах A, если элементы набора подпадают под «условия блокировки»?

Моя мысль - закодировать ограничения, а затем использовать что-то вроде itertools Python для генерации перестановок. Мысли и предложения приветствуются.


person Merjit    schedule 25.04.2010    source источник
comment
Что такое LSAT? Согласно Google, это вступительный тест юридических вузов, но в данном контексте это кажется маловероятным. Пожалуйста, не используйте непонятные сокращения, не объясняя их и не указывая URL.   -  person Dave Kirby    schedule 25.04.2010
comment
LSAT, о котором я говорю, действительно является вступительным экзаменом на юридический факультет. Один раздел состоит из логических игр, подобных той, о которой я упоминал выше. Моя цель - определить количество возможных решений для каждой головоломки.   -  person Merjit    schedule 25.04.2010


Ответы (2)


Итак, как я понимаю, есть два пути решения этой проблемы:

  1. Подумайте о написании программы, которая в первую очередь решит эту проблему. Это будет сложно.

  2. Но комбинаторика учит нас, что более простой способ сделать это - подсчитать все перестановки и вычесть те, которые не удовлетворяют вашим ограничениям.

Я бы выбрал номер 2.

Вы можете найти все перестановки данной строки или списка, используя этот алгоритм. Используя этот алгоритм, вы можете получить список всех перестановок. Теперь вы можете применить ряд фильтров к этому списку, проверив различные ограничения проблемы.

def L_before_O(s):
    return (s.index('L') - s.index('O') == 1)

def N_after_L(s):
    return (s.index('L') < s.index('N'))

def G_and_P(s):
    return (abs(s.index('G') - s.index('P')) == 2)

def all_perms(s):    #this is from the link
    if len(s) <=1:
        yield s
    else:
        for perm in all_perms(s[1:]):
            for i in range(len(perm)+1):
                yield perm[:i] + s[0:1] + perm[i:]

def get_the_answer():
    permutations = [i for i in all_perms('GHLOPSN')] #N is the news tape
    a = [i for i in permutations if L_before_O(i)]
    b = [i for i in a if N_after_L(i)]
    c = [i for i in b if G_and_P(i)]
    return c

Я не тестировал это, но это общее представление о том, как я буду писать такой вопрос.

Надеюсь это поможет

person inspectorG4dget    schedule 25.04.2010
comment
Это отличный ответ на вопросы 1 и 3 и элегантный способ кодирования ограничений игры! Тем не менее, я все еще в неведении относительно того, как подсчитывать перестановки в случае вопроса 2 - где вам разрешено удваивать переменные, чтобы заполнить количество доступных мест в матрице. - person Merjit; 25.04.2010
comment
Ну, программно вы можете просто выполнить len (c). Это вернет количество таких действительных перестановок. Однако, если ваш вопрос заключается в том, как мне это сделать вручную, я знаю, как это сделать, но не знаю, как написать это здесь. Разместите комментарий, сообщив мне, хотите ли вы этого, и в этом случае я сделаю это вручную на бумаге, отсканирую его, выложу на свой веб-сайт и опубликую здесь ссылку. - person inspectorG4dget; 26.04.2010
comment
Это именно то, что я ищу. Я использую это как возможность узнать об области математики, о которой я мало что знал раньше, поэтому любая дополнительная информация будет полезна. Меня особенно интересует проблема 2, потому что она часто возникает как загадка LSAT. Спасибо! - person Merjit; 27.04.2010
comment
Мне жаль, что прошло так много времени. Я не забыл о проблеме. Я решил эту проблему и теперь ищу сканер, которым можно было бы пользоваться. Надеюсь, я смогу загрузить это к понедельнику - person inspectorG4dget; 02.05.2010
comment
Спасибо! Я очень ценю это. - person Merjit; 03.05.2010
comment
Я написал ответ на двух листах бумаги, и их можно найти по адресу: индивидуальный. utoronto.ca/ashtopgun/Hobbyism/StackOverflow/ Это мой личный веб-сайт, и я был бы признателен за несколько посещений, если это не требует слишком многого. - person inspectorG4dget; 04.05.2010

Это легко решить (несколько строк кода) как целочисленную программу. Используя такой инструмент, как GNU Linear Programming Kit, вы декларативно указываете свои ограничения и пусть решатель найдет лучшее решение. Вот пример программы GLPK.

Вы можете закодировать это, используя язык программирования общего назначения, такой как Python, но именно такие вещи вы увидите в первых нескольких главах учебника по целочисленному программированию. Наиболее эффективные алгоритмы уже разработаны другими.

РЕДАКТИРОВАТЬ: чтобы ответить на вопрос Мерджита:

Определять:

  1. матрица Y, где Y_ (ij) = 1, если лента i воспроизводится перед лентой j, и 0 в противном случае.
  2. вектор C, где C_i указывает временной интервал, когда играется i (например, 1,2,3,4,5,6,7)
  3. Большая константа M (найдите термин "большой M" в учебнике по оптимизации)

Минимизируйте сумму вектора C при следующих ограничениях:

Y_(ij) != Y_(ji) // If i is before j, then j must not be before i
C_j < C_k + M*Y_(kj) // the time slot of j is greater than the time slot of k only if Y_(kj) = 1
C_O - C_L = 1 // L must be played immediately before O
C_N > C_L // news tape must be played at some time after L
|C_G - C_P| = 2 // You will need to manipulate this a bit to make it a linear constraint

Это должно помочь вам добраться до цели. Вы хотите записать указанные выше ограничения в синтаксисе языка MathProg (как показано в ссылках) и убедиться, что я не пропустил никаких ограничений. Затем запустите решатель GLPK для ограничений и посмотрите, что он даст.

person RexE    schedule 25.04.2010
comment
Я думаю, что целочисленное программирование, вероятно, лучший способ создать набор обобщенных решений для такого рода проблем, но я не уверен, как кодировать такую ​​игру с линейной сортировкой в ​​качестве проблемы оптимизации. Где / как мне разместить стоимостные коэффициенты? - person Merjit; 25.04.2010