Trang 1
MÔN : CÁC MẪU THIẾT KẾ HỚNG ỐI TỢNG
Bài thực hành số 5.1 : Xây dựng và kiểm thử thuật gii tiến hóa trên các cá thể
n gin
I. Mục tiêu :
Giúp SV làm quen với gii thuật tiến hóa và cơng dụng của nó. Giúp SV biết
cách sử dụng các mẫu thiết kế Singleton, Prototype, Abstract Factory trong
từng yêu cầu cụ thể.
II. Nội dung :
Xây dựng module thực hiện gii thuật tiến hóa trên các cá thể chứa số thực. Ý
tởng gii thuật tiến hóa nh sau :
1. lúc ầu, ta có 1 thế hệ gồm n cá thể, mỗi cá thể có 1 giá trị ặc trng (specval)
và có ộ thích nghi (fitness) xác ịnh.
2. q trình tiến hóa của mỗi thế hệ diễn ra theo c chế lặp, mỗi chu kỳ tiến hóa
có các hot ộng sau :
- xác ịnh li ộ thich nghi của từng cá thể.
- chọn lựa 1 số cá thể có ộ thích nghi cao nhất ể giữ chúng li làm nồng cốt cho
thế hệ mới.
- cho các cá thể này phối giống ể to ra các cá thể con cho ủ số lợng.
- chọn 1 số cá thể và cho chúng ột biến thành các thể khác.
Thế hệ các cá thể ầu tiên
1. xác ịnh li ộ thich nghi của từng
cá thể.
2. chọn lựa 1 số cá thể có ộ thích
nghi cao nhất ể giữ chúng li làm
nồng cốt cho thế hệ mới.
3. cho các cá thể này phối giống ể
to ra các cá thể con cho ủ số
lợng.
4. chọn 1 số cá thể và cho chúng ột
biến thành các thể khác.
Thế hệ các cá thể kế tiếp
III. Chuẩn ầu ra :
Nắm vững tính chất, cơng dụng của các mẫu thiết kế Singleton, Prototype,
Abstract Factory ể có thể dùng li mẫu này trong bất kỳ vị trí nào của
chng trình mới cần xây dựng.
IV. Qui trình xây dựng chng trình
Trang 2
1. Chy VS .Net, chọn menu File.New.Project ể hiển thị cửa sổ New Project.
2. Mở rộng mục Visual C# trong TreeView "Project Types", chọn mục Window,
chọn icon "Windows Form Application" trong listbox "Templates" bên phi, thiết
lập th mục chứa Project trong listbox "Location", nhập tên Project vào textbox
"Name:" (td. BaiTH5), click button OK ể to Project theo các thông số ã khai
báo.
3. Form ầu tiên của ứng dụng ã hiển thị trong cửa sổ thiết kế, việc thiết kế form
là q trình lặp 4 thao tác to mới/xóa/hiệu chỉnh thuộc tính/to hàm xử lý sự
kiện cho từng ối tợng cần dùng trong form. Ta s giới thiệu yêu cầu của ứng
dụng sau. Bây giờ ta s xây dựng th viện chứa các thành phần miêu t thuật
gii tiến hóa tổng quát.
4. Dời chuột về gốc cây Project trong cửa sổ "Solution Explorer", ấn phi chuột
trên phần tử gốc này, chọn option Add.New Folder, ặt tên cho folder mới là
GenLib.
5. Thờng bài tốn dùng thuật gii tiến hóa cần to thế hệ ầu tiên các cá thể 1
cách ngẫu nhiên. Việc to ối tợng ngẫu nhiên thờng liên quan ến việc to
số nguyên, số thực ngẫu nhiên. ể việc lấy số ngẫu nhiên của nhiều phần tử
trong phần mềm ợc nhất quán, ta s to 1 ối tợng duy nhất chuyên phục
vụ to số ngẫu nhiên. ể bo m phần tử to số ngẫu nhiên là duy nhất, ta
dùng mẫu thiết kế Singleton. Hãy hiện thực ối tợng này có các dịch vụ sau :
to số nguyên ngẫu nhiên bất kỳ.
to số nguyên ngẫu nhiên nằm trong khong từ 0 tới n.
to số thực ngẫu nhiên nằm trong khong từ 0 tới 1.
Dời chuột về th mục GenLib trong cửa sổ “Solution Explorer”, ấn phi chuột
vào nó ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị cửa sổ
“Add New Item”, chọn mục “Class”, hiệu chỉnh tên class là MyRandom.cs, chọn
button Add ể máy to 1 class mới. Viết code cho class này nh sau :
class MyRandom {
//hàm khởi to private ể cấm bên ngoài to ối tợng MyRandom
private MyRandom() { }
//thông tin dùng chung trong class
private static MyRandom myrnd = new MyRandom();
public static MyRandom getInstance() { return myrnd; }
//thông tin trong ối tợng
private Random rnd = new Random();
//tác vụ to số nguyên ngẫu nhiên bất kỳ
public int RndInt() { return rnd.Next(); }
//tác vụ to số nguyên ngẫu nhiên trong khong từ 0 ến n
public int RndInt(int n) { return rnd.Next(n); }
//tác vụ to số thực ngẫu nhiên từ 0 tới 1
public double RndDouble() { return rnd.NextDouble(); }
}
Lu ý rằng ta ã dùng mẫu Adapter ể xây dựng class MyRandom dựa trên
class Random của .NET.
Trang 3
6. ịnh nghĩa interface cho ối tợng cá thể của thuật gii tiến hóa tổng quát có
các dịch vụ sau :
tham kho giá trị ặc trng.
tham kho/hiệu chỉnh ộ fitness.
phối giống với cá thể khác.
ột biến mình
nhân bn vơ tính mình
gii mã mình thành chuỗi vn bn
Dời chuột về th mục GenLib trong cửa sổ “Solution Explorer”, ấn phi chuột
vào nó ể hiển thị menu lệnh, chọn chức nng Add.New Item ể hiển thị cửa sổ
“Add New Item”, chọn mục “Interface”, hiệu chỉnh tên interface là
IIndividual.cs, chọn button Add ể máy to 1 interface mới. Viết code cho
interface này nh sau :
interface IIndividual : IComparable<IIndividual> {
//thuộc tính luận lý SpecValue : chỉ ọc
Object SpecValue {get;}
//thuộc tính luận lý Fitness : ọc/ghi
double Fitness {get; set;}
//hàm phối giống với other
IIndividual cross(IIndividual other);
//hàm ột biến mình
void muter();
//hàm to ối tợng mới theo c chế nhân bn vơ tính (dùng mẫu Prototype)
IIndividual clone();
//hàm gii mã ối tợng thành dng chuỗi vn bn
String ToString();
}
7. Viết thêm class abstract chứa những thông tin chung mà các ối tợng cá thể
khác nhau s dùng. Dĩ nhiên class này phi hiện thực interface IIndividual :
Dời chuột về th mục GenLib trong cửa sổ “Solution Explorer”, ấn phi chuột
vào nó ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị cửa sổ
“Add New Item”, chọn mục “Class”, hiệu chỉnh tên class là
AbstractIndividual.cs, chọn button Add ể máy to 1 class mới. Viết code cho
class này nh sau :
abstract class AbstractIndividual : IIndividual {
protected double fitness = 0.0;
protected bool muted = false;
public AbstractIndividual()
{
}
//thuộc tính luận lý SpecValue : ọc/ghi
public abstract Object SpecValue { get; set; }
Trang 4
public bool Muted
{
get { return muted; }
set { muted = value; }
}
public double Fitness
{
get { return fitness; }
set { fitness = value; }
}
//hàm so sánh với cá thể khác (phục vụ sắp xếp danh sách)
public int CompareTo(IIndividual o)
{
if (o.Fitness == Fitness)
return 0;
else if (Fitness < o.Fitness)
return -1;
return 1;
}
//hàm nhân bn mình theo mẫu Prototype
public abstract IIndividual clone();
//hàm ột biến mình
public abstract void muter();
//hàm phối giống với other
public abstract IIndividual cross(IIndividual other);
}
8. Ta cần ối tợng mục tiêu chuyên ánh giá cá thể ể tính ộ thích nghi của các
thể ó theo ngữ nghĩa xác ịnh. Trớc hết ta ịnh nghĩa interface tối thiểu cho
ối tợng mục tiêu này.
Dời chuột về th mục GenLib trong cửa sổ “Solution Explorer”, ấn phi chuột
vào nó ể hiển thị menu lệnh, chọn chức nng Add.New Item ể hiển thị cửa sổ
“Add New Item”, chọn mục “Interface”, hiệu chỉnh tên interface là ITarget.cs,
chọn button Add ể máy to 1 interface mới. Viết code cho interface này nh
sau :
interface ITarget {
//tác vụ tính tốn cá thể
double eval(IIndividual ind);
}
9. Bây giờ ta ịnh nghĩa interface cho ối tợng thế hệ với các tính chất sau :
lúc ầu cha có cá thể nào.
cho phép thêm từng cá thể vào, số lợng các thể là bất kỳ.
cho phép tham kho số lợng cá thể.
Trang 5
tiến hóa sang thế hệ mới theo 2 phng pháp : phối giống và ột biến.
Dời chuột về th mục GenLib trong cửa sổ “Solution Explorer”, ấn phi chuột
vào nó ể hiển thị menu lệnh, chọn chức nng Add.New Item ể hiển thị cửa sổ
“Add New Item”, chọn mục “Interface”, hiệu chỉnh tên interface là
IPopulation.cs, chọn button Add ể máy to 1 interface mới. Viết code cho
interface này nh sau :
interface IPopulation {
//hàm tr về số cá thể
int size();
//hàm thêm cá thể mới vào thế hệ
void add(IIndividual individu);
//thuộc tính truy xuất cá thể thứ i
IIndividual this[int i] { get; }
//hàm gii mã ối tợng thành chuỗi vn bn
String ToString();
//hàm tiến hóa sang thế hệ mới
IPopulation evoluer(ITarget cible);
}
10. Ta hiện thực ối tợng thế hệ, ối tợng này s chứa thuật gii tiến hóa tổng
quát.
Dời chuột về th mục GenLib trong cửa sổ “Solution Explorer”, ấn phi chuột
vào nó ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị cửa sổ
“Add New Item”, chọn mục “Class”, hiệu chỉnh tên class là Population.cs, chọn
button Add ể máy to 1 class mới. Viết code cho class này nh sau :
class Population : IPopulation {
//qun lý thế hệ các cá thể bằng class List<T> của .NET
private List<IIndividual> individus = new List<IIndividual>();
//dùng ối tợng to số ngẫu nhiên duy nhất trong tồn chng trình
private static MyRandom rnd = MyRandom.getInstance();
//hàm tr về số cá thể
public int size() {
return individus.Count();
}
//hàm thêm cá thể mới vào thế hệ
public void add(IIndividual individu) {
individus.Add(individu);
}
//thuộc tính truy xuất cá thể thứ i
public IIndividual this[int i] {
get { return individus[i]; }
}
//hàm gii mã ối tợng thành chuỗi vn bn
public override String ToString() {
String buf = "[";
Trang 6
bool fstart = true;
for (int i = 0; i < individus.Count(); i++)
if (fstart) {
fstart = false;
buf += individus[i].ToString();
}
else buf += ", " + individus[i].ToString();
return buf + "]";
}
//hàm tiến hóa sang thế hệ mới
public IPopulation evoluer(ITarget cible) {
//tính ộ thích nghi các cá thể và sắp xếp chúng
evaluer(cible);
//to thế hệ mới
Population pop = reproduire();
//cho 5% cá thể bị ột biến
pop.muter(0.05);
//tính li ộ thích nghi các cá thể và sắp xếp chúng
//pop.evaluer(cible);
return pop;
}
//hàm tính ộ thích nghi của từng cá thể và sắp xếp các cá thể theo ộ thích nghi của
chúng
private void evaluer(ITarget cible) {
//lặp tính ộ thích nghi của từng cá thể
foreach (IIndividual ind in individus)
{
ind.Fitness = cible.eval(ind);
}
//sắp xếp các cá thể theo ộ thích nghi của chúng
Sort();
}
//hàm sắp xếp thự tự các cá thể theo ngữ nghĩa xác ịnh
private void Sort() {
individus.Sort();
individus.Reverse();
}
//hàm ột biến cho cá thể
private void muter(double ratio) {
//to tập hợp cá thể cần ột biến (trừ cá thể ầu tiên có ộ thích nghi tốt nhất)
List<IIndividual> subl = individus.GetRange(1, individus.Count - 1);
//xử lý ột biến cho từng cá thể với xác suất ratio
Trang 7
foreach (IIndividual ind in subl) {
if (rnd.RndDouble() < ratio)
ind.muter();
}
}
//hàm to thế hế mới
private Population reproduire() {
//chọn 20% cá thể có ộ thích nghi tốt nhất
int max = individus.Count() / 5;
Population pop = new Population();
//cho chúng thành cá thể của thế hệ mới
for (int i = 0; i < max; i++) {
pop.add(individus[i].clone());
}
//lặp phối giống từng cặp cá thể ã có (chọn ngẫu nhiên) ể to thêm 80% cá thể mới
for (int i = max; i < size(); i++) {
int mec = rnd.RndInt(max);
int mef = rnd.RndInt(max);
pop.add(individus[mec].cross(individus[mef]));
}
return pop;
}
}
11. Ta dùng mẫu Abstract Factory ể cung cấp dịch vụ to các ối tợng mà chng
trình ứng dụng dùng. ối tợng Factory có kh nng nh sau :
to ợc 1 thế hệ cá thể với số lợng xác ịnh.
to ợc ối tợng mục tiêu của bài toán.
Dời chuột về th mục GenLib trong cửa sổ “Solution Explorer”, ấn phi chuột
vào nó ể hiển thị menu lệnh, chọn chức nng Add.New Item ể hiển thị cửa sổ
“Add New Item”, chọn mục “Interface”, hiệu chỉnh tên interface là
IPopulationFactory.cs, chọn button Add ể máy to 1 interface mới. Viết code
cho interface này nh sau :
interface IPopulationFactory {
//hàm to ối tợng mục tiêu
ITarget createTarget() ;
//hàm to thế hệ có size cá thể ngẫu nhiên
IPopulation createRandomPopulation(int size) ;
}
12. Bây giờ ta thử áp dụng thuật gii tiến hóa vào bài tốn n gin nh sau : ta
lấy 1 số thực mục tiêu ngẫu nhiên, ta to ngẫu nhiên 1 thế hệ xuất phát gồm n
số thực có ngẫu nhiên. Thử áp dụng thuật gii tiến hóa tổng quát ợc xây
dựng trong th viện GenLib ể xem thế hệ số thực ban ầu có hội tụ về giá trị
mục miêu hay không ?
Trang 8
13. Ta ịnh nghĩa class MyDouble ể qun lý số thực. MyDouble chính là giá trị ặc
trng của cá thể cần tiến hóa.
Dời chuột về phần tử gốc của cây Project trong cửa sổ “Solution Explorer”, ấn
phi chuột vào nó ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị
cửa sổ “Add New Item”, hiệu chỉnh tên class là MyDouble.cs, chọn button Add
ể máy to 1 class mới. Viết code cho class này nh sau :
class MyDouble {
private double val;
public MyDouble(double v) { val = v; }
public double Val
{
get { return val; }
set { val = value; }
}
//hàm gii mã ối tợng mục tiêu ra chuỗi vn bn
public override String ToString()
{
String buf = String.Format("{0:f5}", val);
return buf;
}
}
14. Hiện thực ối tợng cá thể có các tính chất cụ thể nh sau :
giá trị ặc trng là ối tợng MyDouble qun lý số thực từ 0 tới 1.
ộ fitness là số thực, càng lớn nghĩa là càng thích nghi tốt.
phối giống với cá thể khác ể to cá thể con có giá trị ặc trng bằng trung
bình cộng của cha m.
ột biến mình theo nguyên tắc : to 1 các thể mới ngẫu nhiên, ột biến giá
trị ặc trng của mình bằng trung bình cộng của cá thể mới với mình.
nhân bn vơ tính mình (dùng mẫu Prototype)
gii mã mình thành chuỗi vn bn miêu t giá trị ặc trng.
Dời chuột về phần tử gốc của cây Project trong cửa sổ “Solution Explorer”,
ấn phi chuột vào nó ể hiển thị menu lệnh, chọn chức nng Add.Class ể
hiển thị cửa sổ “Add New Item”, hiệu chỉnh tên class là DoubleIndividual.cs,
chọn button Add ể máy to 1 class mới. Viết code cho class này nh sau :
using BaiTH5.GenLib;
...
class DoubleIndividual : IIndividual {
//giá trị ặc trng của cá thể
private MyDouble spVal;
//ộ thích nghi của cá thể
private double fitness = 0.0;
//thuộc tính miêu t ã bị ộ biến cha
private bool muted = false;
//ối tợng to số ngẫu nhiên duy nhất trong tồn chng trình
private static MyRandom rnd = MyRandom.getInstance();
//hàm khởi to cá thể có giá trị ặc trng ngẫu nhiên
Trang 9
public DoubleIndividual() {
this.spVal = new MyDouble(rnd.RndDouble());
}
//hàm khởi to cá thể có giá trị ặc trng xác ịnh
public DoubleIndividual(MyDouble valeurPropre) {
this.spVal = valeurPropre;
}
//hiện thực thuộc tính luận lý Muted
public bool Muted {
get { return muted; }
set { muted = value; }
}
//hiện thực thuộc tính luận lý SpecValue
public Object SpecValue {
get { return spVal; }
set { spVal = (MyDouble)value; }
}
//hiện thực thuộc tính luận lý Fitness
public double Fitness {
get { return fitness; }
set { fitness = value; }
}
//hàm gii mã ối tợng thành chuỗi vn bn
public override String ToString() {
//return String.Format("vp={0:f4}, fit={1:f4}",valeurPropre, fitness);
return String.Format("{0:f5}", spVal);
}
//hàm so sánh với cá thể khác (phục vụ sắp xếp danh sách)
public int CompareTo(IIndividual o) {
if (o.Fitness == Fitness)
return 0;
else if (Fitness < o.Fitness)
return -1;
return 1;
}
//hàm phối giống với cá thể khác
public IIndividual cross(IIndividual other) {
MyDouble o1 = SpecValue as MyDouble; //giá trị ặc trng của mình
MyDouble o2 = other.SpecValue as MyDouble;//giá trị ặc trng của ối tác
//to cá thể con
if (o1 == null && o2 == null) return new DoubleIndividual(new MyDouble(0));
if (o1 == null) return other;
if (o2 == null) return this;
return new DoubleIndividual(new MyDouble((o1.Val + o2.Val) / 2));
}
Trang 10
//hàm ột biến cá thể hiện hành
public void muter() {
//ột biến tối a 10% biên ộ giá trị ặc trng
// spVal += (rnd.RndDouble() < 0.5 ? 1 : -1) * rnd.RndDouble() * 0.1 * spVal;
//theo trung bình cộng với giá trị ặc trng ngẫu nhiên
spVal = new MyDouble((spVal.Val + rnd.RndDouble()) / 2);
//theo giá trị ặc trng ngẫu nhiên
// spVal = Math.random();
}
//hàm to ối tợng mới theo c chế nhân bn vơ tính (dùng mẫu Prototype)
public IIndividual clone() {
return new DoubleIndividual(spVal);
}
}
15. Hiện thực ối tợng mục tiêu nh sau :
nó có giá trị ặc trng là MyDouble chứa 1 số thực từ 0 tới 1 giống nh các
cá thể.
tính ộ fitness của cá thể theo cơng thức 1/((sv1-sv2)^2), trong ố sv1 là
giá trị ặc trng của nó và sv2 là giá trị ặc trng của cá thể cần tính tốn.
Dời chuột về phần tử gốc của cây Project trong cửa sổ “Solution Explorer”, ấn
phi chuột vào nó ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị
cửa sổ “Add New Item”, chọn mục “Class”, hiệu chỉnh tên class là
DoubleTarget.cs, chọn button Add ể máy to 1 class mới. Viết code cho class
này nh sau :
using BaiTH5.GenLib;
...
class DoubleTarget : ITarget {
//giá trị mục tiêu mà ta mong muốn t ợc
private double val;
//ối tợng to số ngẫu nhiên duy nhất trong tồn chng trình
private MyRandom rnd = MyRandom.getInstance();
//hàm khởi to ngẫu nhiên giá trị mục tiêu
public DoubleTarget() {
val = rnd.RndDouble();
}
//hàm khởi to giá trị mục tiêu xác ịnh
public DoubleTarget(double d) {
val = d;
}
//hàm tính ộ thích nghi của ối tợng theo ngữ nghĩa mong muốn
//càng gần với mục tiêu càng có ộ thích nghi cao
public double eval(IIndividual i) {
MyDouble o1 = i.SpecValue as MyDouble;
if (o1 == null) return 0;
return 1 / ((o1.Val - val) * (o1.Val - val));
Trang 11
}
//tác vụ tính tốn trị của cá thể
public double getVal(IIndividual i) {
MyDouble o1 = i.SpecValue as MyDouble;
if (o1 == null) return 0;
return o1.Val;
}
//hàm tr về giá trị mục tiêu
public double getValue() {
return val;
}
//hàm gii mã ối tợng mục tiêu ra chuỗi vn bn
public override String ToString() {
String buf = String.Format("Giá trị mong muốn : {0:f5}", val);
return buf;
}
}
16. Hiện thực ối tợng Factory cho ứng dụng nh sau :
Dời chuột về phần tử gốc của cây Project trong cửa sổ “Solution Explorer”, ấn
phi chuột vào nó ể hiển thị menu lệnh, chọn chức nng Add.Class ể hiển thị
cửa sổ “Add New Item”, chọn mục “Class”, hiệu chỉnh tên class là
DoublePopFactory.cs, chọn button Add ể máy to 1 class mới. Viết code cho
class này nh sau :
using BaiTH6.GenLib;
...
class DoublePopFactory : IPopulationFactory {
//hàm to ối tợng mục tiêu
public ITarget createTarget() {
return new DoubleTarget();
}
//hàm to thế hệ có size cá thể ngẫu nhiên
public IPopulation createRandomPopulation(int size) {
//to 1 thế hệ rỗng
IPopulation pop = new Population();
//lặp thêm từng cá thể vào thế hệ
for (int i = 0; i < size; i++) {
pop.add(new DoubleIndividual());
}
return pop;
}
}
17. Nếu cửa sổ ToolBox cha hiển thị chi tiết, chọn menu View.Toolbox ể hiển thị
nó (thờng nằm ở bên trái màn hình). Click chuột vào button
(Auto Hide)
nằm ở góc trên phi cửa sổ ToolBox ể chuyển nó về chế ộ hiển thị thờng
trực.
18. Duyệt tìm phần tử Button trong cửa sổ ToolBox, chọn nó và v nó ở góc trên trái
của Form. Vào cửa sổ thuộc tính của Button và hiệu chỉnh li thuộc tính Text =
Trang 12
"Start", thuộc tính (Name) = btnStart. To hàm xử lý sự kiện Click trên Button
rồi viết on code kiểm thử thuật gii tiến hóa nh sau :
using System.IO;
using BaiTH6.GenLib;
...
private void btnStart_Click(object sender, EventArgs e){
int popSize = 20;
int nbGens = 10;
//to ối tợng qun lý file ể ghi dữ liệu
StreamWriter oFile = new StreamWriter("data.txt", true, Encoding.Unicode);
//xuất số cá thể của mỗi thế hệ ra file
oFile.WriteLine("Ta sử dụng cộng ồng có " + popSize + " cá thể");
//to ối tợng Factory cho ứng dụng
IPopulationFactory pf = new DoublePopFactory();
//nhờ Factory to ngẫu nhiên thế hệ ầu tiên
IPopulation pop = pf.createRandomPopulation(popSize);
//nhờ Factory to ối tợng mục tiêu cần hội tụ tới
ITarget vc = pf.createTarget();
//xuất ối tợng mục tiêu ra file
oFile.WriteLine(vc);
//lặp tiến hóa thế hệ với số lầ lặp xác ịnh
for (int i = 0; i < nbGens; i++)
{
//xuất thế hệ hiện hành ra file
oFile.WriteLine("Thế hệ " + i + ":");
oFile.WriteLine(pop);
pop = pop.evoluer(vc);
}
//xuất thế hệ cuối cùng ra file
oFile.WriteLine("Kết qu : " + pop);
//óng file
oFile.Close();
}
19. Dịch và chy chng trình. Nếu có lỗi thì sửa, nếu hết lỗi thì chng trình s
chy. Chức nng của chng trình là to thử 1 thế hệ gồm popSize cá thể, cho
nó tiến hóa nbGen chu kỳ, mỗi chu kỳ tiến hóa chng trình xuất giá trị ặc
trng của các cá thể của thế hệ hiện hành ra file ể chúng ta kiểm tra.
20. Dùng trình WordPad mở file data.txt trong th mục chứa file kh thi của
chng trình, quan sát xem giá trị mục tiêu là bao nhiêu, giá trị ặc trng ban
ầu của từng cá thể, giá trị ặc trng của các cá thể theo từng thế hệ và giá trị
ặc trng của các cá thể ở thế hệ cuối cùng. So sánh xem chúng có gần sát với
giá trị mục tiêu không ?