문제는 매트릭스 의 Hafnian 을 계산할 수있는 가장 빠른 코드를 작성하는 것 입니다.
대칭의 Hafnian 2n
-by- 2n
매트릭스 A
로서 정의된다 :
여기서 S 2N가 에서 모든 정수 순열의 집합을 나타냄 1
에 2n
즉, [1, 2n]
.
위키 백과 링크는 또한 흥미로울 수있는 다른 수식을 제공합니다 (웹에서 더 자세히 살펴보면 더 빠른 방법이 존재합니다). 동일한 위키 페이지는 인접 행렬에 대해 이야기하지만 코드는 다른 행렬에서도 작동합니다. 값이 모두 정수이지만 모두 양수라고 가정 할 수는 없습니다.
거기에 또한 빠른 알고리즘은 하지만 이해하기 어려운 것 같다. Christian Sievers는이를 Haskell에서 최초로 구현했습니다.
이 질문에서 행렬은 모두 정사각형이며 치수가 균일합니다.
참조 구현 (가장 느린 방법을 사용하고 있음에 유의하십시오).
다음은 Mr. Xcoder의 Python 코드 예제입니다.
from itertools import permutations
from math import factorial
def hafnian(matrix):
my_sum = 0
n = len(matrix) // 2
for sigma in permutations(range(n*2)):
prod = 1
for j in range(n):
prod *= matrix[sigma[2*j]][sigma[2*j+1]]
my_sum += prod
return my_sum / (factorial(n) * 2 ** n)
print(hafnian([[-1, 1, 1, -1, 0, 0, 1, -1], [1, 0, 1, 0, -1, 0, -1, -1], [1, 1, -1, 1, -1, -1, 0, -1], [-1, 0, 1, -1, -1, 1, -1, 0], [0, -1, -1, -1, -1, 0, 0, -1], [0, 0, -1, 1, 0, 0, 1, 1], [1, -1, 0, -1, 0, 1, 1, 0], [-1, -1, -1, 0, -1, 1, 0, 1]]))
4
M = [[1, 1, 0, 0, 0, 0, 0, 1, 0, 0], [1, 1, -1, 0, -1, 1, 1, 1, 0, -1], [0, -1, -1, -1, 0, -1, -1, 0, -1, 1], [0, 0, -1, 1, -1, 1, -1, 0, 1, -1], [0, -1, 0, -1, -1, -1, -1, 1, -1, 1], [0, 1, -1, 1, -1, 1, -1, -1, 1, -1], [0, 1, -1, -1, -1, -1, 1, 0, 0, 0], [1, 1, 0, 0, 1, -1, 0, 1, 1, -1], [0, 0, -1, 1, -1, 1, 0, 1, 1, 1], [0, -1, 1, -1, 1, -1, 0, -1, 1, 1]]
print(hafnian(M))
-13
M = [[-1, 0, -1, -1, 0, -1, 0, 1, -1, 0, 0, 0], [0, 0, 0, 0, 0, -1, 0, 1, -1, -1, -1, -1], [-1, 0, 0, 1, 0, 0, 0, 1, -1, 1, -1, 0], [-1, 0, 1, -1, 1, -1, -1, -1, 0, -1, -1, -1], [0, 0, 0, 1, 0, 0, 0, 0, 0, 1, -1, 0], [-1, -1, 0, -1, 0, 0, 1, 1, 1, 1, 1, 0], [0, 0, 0, -1, 0, 1, 1, -1, -1, 0, 1, 0], [1, 1, 1, -1, 0, 1, -1, 1, -1, -1, -1, -1], [-1, -1, -1, 0, 0, 1, -1, -1, -1, 1, -1, 0], [0, -1, 1, -1, 1, 1, 0, -1, 1, -1, 1, 1], [0, -1, -1, -1, -1, 1, 1, -1, -1, 1, 0, -1], [0, -1, 0, -1, 0, 0, 0, -1, 0, 1, -1, 1]]
print(hafnian(M))
13
M = [[-1, 1, 0, 1, 0, -1, 0, 0, -1, 1, -1, 1, 0, -1], [1, -1, 1, -1, 1, 1, -1, 0, -1, 1, 1, 0, 0, -1], [0, 1, 1, 1, -1, 1, -1, -1, 0, 0, -1, 0, -1, -1], [1, -1, 1, -1, 1, 0, 1, 1, -1, -1, 0, 0, 1, 1], [0, 1, -1, 1, 0, 1, 0, 1, -1, -1, 1, 1, 0, -1], [-1, 1, 1, 0, 1, 1, -1, 0, 1, -1, -1, -1, 1, -1], [0, -1, -1, 1, 0, -1, -1, -1, 0, 1, -1, 0, 1, -1], [0, 0, -1, 1, 1, 0, -1, 0, 0, -1, 0, 0, 0, 1], [-1, -1, 0, -1, -1, 1, 0, 0, 1, 1, 0, 1, -1, 0], [1, 1, 0, -1, -1, -1, 1, -1, 1, 1, 1, 0, 1, 0], [-1, 1, -1, 0, 1, -1, -1, 0, 0, 1, -1, 0, -1, 0], [1, 0, 0, 0, 1, -1, 0, 0, 1, 0, 0, 1, 1, 1], [0, 0, -1, 1, 0, 1, 1, 0, -1, 1, -1, 1, 1, -1], [-1, -1, -1, 1, -1, -1, -1, 1, 0, 0, 0, 1, -1, -1]]
print(hafnian(M))
83
작업
2n
by 2n
행렬이 주어진 Hafnian을 출력 하는 코드를 작성해야합니다 .
코드를 테스트해야하므로 표준 입력을 읽는 것과 같이 코드를 입력으로 매트릭스를 제공하는 간단한 방법을 제공 할 수 있다면 도움이 될 것입니다. 요소를 사용하여 무작위로 선택된 매트릭스에서 코드를 테스트합니다 {-1, 0, 1}에서 선택되었습니다. 이와 같은 테스트의 목적은 Hafnian이 매우 큰 가치를 가질 가능성을 줄이는 것입니다.
이상적으로는이 질문의 예제에서 표준으로 직접 입력 한 것과 똑같이 코드를 행렬로 읽을 수 있습니다. 입력은 [[1,-1],[-1,-1]]
예를 들어 보입니다 . 다른 입력 형식을 사용하려면 문의하십시오. 최선을 다해 수용하겠습니다.
점수와 관계
크기가 커지는 임의의 행렬에서 코드를 테스트하고 컴퓨터에서 코드가 처음 1 분 이상 걸리면 중지합니다. 공정성을 보장하기 위해 점수 제출 매트릭스는 모든 제출물에 대해 일관성이 있습니다.
두 사람이 같은 점수를 얻는다면 승자는 그 가치에서 가장 빠른 것입니다 n
. 그것들이 서로 1 초 이내에 있다면 그것은 먼저 게시 된 것입니다.
언어와 라이브러리
Hafnian을 계산하기 위해 원하는 언어와 라이브러리를 사용할 수 있지만 기존 기능은 사용할 수 없습니다. 가능하다면 코드를 실행하는 것이 좋을 것이므로 가능한 경우 리눅스에서 코드를 실행 / 컴파일하는 방법에 대한 자세한 설명을 포함하십시오. '
내 컴퓨터 타이밍이 64 비트 컴퓨터에서 실행됩니다. 이것은 8GB RAM, AMD FX-8350 8 코어 프로세서 및 Radeon HD 4250이 포함 된 표준 우분투 설치입니다. 또한 코드를 실행할 수 있어야합니다.
더 많은 언어로 답변 요청
좋아하는 초고속 프로그래밍 언어로 답을 얻는 것이 좋습니다. 시작하기 위해, 포트란 , nim 및 녹은 어떻습니까?
리더 보드
- C ++를 사용하여 52 마일 . 30 초.
- C를 사용하여 ngn로 50 . 50 초
- 46 Haskell을 사용하는 Christian Sievers . 40 초
- Python 2 + pypy 사용하여 40 마일 . 41 초
- Python 3 + pypy를 사용하는 ngn의 34 . 29 초
- 28 Python을 사용하는 Dennis의 3 . 35 초 (파이피가 느리다)