[Thuật Toán] Sinh các chỉnh hợp lặp chập k của n


THUẬT TOÁN SINH CÁC CHỈNH HỢP LẶP CHẬP K CỦA N

Xét về bản chất thì thuật toán sinh các chuỗi nhị phân có độ dài là k thực chất là liệt kê các chỉnh hợp lặp chập k của 2 (vì tập nguồn của chúng ta có 2 phần tử là 0 và 1). 

Vậy thì nếu tập nguồn của chúng ta không phải là 2 phần tử nữa, mà là n phần tử thì sao ?

Khi đó, bài toán mới của chúng ta sẽ là :

Cho tập X có n phần tử {1,2,…,n}. hãy liệt kê các chỉnh hợp lặp chập k của n.

Ví dụ : với n = 2 và k = 3 nhập từ bàn phím thì các cấu hình của bài toán là :
(111) ; (112) ; (121) ; (122) ; (211) ; (212) ; (221) ; (222).

Theo công thức của chỉnh hợp lặp thì số các cấu hình = n^k= 2^3 = 8.

Và nhìn vào ví dụ trên, chúng ta cũng sẽ thấy cấu hình đầu là toàn số 1 và cấu hình cuối toàn số n. và  ta dễ dàng tìm ra thuật toán như sau :

Xét từ cuối dãy về đầu, gặp chữ số có giá trị chưa bằng  n :
·       *  Tăng chữ số đó lên 1 đơn vị
·        * Gán tất cả phần tử sau vị trí đó = 1.

Thuật toán dừng lại khi sinh được cấu hình cuối gồm các phần tử có giá trị đều = n.
Source code tham khảo :


#include<iostream>
using namespace std;
int n, k, a[10];
bool check = false;
void display(){

 for (int i = 1; i <= k; i++){
  cout << a[i];
 }
 cout << endl;
}
void nextString(){
 int i = k;
 while (a[i]==n&&i>0){  // nếu a[i] = n và i > 0 thì giảm i
  i--;
 }
 if (i == 0) check = true; // nếu i = 0 thì đã đến cấu hình cuối cùng 
 else
 {
  a[i]++;     // tăng a[i] lên 1 đơn vị
  for (int j = i + 1; j <= k; j++){
   a[j] = 1;   // đặt tất cả phần tử phía sau a[i] = 1
  }

 }
}
void main(){
 cout << " nhap n = ";
 cin >> n;
 cout << " nhap k = ";
 cin >> k;
 for (int i = 1; i <= k; i++){
  a[i] = 1;
 }
 while (!check){
  display();
  nextString();
 }
 system("pause");
}
bài viết chắc chắn còn nhiều thiếu sót rất mong bạn đọc góp ý qua email : trieuhiepptit@gmail.com Thanks for reading !

[Tản mạn] về mọi thứ trong cuộc sống


Vì đơn giản, sống là cho đi, đâu cần nhận lại :)

[Thuật Toán] Sinh các chuỗi nhị phân có độ dài n

THUẬT TOÁN SINH CÁC DÃY NHỊ PHÂN CÓ ĐỘ DÀI N

Một dãy nhị phân có độ dài n là một dãy x[1..n] trong đó x[i] ∈{0,1}
ví dụ 1 dãy nhị phân có độ dài = 3 :

chúng ta có thể liên hệ giữa số chuỗi nhị phân này với định nghĩa chỉnh hợp như sau :

cho tập X gồm 2 phần tử {0;1}
mỗi bộ( dãy ) gồm n phần tử từ 2 phần tử đã cho ta được 1 chỉnh hợp lặp chập n của 2.


như vậy,
với n = 3 thì số cấu hình ( hay số dãy nhị phân ) = 8 ( như trên hình ban đầu ).


ta nhận thấy cấu hình đầu tiên sẽ là 00…0 và cấu hình cuối cùng sẽ là 11…1.

