Như tôi đã nêu trước đây, việc sử dụng Compile
sẽ đưa ra mã nhanh hơn. Sử dụng một thuật toán từ fxtbook, đoạn code sau tạo ra một phân vùng tiếp theo trong trật tự tự từ điển:
PermutationIterator[f_, n_Integer?Positive, nextFunc_] :=
Module[{this = Range[n]},
While[this =!= {-1}, f[this]; this = nextFunc[n, this]];]
Các mã sau đây giả định chúng tôi chạy phiên bản 8:
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
];
Sau đó
In[75]:= Reap[PermutationIterator[Sow, 4, cfNextPartition["C"]]][[2,
1]] === Permutations[Range[4]]
Out[75]= True
Đây là rõ ràng hơn về hiệu suất so với chức năng gốc gen
.
In[83]:= gen[dummy, 9] // Timing
Out[83]= {26.067, Null}
In[84]:= PermutationIterator[dummy, 9, cfNextPartition["C"]] // Timing
Out[84]= {1.03, Null}
Sử dụng máy ảo Mathematica không phải là chậm hơn nhiều:
In[85]:= PermutationIterator[dummy, 9,
cfNextPartition["MVM"]] // Timing
Out[85]= {1.154, Null}
Tất nhiên đây là nơi nào gần thi mã C, tuy nhiên cung cấp một tốc độ đáng kể-up trên tinh khiết đang cấp cao nhất.
FWIW, cách tạo lặp/tạo của Python là khá bất thường. Miễn là bạn có một số loại trừu tượng trên trạng thái (bao đóng, các lớp), bạn có thể thực hiện chúng trong bất kỳ ngôn ngữ nào. – jrockway
Ah, hay. Có thể thêm rằng như là một câu trả lời cho câu hỏi của riêng bạn (nó được coi là khá kosher để làm điều đó). Hay vẫn còn một câu hỏi chưa được trả lời ở đây? – dreeves
Vâng, bạn cần phải thông minh một cách rõ ràng các chức năng của bạn xung quanh, trong khi các loại năng suất Python loại con số nó ra cho bạn, và làm cho nó phù hợp với khuôn khổ. Vì vậy, nó không phải là khá hoàn hảo. Nhưng đủ tốt, thực sự, tôi sử dụng nó ngay bây giờ. – nes1983