Tôi hiện đang tính toán hoán vị duy nhất của một mảng dữ liệu. Mặc dù mã sau đang hoạt động nhưng nó không hiệu quả như tôi muốn. Khi tôi nhận được hơn 6 hoặc 8 mục, nó trở nên rất chậm và tôi bắt đầu chạy vào các vấn đề về bộ nhớ.Hiệu quả tính toán hoán vị duy nhất trong một tập hợp
Đây là mã và giải thích
<?php
function permuteUnique($items, $count = false, $perms = [], &$return = []) {
if ($count && count($return) == $count) return $return;
if (empty($items)) {
$duplicate = false;
foreach ($return as $a) {
if ($a === $perms) {
$duplicate = true;
break;
}
}
if (!$duplicate) $return[] = $perms;
} else {
for ($i = count($items) - 1; $i >= 0; --$i) {
$newitems = $items;
$newperms = $perms;
list($tmp) = array_splice($newitems, $i, 1);
array_unshift($newperms, $tmp);
permuteUnique($newitems, $count, $newperms, $return);
}
return $return;
}
}
function factorial($n) {
$f = 1;
for ($i = 2; $i <= $n; $i++) $f *= $i;
return $f;
}
Với đầu vào [1, 1, 2]
tôi nhận được đầu ra sau như mong đợi
array (size=3)
0 =>
array (size=3)
0 => int 1
1 => int 1
2 => int 2
1 =>
array (size=3)
0 => int 1
1 => int 2
2 => int 1
2 =>
array (size=3)
0 => int 2
1 => int 1
2 => int 1
Tham số $count
được để tôi có thể vượt qua số hoán vị độc đáo Tôi mong đợi chức năng và một khi nó đã tìm thấy rằng nhiều, nó có thể ngừng tính toán và trả lại dữ liệu. Điều này được tính là giai thừa của tổng số mục chia cho sản phẩm giai thừa của tổng số tất cả các mục trùng lặp. Tôi không chắc tôi đã nói đúng như vậy để tôi cho bạn xem một ví dụ.
Được đặt số [1, 2, 2, 3, 4, 4, 4, 4]
số hoán vị duy nhất được tính là 8!/(2!4!) = 840
vì có 8 mục, một trong số đó được nhân đôi hai lần và một số khác được nhân đôi 4 lần.
Bây giờ nếu tôi dịch rằng mã php ...
<?php
$set = [1, 2, 2, 3, 4, 4, 4, 4];
$divisor = 1;
foreach (array_count_values($set) as $v) {
$divisor *= factorial($v);
}
$count = factorial(count($set))/$divisor;
$permutations = permuteUnique($set, $count);
nó khá chậm. Nếu tôi ném một bộ đếm vào hàm permuteUnique
, nó chạy trên 100k lần trước khi nó tìm thấy các hoán vị duy nhất 840.
Tôi muốn tìm cách giảm số này và tìm đường dẫn ngắn nhất có thể đến các hoán vị duy nhất. Tôi đánh giá cao bất kỳ trợ giúp hoặc lời khuyên nào bạn có thể đưa ra.
Nhìn vào ['std :: next_permutation'] (http://en.cppreference.com/w/cpp/algorithm/next_permutation) cho C++ và tìm hoặc thực hiện một cái gì đó như thế này cho PHP. – MvG