let menu = ["Home", "Algorithms", "CodeHub", "VNOI Statistics"];

Sinh hoán vị

Sinh hoán vị

Sinh theo thứ tự từ điển

Giả sử đang có hoán vị \((A_1, A_2, ... , A_N)\) , sinh hoán vị tiếp theo trong thứ tự từ điển bằng thuật toán sau:

  • Bước 1: Tìm vị trí \(K\) lớn nhất thoả \(A_K < A_{K+1}\), nếu không tìm được thì đây là hoán vị cuối cùng, dừng thuật toán.
  • Bước 2: Tìm vị trí \(L\) lớn nhất thoả \(A_K < A_L\)
  • Bước 3: Đổi chỗ 2 phần tử \(A_K\) và \(A_L\).
  • Bước 4: Đảo ngược mảng trong đoạn \((A_{K+1}, A_{K+2},..., A_N)\).

Lặp lại các bước trên đến khi sinh được hoán vị cuối cùng.

#include <iostream>
#include <vector>
using namespace std;

void print(const vector<int> &a) {
    for (int i=0; i<a.size(); i++) cout << a[i] << " ";
    cout << endl;
}

void permute(vector<int> &a, int n) {
    while (true) {
        print(a);
        int k, l;
        for (k = n-2; k>=0; k--) if (a[k] < a[k+1]) break; // Bước 1
        if (k<0) break;                                    //
        for (l = n-1; l>k; l--) if (a[k] < a[l]) break; // Bước 2
        swap(a[k], a[l]); // Bước 3
        for (int i=k+1, j=n-1; i<j; i++, j--) swap(a[i], a[j]); // Bước 4
    }
}

int main() {
    vector<int> a = {1, 2, 3, 4, 5, 6, 7};
    permute(a, a.size());
    return 0;
}

Sinh theo thuật toán Heap (Heap’s Algorithm)

Hoán vị sinh theo thuật toán Heap thoả mãn: hoán vị sau được tạo thành từ hoán vị trước bằng cách hoán vị 2 phần tử, các phần tử khác giữ nguyên vị trí.

Cài đặt đệ quy:

void permute(vector<int> &a, int k) {
    if (k==1) return print(a);
    for (int i=0; i<k-1; i++) {
        permute(a, k-1);
        if (k%2==0) swap(a[i], a[k-1])
        else swap(a[0], a[k-1]);
    }
    permute(a, k-1);
}

Cài đặt không đệ quy:

void permute(vector<int> &a, int n) {
    vector<int> c(0, n);
    print(a, n);
    int i=0;
    while (i<n) {
        if (c[i] < i) {
            if (i%2 == 0) swap(a[0], a[i])
            else swap(a[c[i]], a[i]);
            print(a, n);
            c[i]++;
            i = 0;
        } else c[i++] = 0;
    }
}

Xem thêm

Comments