Nhận xét rằng nếu cấu hình x[1..n] là cấu hình đang có và không phải cấu hình cuối cùng cần liệt kê thì dãy kế tiếp sẽ nhận được bằng cách cộng thêm 1 ( theo cơ số 2 có nhớ) vào cấu hình hiện tại.

như vậy, phương pháp sinh đã được thỏa mãn 2 điều kiện đó là : biết được cấu hình đầu-cuối ; thuật toán sinh được cấu hình tiếp theo từ cấu hình trước nó.

chúng ta sẽ sử dụng phương pháp sinh để "đẻ" ra các cấu hình thỏa mãn đề bài như sau :

xét từ cuối dãy đi lên, gặp số 0 đầu tiên : 
* nếu thấy thì thay số 0 bằng số 1 và đặt tất cả phần tử sau vị trí đó = 0.
* nếu không thấy thì dãy toàn số 1, đây là cấu hình cuối cùng.

code của chương trình như sau :


#include<iostream>
using namespace std;
int n, a[10];
bool check = false;            // tạo 1 biến kiểu bool để kiểm tra xem đã đến cấu hình cuối chưa
void display(){  // hiển thị cấu hình ra màn hình
 for (int i = 1; i <= n; i++){
  cout << a[i];
 }
 cout << endl;
}
void nextString(){
 int i = n;
 while (a[i]==1 && i > 0){
  i--;
 }
 if (i == 0) check = true; // nếu i=0 tức là đã đến cấu hình cuối, gán biến check = true
 else
 {
  a[i] = 1;    // còn không thì gán a[i]=1
  for (int j = i + 1; j <= n; j++){
   a[j] = 0;   // gán tất cả phần tử phía sau a[i] =0
  }
 }
}
void main(){
 cout << " nhap do dai day nhi phan";
 cin >> n;
 for (int i = 1; i <= n; i++){   // cấu hình đầu tiên gồm toàn số 0
  a[i] = 0;
 }
 while (!check){
  display();       // hiển thị cấu hình
  nextString();      // sinh cấu hình tiếp theo
 }
 system("pause");
}

bài viết chắc chắn còn nhiều thiếu sót rất mong bạn đọc góp ý qua email : trieuhiepptit@gmail.com Thanks for reading !

[Thuật Toán] Phương Pháp Sinh ( Generation)

PHƯƠNG PHÁP SINH ( GENERATION )


phương pháp sinh ??? trước đây học khi mình đọc thấy cụm từ này mình thấy nó khá là "khó hiểu". vấn đề của chị em sao lại có mặt trong môn liên quan đến toán tin này nhỉ :/
nhưng sau khi học xong thì thấy nó có liên quan thật :V , nhưng mà không phải là liên quan theo nghĩa đen =)))
chúng ta sẽ tiếp cận với nó 1 cách tự nhiên nhất nhóe :3

* Cấu hình là gì ?

chúng ta sẽ xét ví dụ về bài toán tổ hợp sau :
giả sử mình có tập X ={1,2,3,4,5,6,7} gồm có 7 phần tử.
hãy liệt kê 1 số 1 số chỉnh hợp không lặp chập 5 của X.

ta dễ dàng nhận thấy 1 số chỉnh hợp không lặp chập 5 của 7 như là : 12345, 23456, 73241...
vậy thì mỗi bộ (12345), (23456),... được gọi là 1 cấu hình
đó, cấu hình về cơ bản nôm na chỉ là thế thôi :3  nó chỉ là 1 nghiệm thỏa mãn yêu cầu đề bài của bài toán tổ hợp. mỗi cấu hình đều có các phần tử. ví dụ cấu hình 12345 có các phần tử 1,2,3,4,5.

* Phương pháp sinh dùng để làm gì ?

