Daha önce belirttiğim gibi, Compile
kullanarak daha hızlı kod verilecektir.
ClearAll[cfNextPartition];
cfNextPartition[target : "MVM" | "C"] :=
cfNextPartition[target] =
Compile[{{n, _Integer}, {this, _Integer, 1}},
Module[{i = n, j = n, ni, next = this, r, s},
While[Part[next, --i] > Part[next, i + 1],
If[i == 1, i = 0; Break[]]];
If[i == 0, {-1}, ni = Part[next, i];
While[ni > Part[next, j], --j];
next[[i]] = Part[next, j]; next[[j]] = ni;
r = n; s = i + 1;
While[r > s, ni = Part[next, r]; next[[r]] = Part[next, s];
next[[s]] = ni; --r; ++s];
next
]], RuntimeOptions -> "Speed", CompilationTarget -> target
];
Sonra
In[75]:= Reap[PermutationIterator[Sow, 4, cfNextPartition["C"]]][[2,
1]] === Permutations[Range[4]]
Out[75]= True
budur:
Aşağıdaki kod varsayar
PermutationIterator[f_, n_Integer?Positive, nextFunc_] :=
Module[{this = Range[n]},
While[this =!= {-1}, f[this]; this = nextFunc[n, this]];]
biz sürüm 8 çalıştırın: fxtbook gelen bir algoritma kullanarak, aşağıdaki kod lexicographic sıralamada bir sonraki bölümü oluşturur Orijinal gen
işlevinden açıkça daha iyi performans. Mathematica adlı sanal makine kullanma
In[83]:= gen[dummy, 9] // Timing
Out[83]= {26.067, Null}
In[84]:= PermutationIterator[dummy, 9, cfNextPartition["C"]] // Timing
Out[84]= {1.03, Null}
çok daha yavaş değil:
In[85]:= PermutationIterator[dummy, 9,
cfNextPartition["MVM"]] // Timing
Out[85]= {1.154, Null}
Tabii bu, hiçbir yerde C kodu uygulaması yakındır henüz saf üst düzey kodu üzerinde önemli bir hız-up sağlar.
FWIW, Python'un yineleyici/üreteç yapma şekli oldukça sıradışı. Devlet üzerinde bir çeşit soyutlama (kapaklar, sınıflar) olduğu sürece, bunları herhangi bir dubada uygulayabilirsiniz. – jrockway
Ah, güzel. Belki de bunu kendi sorunuza bir cevap olarak ekleyelim (bunu yapmak için oldukça koşucu sayılır). Yoksa burada hala cevaplanmamış bir soru var mı? – dreeves
Python, sizin için bir şey ifade ediyor ve bu çerçeveye uygun hale getirirken, işlevlerinizi açık bir şekilde iletmeniz gerekiyor. Yani, bu mükemmel değil. Ama yeterince iyi, aslında, şimdi kullanıyorum. – nes1983