У меня есть массив:
array([[ 4, 10],
[ 4, 2],
[ 0, 7],
[ 5, 11],
[ 6, 8],
[ 3, 6],
[ 9, 7],
[ 2, 11],
[ 9, 5],
[ 8, 1]])
Я хочу метод, с помощью которого можно упорядочить пары значений так, чтобы как можно больше парных наборов из 2 элементов имели общее значение.Это пример желаемого упорядоченного массива:
array([[ 4, 10],
[ 4, 2],
[ 2, 11],
[ 5, 11],
[ 9, 5],
[ 9, 7],
[ 0, 7], #note the gap here:
[ 8, 1],
[ 6, 8],
[ 3, 6]])
Для этих массивов выполняется несколько условий.Дублированных пар нет (то есть: [1,0] и [0,1] не появятся в других местах массива, если [0,1] уже существует).Ни одна пара не имеет такое же значение (то есть: [1,1] не будет существовать).Ни одна пара не будет иметь более двух совпадений (iow: ни одно значение не существует более двух раз во всем массиве.), Но пара может иметь всего лишь несколько совпадений (обратите внимание, что в приведенном выше массиве пробел, между которым нет совпадения).
Очевидно, я могу создать любую перестановку массива, но это кажется грубым.Я думаю, что может быть какой-то способ разрезания колоды и повторной укладки таким образом, чтобы она сортировалась с небольшим количеством разрезов.Но прежде чем идти по этому пути, я хочу: 1) убедиться, что нет функции numpy
или collections
, которая уже делает это.2) Знайте, что нет хитрого гениального способа использовать numpy .sort()
(или подобный) для этого.3) Найдите, является ли это обычной задачей, и существует ли алгоритм, который это делает.(«О, это алгоритм Блюмена-Функе!»)
Вот код, который генерирует перемешанные тестовые массивы и проверяет отсортированные массивы:
def shuffled(N=12, ans=1):
'''returns is now the unsorted test array'''
r = range(N)
random.shuffle(r)
l = []
for i in range(N):
l.append((r[i-1], r[i]))
random.shuffle(l)
return np.array(l)[ans+1:]
# step 2: ???
def test_ordered(a):
'''checks if generated array has been sorted'''
c0 = a[1:,0]==a[:-1,0]
c1 = a[1:,0]==a[:-1,1]
c2 = a[1:,1]==a[:-1,0]
c3 = a[1:,1]==a[:-1,1]
cond = c0+c1+c2+c3
ans = sum(numpy.logical_not(cond))
# when sorted this should return the same number input into
# shuffled() as 'ans':
return ans
(Это субъективный вопрос? IМеня предупреждают, что это так.)
Результаты:
Большое спасибо за вашу помощь.Решение Свена было примерно на 20% быстрее, чем у Пола, и, к счастью, оба они работают в линейном времени, ответ Дуга не решил проблему.Существовала высокая, но в значительной степени линейная зависимость производительности от количества «разрывов» или «разрывов» во входных данных.Смотрите сюжет ниже.Ось с магнитудой 10000 равна N. Ось 0.5 - это процент разрывов.Ось Z - производительность в секундах.
Еще раз спасибо!