mình cũng sẽ ví dụ luôn cho dễ hiểu. với dữ liệu đề như trên, nếu mình muốn liệt kê tất cả các chỉnh hợp không lặp chập 5 của X ( hay gọi là liệt kê tất cả các cấu hình của bài toán) thì phải làm như thế nào ?
chày cối đếm tay và viết vào máy ? :D điều này có thể thực hiện nếu chỉ có ít phần tử chứ cho liệt kê mà tập có 30 phần tử thì nổ não :D
vậy cách giải quyết ví dụ là gì ? câu trả lời là phương pháp sinh.

* vậy mục đích của phương pháp sinh là gì ? 

phương pháp sinh dùng có thể áp dụng để giải bài toán liệt kê tổ hợp, hay nói cách khác là liệt kê các cấu hình của bài toán.

* phương pháp sinh hoạt động như thế nào ?

rất đơn giản, nó sẽ "đẻ" ra các cấu hình tiếp theo từ các cấu hình trước đó cho đến khi nào hết nghiệm thì thôi. :D
ví dụ: trong ví dụ trên, từ cấu hình 123456 PPS sẽ đẻ ra tiếp cấu hình 23456 cho đến khi hết nghiệm của bài toán

* điều kiện để áp dụng được phương pháp sinh : 

có 2 điều kiện để sử dụng được phương pháp sinh :
– Xác định được trật tự các nghiệm. Biết được nghiệm đầu và nghiệm cuối cùng.
– Xây dựng được thuật toán từ một nghiệm (cấu hình) chưa phải là nghiệm cuối cùng ta đều sinh ra một cấu hình đứng sau nó.

cấu trúc của thuật toán sinh như sau :

while(chưa phải là cấu hình cuối cùng){
<đưa ra cấu hình hiện tại>;
<sinh cấu hình kế tiếp>;
}

như vậy là đã xong phần giới thiệu về phương pháp sinh :D
bài sau mình sẽ chi tiết phương pháp này vào 3 thuật toán cơ bản & đặc trưng của phương pháp sinh. đó là thuật toán sinh nhị phân, sinh hoán vị & sinh các tập con của 1 tập.
bài viết chắc chắn còn nhiều thiếu sót rất mong bạn đọc góp ý qua email : trieuhiepptit@gmail.com
Thanks for reading !

[Thuật Toán] Nhắc lại 1 số kiến thức về đại số tổ hợp




trong bài đầu tiên này, chúng ta sẽ cùng ôn lại 1 số kiến thức về đại số tổ hợp mà các bạn đã từng học ở cấp 3 nhé, mình chỉ nhắc lại thôi :D
có 4 khái niệm các bạn cần phân biệt được, đó là chỉnh hợp lặp, chỉnh hợp không lặp, hoán vị & tổ hợp.

1. Chỉnh Hợp Lặp

 để định nghĩa chỉnh hợp lặp này theo góc độ ánh xạ thì có vẻ là khá là khó hiểu nên mình sẽ nói về nó dưới 1 góc độ khác.

* ĐN : cho 1 tập X gồm n phần tử. 
   mỗi bộ ( hoặc nhóm ) có thứ tự gồm k phần tử lấy ra từ n phần tử đã cho ta được 1 chỉnh hợp    lặp chập k của n.
   các phần tử trong bộ ( nhóm trên ) có thể lặp lại 1,2,3,....,k lần.

ví dụ : tập X gồm các phần tử : {1,2,3,4,5}
thì (1,2,1,3) là 1 chỉnh hợp lặp chập 4 của X.
bằng phép quy nạp toán học ta có thể dễ dàng chứng minh được kết quả sau :

* số các chỉnh hợp lặp chập k của n phần tử là nk

2. Chỉnh Hợp Không Lặp

* ĐN : cho 1 tập X gồm n phần tử. 
   lấy ra k phần tử trong n phần tử và có sự sắp xếp ( thứ tự nhất định ) ta được 1 chỉnh hợp          không lặp chập k của n

