Подтвердить что ты не робот

Проблема динамического программирования

Это тонированная версия проблемы компьютерного зрения, которую мне нужно решить. Предположим, что вам заданы параметры n, q и приходится подсчитывать количество способов назначения целых чисел 0.. (q-1) элементам сетки n-на-n, так что для каждого присваивания все истинно

  • Нет двух соседей (по горизонтали или по вертикали), получающих одинаковое значение.
  • Значение в позициях (i, j) равно 0
  • Значение в позиции (k, l) равно 0

Так как (i, j, k, l) не заданы, вывод должен быть массивом оценок выше, по одному для каждой допустимой установки (i, j, k, l)

Ниже приведен грубый подход. Цель состоит в том, чтобы получить эффективный алгоритм, который работает для q <= 100 и для n <= 18.

def tuples(n,q):
  return [[a,]+b for a in range(q) for b in tuples(n-1,q)] if n>1 else [[a] for a in range(q)]

def isvalid(t,n):
  grid=[t[n*i:n*(i+1)] for i in range(n)];
  for r in range(n):
    for c in range(n):
      v=grid[r][c]
      left=grid[r][c-1] if c>0 else -1
      right=grid[r][c-1] if c<n-1 else -1
      top=grid[r-1][c] if r > 0 else -1
      bottom=grid[r+1][c] if r < n-1 else -1
      if v==left or v==right or v==top or v==bottom:
        return False
  return True

def count(n,q):
  result=[]
  for pos1 in range(n**2):
    for pos2 in range(n**2):
      total=0
      for t in tuples(n**2,q):
        if t[pos1]==0 and t[pos2]==0 and isvalid(t,n):
          total+=1

      result.append(total)

  return result

assert count(2,2)==[1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1]

Обновление 11/11 Я также спросил об этом на TopCoder forums, и их решение является наиболее эффективным из того, что я видел до сих пор (около 3 часов для n = 10, любой q, по оценке автора)

4b9b3361

Ответ 1

Возможно, это звучит слишком просто, но это работает. Случайно распределяйте значения во все ячейки до тех пор, пока только два не будут пустыми. Проверка смежности всех значений. Вычислите средний процент успешных бросков против всех бросков, пока дисперсия не упадет с приемлемым пределом.

Риск падает до нуля, а риск, который находится под угрозой, - это лишь небольшое время выполнения.

Ответ 2

Это не ответ, просто вклад в обсуждение, слишком длинное для комментария.

TL;DR; Любой алгоритм, который сводится к "вычислению возможностей и подсчетам", например, Эрик Липперт или подход грубой силы, не будет работать для целей @Ярослава q <= 100 и n <= 18.

Сначала подумайте об одном столбце n x 1. Сколько допустимых номеров этого столбца существует? Для первой ячейки мы можем выбрать между номерами q. Поскольку мы не можем повторять вертикально, мы можем выбрать между q - 1 номерами для второй ячейки и, следовательно, q - 1 номера для третьей ячейки и т.д. Для q == 100 и n == 18 это означает, что есть допустимые раскраски q * (q - 1) ^ (n - 1) = 100 * 99 ^ 17, которые очень грубо 10 ^ 36.

Теперь рассмотрим любые два допустимых столбца (назовем их столбцами хлеба), разделенные столбцом буфера (назовите его горчичным столбцом). Вот тривиальный алгоритм для нахождения допустимого набора значений для горчичного столбца, когда q >= 4. Начните с верхней ячейки горчичной колонки. Нам нужно только беспокоиться о соседних ячейках колонок хлеба, которые имеют не более 2 уникальных значений. Выберите любое третье число для горчичного столбца. Рассмотрим вторую ячейку горчичного столбца. Мы должны рассмотреть предыдущую горчичную ячейку и 2 соседние клетки хлеба с общим количеством не более 3 уникальных значений. Выберите четвертое значение. Продолжайте заполнять горчичную колонку.

У нас есть не более двух столбцов, содержащих жестко закодированную ячейку 0. Используя столбцы горчицы, мы можем сделать по крайней мере шесть столбцов хлеба, каждый из которых содержит около 10 ^ 36 решений для всего не менее 10 ^ 216 действительных решений, дают или принимают порядок величины для ошибок округления.

Есть, согласно Википедии, о 10 ^ 80 атомах во Вселенной.

Поэтому будьте умнее.

