Zorluk, bir matrisin Hafnianını hesaplamak için mümkün olan en hızlı kodu yazmaktır .
Simetrik 2n
-by- 2n
matrisin Hafnyanı A
şu şekilde tanımlanır:
İşte S 2n gelen sayının tüm permütasyon kümesini temsil 1
etmek 2n
olduğunu, [1, 2n]
.
Vikipedi bağlantısı da ilgi çekici olabilecek farklı görünümlü bir formül verir (ve web'e daha fazla bakarsanız daha hızlı yöntemler de mevcuttur). Aynı wiki sayfası bitişik matrislerden bahseder, ancak kodunuz diğer matrisler için de çalışmalıdır. Değerlerin hepsinin tamsayı olacağını, ancak hepsinin pozitif olduğunu varsayamazsınız.
Ayrıca daha hızlı bir algoritma var ama anlaşılması zor görünüyor. ve Christian Sievers bunu ilk uygulayan oldu (Haskell'de).
Bu soruda matrislerin hepsi kare ve eşit boyutta simetriktir.
Başvuru uygulaması (bunun mümkün olan en yavaş yöntemi kullandığını unutmayın).
Bay Xcoder'dan bazı örnek python kodları.
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
Görev
Bir matris 2n
tarafından verilen 2n
Hafnian çıktısını veren bir kod yazmalısınız.
Kodunuzu test etmem gerekeceğinden, kodunuza girdi olarak bir matris vermem için basit bir yol verebilirseniz, örneğin standarttan okuyarak kodunuzu test etmeniz yararlı olacaktır. {-1, 0, 1} arasından seçildi. Bunun gibi testlerin amacı Hafnian'ın çok büyük bir değer olma şansını azaltmaktır.
İdeal olarak kodunuz matrislerde tam olarak bu sorudaki örneklerde olduğu gibi doğrudan standart olarak okuyabilecektir. Bu, [[1,-1],[-1,-1]]
örneğin örneğin giriş gibi görünecektir . Başka bir giriş formatı kullanmak istiyorsanız, lütfen sorun; uyum sağlamak için elimden geleni yapacağım.
Skorlar ve bağlar
Kodunuzu artan boyuttaki rastgele matrislerde test edeceğim ve kodunuzun bilgisayarımda ilk kez 1 dakikadan fazla sürdüğünü durduracağım. Puanlama matrisleri, adaleti sağlamak için tüm başvurular için tutarlı olacaktır.
Eğer iki kişi aynı puanı alırsa, kazanan o değerin en hızlı olanıdır n
. Bunlar birbirinin 1 saniyesindeyse, ilk önce gönderilir.
Diller ve kütüphaneler
Hafnian'ı hesaplamak için istediğiniz herhangi bir dili ve kütüphaneyi kullanabilirsiniz, ancak önceden var olan bir işlevi kullanamazsınız. Mümkünse, kodunuzu çalıştırabilmeniz iyi olur, bu yüzden lütfen mümkünse kodunuzu Linux'ta nasıl çalıştıracağınız / derleyeceğiniz konusunda tam bir açıklama ekleyin.
Benim Makine zamanlamaları benim 64 bit makinede işletilecek. Bu, 8GB RAM, AMD FX-8350 Sekiz Çekirdekli İşlemci ve Radeon HD 4250 ile standart bir ubuntu yüklemesidir. Bu aynı zamanda kodunuzu çalıştırabilmem gerektiği anlamına gelir.
Daha fazla dilde yanıt arayın
En sevdiğiniz süper hızlı programlama dilinde cevaplar almak harika olurdu. İşe başlamak için fortran , nim ve pas ne dersiniz ?
Liderler Sıralaması
- C ++ kullanarak 52 km . 30 saniye.
- 50 ngn ile C kullanılarak . 50 saniye.
- 46 Haskell kullanarak Christian Sievers tarafından . 40 saniye.
- Python 2 + pypy kullanarak 40 km . 41 saniye.
- 34 ngn tarafından Python 3 + pypy kullanılarak . 29 saniye.
- 28 Dennis tarafından Python kullanarak 3 . 35 saniye. (Pypy daha yavaştır)