Создать список уникальных перестановок - PullRequest
3 голосов
/ 02 марта 2020

Скажем, у меня есть список из 3 символов:

l:`s1`s2`s3

Что такое q-способ создания следующего списка n * (n + 1) / 2 перестановок?

(`s1;`s1),(`s1;`s2),(`s1;`s3),(`s2;`s2),(`s2;`s3),(`s3;`s3)

Это можно увидеть как в контексте корреляционной матрицы, где я хочу, чтобы вся верхняя три angular часть корреляционной матрицы, включая диагональ.

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

Я знаю, как генерировать диагональные элементы:

q) {(x,y)}'[l;l]

(`s1`s1;`s2`s2;`s3`s3)

Но я не знаю, как генерировать недиагональные элементы.

Ответы [ 3 ]

2 голосов
/ 02 марта 2020

Еще одно решение, которое может оказаться полезным:

q)l
`s1`s2`s3
q){raze x,/:'-1_{1_x}\[x]}l
s1 s1
s1 s2
s1 s3
s2 s2
s2 s3
s3 s3

При этом используется сканер сканирования для создания списка списков символов, при котором каждый элемент отбрасывается первым:

q)-1_{1_x}\[l]
`s1`s2`s3
`s2`s3
,`s3

Требуется дополнительная -1_, так как сканирование также вернет пустой список в конце. Затем присоедините каждый элемент списка к этому результату с помощью каждого права и каждого:

{x,/:'-1_{1_x}\[x]}l
(`s1`s1;`s1`s2;`s1`s3)
(`s2`s2;`s2`s3)
,`s3`s3

Наконец, используйте raze для получения различных перестановок.

РЕДАКТИРОВАТЬ: можно также использовать

q){raze x,/:'til[count x]_\:x}l
s1 s1
s1 s2
s1 s3
s2 s2
s2 s3
s3 s3

, который вообще не нуждается в сканировании и очень похож на решение для сканирования по производительности!

1 голос
/ 02 марта 2020

Я бы попробовал ниже код

{distinct asc each x cross x}`s1`s2`s3

Это

  • cross генерирует все (s_i, s_j) пары
  • asc each сортирует каждую пару по индексу `s3`s1 становится `s1`s3
  • distinct удаляет дубликаты

Не самый эффективный способ для очень короткого.

0 голосов
/ 02 марта 2020

Если я понимаю вопрос (извинения, если я что-то пропустил). Ниже должен дать вам то, что вы ищете

q)test:`s1`s2`s3`s4`s5
q)(til cnt) _' raze (-1+cnt:count test)cut test,'/:test
(`s1`s1;`s2`s1;`s3`s1;`s4`s1;`s5`s1)
(`s2`s2;`s3`s2;`s4`s2;`s5`s2)
(`s3`s3;`s4`s3;`s5`s3)
(`s4`s4;`s5`s4)
,`s5`s5
...