ví dụ : tập X gồm các phần tử : {1,2,3,4,5}
thì (1,2,3) là 1 chỉnh hợp không lặp chập 3 của X.

* số các chỉnh hợp không lặp chập k của X được tính theo công thức : 
3. Hoán Vị

* khi k = n thì 1 chỉnh hợp không lặp chập n của X được gọi là 1 hoán vị của X

* số các hoán vị của tập X gồm n phần tử ( hay số chỉnh hơp không lặp chập n của X ) là n!

4. Tổ Hợp
* ĐN : cho 1 tập X gồm n phần tử. 
   lấy ra k phần tử trong n phần tử ta được 1 tổ hợp chập k của n.

ví dụ : tập X gồm các phần tử : {1,2,3,4,5}
thì (1,2,3) là 1 tổ hợp chập 3 của X.

* số các tổ hợp chập k của X được tính theo công thức : 
5. Mối quan hệ giữa tổ hợp & chỉnh hợp

* các bạn có hể dễ dàng nhận ra mối quan hệ đầu tiên giữa tổ hợp & chỉnh hợp không lặp thông qua 2 công thức tính , có nghĩa là :
* vậy điều khác biệt giữa chỉnh hợp không lặp và tổ hợp là gì ? 
nhiều bạn đọc không kĩ sẽ thắc mắc rằng cái định nghĩa và ví dụ của chỉnh hợp không lặp và tổ hợp na ná nhau. đúng là chúng có hơi giống nhau, điều khác nhau duy nhất giữa chúng đó là cụm từ "có sự sắp xếp ( thứ tự nhất định )".

vì thế, các bạn chỉ cần hiểu nôm na nó khác nhau như sau :

∎ chỉnh hợp không lặp là lấy ra và có sự sắp xếp thứ tự các phần tử .
∎ tổ hợp là chỉ lấy ra mà không có sự sắp xếp thứ tự các phần tử .
∎ tổ hợp "nằm trong" chỉnh hợp không lặp.

như vậy là mình đã trình bày xong với các bạn toàn bộ kiến thức cơ bản về 4 nội dung : chỉnh hợp lặp, chỉnh hợp không lặp, hoán vị & tổ hợp.
bài viết chắc chắn còn nhiều thiếu sót rất mong bạn đọc góp ý qua email : trieuhiepptit@gmail.com
Thanks for reading !

Những ca khúc buồn cho người thất tình

 thất tình là tình trạng một bên trong quan hệ tình ái không được bên kia đáp lại tình yêu của mình dành cho đối phương một cách tha thiết, việc từ chối đáp lại tình cảm này được thực hiện công khai hoặc ngầm hiểu là như vậy, điều đó trực tiếp gây ra những trạng thái cảm xúc qua nhiều cung bậc khác nhau, từ sự buồn chán, đau khổ, cô đơn, hoang mang cho đến tổn thương, thậm chí là nguy cơ tự tử hoặc trả thù, nó là biểu hiện của sự bất toại nguyện, không đạt được mục đích mà mình muốn trong tình cảm. Phạm vi thất tình có thể là trong giai đoạn tán tỉnh, cửa cẩm lẫn nhau của những đôi trai gái nhưng một bên bị từ chối hoặc ở giai đoạn hai bên đã nảy sinh tình cảm thậm chí là có tình yêu nhưng vì lý do nào đó một bên không còn tình cảm hoặc đòi chia tay mà bên kia vẫn muốn níu kéo.
Khi rơi vào trạng thái thất tình, cả nam và nữ đều tâm trạng, tuy nhiên, các biểu hiện của các bên khác nhau tùy vào giới tính và hoàn cảnh.
Những ca khúc buồn cho người thất tình

Thumbnail
Người Hữu Tình Trồng Hoa , Hoa Không Thắm - Kẻ Vô Tình Cắm Liễu, Liễu Lại Xanh

bài test


sdjsiVSBSdvSVBshdbVJxb