Ответ 3

Update 11/11 Я также спросил об этом на форумах TopCoder, и их решение является наиболее эффективным, которое я видел до сих пор (около 41 часа для n = 10, любой q, из оценки автора)

Я автор. Не 41, всего 3 неудобных параллелизируемых часа процессора. Я подсчитал симметрии. При n = 10 существует только 675 действительно четких пар (i, j) и (k, l). Моя программа требует ~ 16 секунд за каждый.

Ответ 4

Я создаю вклад, основанный на вкладе в обсуждение Дэйвом Аароном Смитом.

Не будем рассматривать теперь последние два ограничения ((i,j) и (k,l)).

Только с одним столбцом (nx1) решение q * (q - 1) ^ (n - 1).


Сколько вариантов для второго столбца? (q-1) для верхней ячейки (1,2), но затем q-1 или q-2 для ячейки (2,2), если (1,2)/(2,1) имеют или не имеют один и тот же цвет.

То же самое для решений (3,2): q-1 или q-2.

Мы видим, что у нас есть бинарное дерево возможностей, и нам нужно суммировать это дерево. Предположим, что левый ребенок всегда "одного цвета сверху и слева", а правый ребенок - "разные цвета".

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

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

Без равномерного распределения это было бы невозможно.

Задача: равномерное распределение?

Ответ: Мы получили бы такое же количество решений, построив сначала второй столбец, первый, а затем третий. В этом случае распределение второго столбца равномерно, поэтому оно также в первом случае.

Теперь мы можем применить ту же "идею дерева", чтобы подсчитать количество возможностей для третьего столбца.

Я попытаюсь разобраться в этом и построить общую формулу (поскольку дерево имеет размер 2 ^ n, мы не хотим явно его изучать).

Ответ 5

Несколько наблюдений, которые могут помочь другим автоответчикам:

  1. Значения 1..q взаимозаменяемы - они могут быть буквами, и результат будет таким же.
  2. Ограничения, которые не соответствуют соседям, являются очень мягкими, поэтому подход грубой силы будет чрезмерно дорогим. Даже если бы вы знали значения во всех, кроме одной ячейки, по-прежнему были бы возможности q-8 для q > 8.
  3. Результат этого будет довольно длинным - для каждого набора из i, j, k, l потребуется строка. Число комбинаций - это что-то вроде n 2 (n 2 -3), так как два фиксированных нуля могут быть где угодно, кроме смежных друг с другом, если они не должны подчиняться первое правило. При n = 100 и q = 18, максимально жесткий случай, это ~ 100 4= 100 миллионов. Так что ваша минимальная сложность и неизбежна, поскольку проблема в настоящее время заявлена.
  4. Существуют простые случаи - когда q = 2, существуют две возможные шахматные доски, поэтому для любой заданной пары нулей ответ равен 1.

Точка 3 делает всю программу O (n 2 (n 2 -3)) как минимум, а также предполагает, что вам понадобится что-то достаточно эффективное для каждого пара нулей, просто написание 100 миллионов строк без каких-либо вычислений, займет некоторое время. Для справки, на секунду в строке, то есть 1x10 8 s ~ 3 года или 3 месяца на 12-ядерном ящике.

Я подозреваю, что есть элегантный ответ, учитывая пару нулей, но я не уверен, что есть аналитическое решение. Учитывая, что вы можете сделать это с 2 или 3 цветами в зависимости от положения нулей, вы можете разбить карту на ряд областей, каждая из которых использует только 2 или 3 цвета, а затем просто количество различных комбинаций 2 или 3 в q (qC2 или qC3) для каждой области умножается на количество областей, умноженное на количество способов расщепления карты.

Ответ 6

Я не математик, но мне кажется, что должно быть аналитическое решение этой проблемы, а именно:

Сначала вычислите, что для платы NxN с цветами Q возможно много разных раскрасок (в том числе, что соседи, имеющие общий край, не получают одинаковый цвет). Это должна быть довольно простая формула.

Затем выясните, сколько из этих решений имеет 0 в (i, j), это должно быть 1/Q-доля.

Затем выясните, сколько из оставшихся решений имеет 0 в (k, l), зависящее от манхэттенского расстояния | ik | + | jl | и, возможно, расстояние до края доски и "четность" этих расстояний, как и на расстоянии на 2, делится на 3, делится на Q.

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