Как вычислить перестановки в линейное время со скручиванием

Вы должны использовать this.signupForm.patchValue({username = 'ahmad'}); вместо сброса

7
задан 27 January 2009 в 22:20
поделиться

5 ответов

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

n = длина строки
A = матрица совместимости
количество возможных строк = сумма 1

Несколько примеров:

n = 1
| 1 0 0 0 0 |
| 0 1 0 0 0 |
| 0 0 1 0 0 |
| 0 0 0 1 0 |
| 0 0 0 0 1 |
sum: 5

n = 3
| 2 0 0 0 0 |
| 0 1 0 0 0 |
| 0 0 1 1 0 |
| 0 0 1 1 0 |
| 0 0 0 0 1 |
sum: 8

n = 8
| 0 0 8 8 0 |
| 0 0 0 0 1 |
| 8 0 0 0 0 |
| 8 0 0 0 0 |
| 0 1 0 0 0 |
sum: 34

Исходная матрица (строка i, столбец j) могла считаться количеством строк, которые запускаются с символа i, и чей следующий символ является символом j. С другой стороны, Вы видели его как количество строк длины 2, которые запускаются с символа i и концы с символом j.

Умножение матриц сохраняет этот инвариант, поэтому после того, как возведение в степень, 1 содержал бы количество строк, которые запускаются с символа i, имеет длину n и заканчивается в символе j.

Посмотрите Википедию: Возведение в степень путем обработки на квадрат для алгоритма для более быстрого вычисления матричных полномочий.

(Спасибо stefan.ciobaca)

Этот конкретный случай уменьшает до формулы:

количество возможных строк = f (n) = 4 + Σk=1.. n 2⌊k-1⁄2 = f (n-1) + 2⌊n-1⁄2

n       f(n)
----    ----
   1       5
   2       6
   3       8
   4      10
   5      14
   6      18
   7      26
   8      34
   9      50
  10      66
19
ответ дан 6 December 2019 в 06:51
поделиться

Вы просто хотите знать, сколько строк данной длины можно создать с правилами в данной матрице? Если так, то, что подход как это должен работать:

n = 5
maxlen = 100

combine = [
      [0, 0, 1, 1, 0],
      [0, 0, 0, 0, 1],
      [1, 0, 0, 0, 0],
      [1, 0, 0, 0, 0],
      [0, 1, 0, 0, 0]
   ]

# counts of strings starting with 0,1,...,4, initially for strings of length one:
counts = [1, 1, 1, 1, 1]

for size in range(2, maxlen+1):
   # calculate counts for size from count for (size-1)
   newcount = []
   for next in range(n):
      total = 0
      for head in range(n):
         if combine[next][head]:
            # |next| can be before |head|, so add the counts for |head|
            total += counts[head]
      # append, so that newcount[next] == total
      newcount.append(total)
   counts = newcount
   print "length %i: %i items" % (size, sum(counts))
3
ответ дан 6 December 2019 в 06:51
поделиться

Ваш алгоритм, кажется, оптимален.

Как Вы используете эти перестановки? Вы накапливаете их в одном списке или используете его один за другим? С тех пор существует огромное количество таких перестановок, таким образом, низкая производительность, возможно, из-за использования памяти большой емкости (при сборе всех их) или просто требуется так много времени. Вы просто не можете сделать миллиардов циклов в тривиальное время.

Ответ на комментарий:

Если Вы просто хотите считать их, то Вы можете с помощью динамического программирования:

Позвольте количеству [n] [m] быть массивом, где количество [l] [j] является количеством таких перестановок, длина которых является l и концом с j,

затем количество [l] [я] = количество [l-1] [i1] +count [l-1] [i2] +..., где i1, i2... являются цифрами, которые могут предшествовать мне (это может быть сохранено в предрасчетном массиве).

Каждая ячейка количества может быть заполнена путем подведения итогов K, числа (K зависит от совместимой матрицы), таким образом, сложность является O (KMN), M является продолжительностью перестановки, и N является общим количеством цифр.

2
ответ дан 6 December 2019 в 06:51
поделиться

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

Затем Ваша стандартная программа для генерации возьмет накопленный результат, число цифры и текущую цифру. Что-то как:

// not really Java - and you probably don't want chars, but you'll fix it
void GenerateDigits(char[] result, int currIndex, char currDigit)
{
    if (currIndex == kMaxIndex) {
        NotifyComplete(result);
        return;
    }
    char[] validFollows = GetValidFollows(currDigit); // table lookup
    foreach (char c in validFollows) {
        result[currIndex] = c;
        GenerateDigits(result, currIndex+1, c);
    }
}

Сложность увеличивается как функция количества цифр для генерации, но что функция зависит от общего количества допустимых, следует для любой цифры. Если общее количество следует, то же для каждой цифры, скажем, k, то время для генерации всех возможных перестановок будет O (k^n), где n является количеством цифр. Извините, я не могу изменить математику. Время для генерации n цифр в основе 10 10^n.

1
ответ дан 6 December 2019 в 06:51
поделиться

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

1
ответ дан 6 December 2019 в 06:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: