У меня есть список из> 10.000 int предметов.Значения предметов могут быть очень высокими, до 10 ^ 27.Теперь я хочу создать все пары предметов и рассчитать их сумму.Затем я хочу найти разные пары с одинаковой суммой.
Например:
l[0] = 4
l[1] = 3
l[2] = 6
l[3] = 1
...
pairs[10] = [(0,2)] # 10 is the sum of the values of l[0] and l[2]
pairs[7] = [(0,1), (2,3)] # 7 is the sum of the values of l[0] and l[1] or l[2] and l[3]
pairs[5] = [(0,3)]
pairs[9] = [(1,2)]
...
Содержимое pairs[7]
- это то, что я ищу.Он дает мне две пары с одинаковой суммой значений.
Я реализовал это следующим образом - и мне интересно, можно ли это сделать быстрее.В настоящее время на 10 000 единиц товара требуется более 6 часов на быстрой машине.(Как я уже говорил, значения l
и, следовательно, ключи pairs
являются целыми числами до 10 ^ 27.)
l = [4,3,6,1]
pairs = {}
for i in range( len( l ) ):
for j in range(i+1, len( l ) ):
s = l[i] + l[j]
if not s in pairs:
pairs[s] = []
pairs[s].append((i,j))
# pairs = {9: [(1, 2)], 10: [(0, 2)], 4: [(1, 3)], 5: [(0, 3)], 7: [(0, 1), (2, 3)]}
Редактировать: Я хочудобавить некоторый фон, как попросил Саймон Стеллинг.
Цель состоит в том, чтобы найти формальные аналогии, такие как
lays : laid :: says : said
, в списке слов, таких как
[ lays, lay, laid, says, said, foo, bar ... ]
Iуже есть функция analogy(a,b,c,d)
, дающая True
, если a : b :: c : d
.Тем не менее, мне нужно будет проверить все возможные четверки, созданные из списка, что будет сложность около O ((n ^ 4) / 2).
В качестве предварительного фильтра, я хочу использоватьсвойство char-count.Это говорит о том, что каждый символ имеет одинаковое количество в (a, d) и в (b, c).Например, в "layssaid" у нас есть 2 a, и мы делаем в "laidsays"
Так что до сих пор идея была
- для каждого слова, чтобы создать "charсчитать вектор "и представить его как целое число (элементы в списке
l
) - создать все пары в
pairs
и посмотреть, есть ли" парные кластеры ", т.е. более одной пары для конкретногосумма символов вектора.
И это работает, это просто медленно.Сложность примерно равна O ((n ^ 2) / 2), но это все еще много, и особенно часто выполняется поиск и вставка в словарь.