Я думаю, что вы можете довольно эффективно вычислить это, построив гистограмму, которая отслеживает, сколько всего 1 в каждом столбце. Возьмите свой пример:
X Y Z
A 0 1 0
B 0 0 1
C 1 1 1
Если вы сложите столбцы, вы получите 1, 2 и 2 соответственно. Чтобы найти среднее попарное сходство, вы можете подумать о том, чтобы найти среднее сходство по каждому столбцу, а затем взять его среднее. В этом случае, чтобы найти попарное сходство, вы спросите, для каждого столбца, сколько существует пар элементов. Для столбца X это 0. Для столбца Y это 1, а для столбца Z это также 1. Если мы вычислим (0/3 + 1/3 + 1/3) / 3, вы получите 2/9, как требуется. Чтобы найти трехстороннее сходство, вы спрашиваете, сколько триплетов в каждом столбце. В каждом есть 0, поэтому среднее значение равно 0.
Причина, по которой это работает, в том, что вы хотите сумму
(Сумма (все возможные k-кортежей строк) (# столбец соответствует по строкам / num столбцам)) / num k-кортежей
Вы можете выделить это, чтобы получить
(Сумма (все возможные k-кортежей строк) (# столбец соответствует столбцам в строках)) / (num k-кортежей * num столбцов)
Эту первую сумму можно затем обменять, чтобы получить
(Sum (все столбцы) (# k-кортежей строк, соответствующих этому столбцу)) / (num k-кортежей * num столбцов)
Вычислить эту сумму намного проще, потому что вы можете просто сделать это:
- Рассчитать суммы столбцов.
- Для каждого столбца найдите, сколько способов выбрать из него k элементов (это равно n, выберите k), затем разделите его на количество столбцов.
- Разделите это общее количество на количество наборов строк из k элементов, которые есть (это количество строк, выбранное k).
Вы можете достаточно эффективно вычислить n select k, используя определение функции выбора (за время O (n + k)). Если у вас R строк и C столбцов, общая работа составит:
- Суммирование столбцов в каждой строке: O (RC)
- Для столбца вычисляется количество комбинаций k-элементов: O (R + k), поскольку сумма не более R.
- По всем столбцам, вычисляя это общее значение: O (CR + Ck)
- Усреднение их вместе: O (C)
Это дает общее время выполнения O (CR + Ck). Я думаю, что если вы связываете k числом строк, это выполняется за время O (CR).
Надеюсь, это поможет!