Thiết kế ứng dụng

Một phần của tài liệu Giai thuật di truyền (Trang 29 - 50)

2.1.Thiết kế giao diện người dùng

Giao diện người dùng của ứng dụng đơn giản gồm các form sau:  Form Chính

Với chức năng chính là tìm kiếm tuyến đường đi ngắn nhất, ngoài ra còn chứa các menu để mở ra những chức năng khác của ứng dụng.

Các sử dụng:

Để tìm kiếm tuyến đường đi ngắn nhất đầu tiên phải chọn những địa

chỉ vào danh sách tìm kiếm ở box “dữ liệu” bằng cách chọn địa chỉ trong “Combo Box” rồi ấn nút “thêm”, người dùng có thể xóa địa chỉ

Combo Box

chọn bản ghi

trong danh sách bằng cách chọn bản ghi sau đó ấn nút xóa sau đó nhập số cá thể và số thế hệ rồi ấn nút tìm kiếm. Khi tiến trình tìm

kiếm kết thúc kết quả sẽ được hiển thị ở box “kết quả”.

 Form cài đặt:

Điền những tham số cài đặt của giải thuật rồi ấn nút “Lưu cài đặt”.

 Form quản lý địa chỉ:

Hình 18

Form này có các chức năng chính là thêm sửa xóa các địa chỉ. Ấn nút thêm để thêm mới địa chỉ, chọn một bản ghi rồi ấn nút sửa để sửa và chọn một bản ghi rồi ấn nút xóa để xóa địa chỉ.

 Form sửa địa chỉ:

Sửa lại thông tin rồi ấn nút “lưu” để sửa.

 Form thêm địa chỉ:

Điền đầy đủ thông tin rồi ấn nút “lưu” để thêm. Hình 20

2.2.Thiết kế các đối tượng của bài toán Bài toán gồm 3 đối tượng chính sau: Bài toán gồm 3 đối tượng chính sau:

Đối tượng Gene (đại diện cho đối tượng gene) gồm các thuộc tính và

phương thức:

o Name (tên địa chỉ)

o Code (ký tự mã hóa của địa chỉ)

o Latitude (vĩ độ của địa chỉ)

o Longitude (kinh độ của địa chỉ)

o Phương thức DistanceTo(obj) (phương thức tính khoảng cách đến một địa chỉ khác) trong đó obj là một gene khác

Đối tượng Chromosome (đại diện cho đối tượng nhiễm sắc thể) gồm

các thuộc tính và phương thức:

o Genes (mảng gene là lời giải có thể của bài toán)

o Fitness (giá trị hàm đánh giá của nhiễm sắc thể)

o Length (Chiều dài của nhiễm sắc thể)

o Phương thức Mutate() (Toán tử đột biến của nhiễm sắc thể)

o Phương thức Inversion() (toán tử đảo vị trí của nhiễm sắc thể)

o Phương thức Hybrid(obj,type) (toán tử lai ghép của nhiễm sắc thể) trong đó obj là một nhiễm sắc thể khác và type là kiểu lai

ghép

Đối tượng Populations (đại diện cho đối tượng quần thể) gồm các

thuộc tính và phương thức:

o _popsize (kích thước của quần thể)

o _generation (số thế hệ phát triển của quần thể)

o _listGene (danh sách gene dùng cho việc tạo mới nhiễm sắc

thể)

o _populations (quần thể bao gồm các cá thể mỗi cá thể tượng

ứng với một nhiễm sắc thể)

o Xbest (Cá thể tốt nhất của quần thể qua mọi thế hệ)

o Phương thức CreatePopulations() (hàm khởi tạo quần thể)

o Phương thức NaturaSelection() (hàm thực hiện chọn lọc tự

o Phương thức HybridAndMutate() (hàm thực hiện các toán tử lai

ghép và đột biến trên quần thể)

o Phương thức GaFuntion() (thủ tục thực thi giải thuật di truyền)

o Phương thức CreateChromosome() (hàm tạo một nhiễm sắc

thể) 3. Cài đặt ứng dụng

3.1. Cài đặt các đối tượng 3.1.1. Đối tượng Gene 3.1.1. Đối tượng Gene

public class Gene {

public string Name { get; set; }//tên địa chỉ

public string Code { get; set; }//ký tự mã hóa của địa chỉ public double Latitude { get; set; }//vĩ độ của địa chỉ public double Longitude { get; set; }//kinh độ của địa chỉ public double DistanceTo(Gene gene);

}

Cài đặt phương thức DistanceTo(Gene gene)

public double DistanceTo(Gene gene) {

/*công thức tính khoảng cách giữa 2 điểm * Δlat = lat2− lat1; Δlong = long2− long1

* a = sin²(Δlat/2) + cos(lat1).cos(lat2).sin²(Δlong/2) * c = 2.atan2(√a , √(1−a)); d = R.c (km)

*/

const int r = 6371; // bán kính trái đất Km

var dLat = gene.Latitude.ToRad() - Latitude.ToRad(); var dLon = gene.Longitude.ToRad() - Longitude.ToRad(); var a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Sin(dLon / 2) * Math.Sin(dLon / 2) * Math.Cos(Latitude.ToRad()) * Math.Cos(gene.Latitude.ToRad());

var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); var d = r * c;

return d; }

Trong đó hàm ToRad() là phương thức quy đổi độ ra Radians được định nghĩa trong lớp Comon.

3.1.2. Đối tượng Chromosome

public class Chromosome {

public readonly Gene[] Genes;

private readonly Random _ramdom = new Random(); public double Fitness { get; private set; } public int Length{ get{ return Genes.Length; }} public Chromosome(Gene[] genes)();

public void Mutate(); public void Inversion();

public Chromosome[] Hybrid(Chromosome chromosome, HybridType type);

}

- Cài đặt phương thức Mutate()

/// <summary>

/// phương thức đột biến của nhiễm sắc thể

/// Bằng cách hoán đổi ngẫu nhiên vị trí của 2 gene /// </summary>

public void Mutate() {

var mutateValue = _ramdom.Next(0, 100); if (mutateValue < Common.MutateRate) {

var pos1 = _ramdom.Next(Length - 1); var pos2 = _ramdom.Next(Length - 1); while (pos1 == pos2)

{

pos1 = _ramdom.Next(Length - 1); pos2 = _ramdom.Next(Length - 1); }

var geneTemple = Genes[pos1]; Genes[pos1] = Genes[pos2]; Genes[pos2] = geneTemple; Fitness = Genes.CallFitness(); }

Trong đó Common.MutateRate là tỉ lệ đột biến trên từng cá thể và hàm CallFitness() là hàm tính độ thích nghi của cá thể được định nghĩa trong lớp Comom.

- Cài đặt phương thức Inversion()

/// <summary>

/// phương thức hoán đổi của nhiễm sắc thể

/// Bằng cách đảo ngược vị trí của một đoạn trong nhiễm sắc thể /// </summary>

public void Inversion() {

var inversionValue = _ramdom.Next(0, 100); if (inversionValue < Common.InversionRate) {

var pos1 = _ramdom.Next(Length); var pos2 = _ramdom.Next(Length); while (pos1 == pos2)

{ pos1 = _ramdom.Next(Length); pos2 = _ramdom.Next(Length); } if (pos1 > pos2) { var x = pos1; pos1 = pos2; pos2 = x; }

for (var i = pos1; i < pos2; i++) {

for (var j = pos2; j > pos1; j--) {

var geneTemple = Genes[i]; Genes[i] = Genes[j]; Genes[j] = geneTemple; } } Fitness = Genes.CallFitness(); } }

Trong đó Common.InversionRate là tỉ lệ hoán đổi trên từng cá thể: - Cài đặt phương thức Hybrid(obj,type).

Obj là đối tượng Chromosome còn type là loại phương thức lai ghép ở ứng

dụng này định nghĩa hai loại đó là PMX và OX.

public Chromosome[] Hybrid(Chromosome chromosome, HybridType type) {

var father = new Gene[Length]; var mother = new Gene[Length]; Genes.CopyTo(father, 0);

chromosome.Genes.CopyTo(mother, 0); var pos1 = _ramdom.Next(Length); var pos2 = _ramdom.Next(Length); while (pos1 == pos2){

pos1 = _ramdom.Next(Length); pos2 = _ramdom.Next(Length); }

if (pos1 > pos2){

var x = pos1;pos1 = pos2;pos2 = x; }

switch (type){

case HybridType.Pmx:{

for(var i = pos1; i < pos2; i++){ for(int j = 0; j < Length; j++){ if(j == j) continue; if(father[j].Code == mother[i].Code) father[j] = father[i]; if(mother[j].Code == father[i].Code) mother[j] = mother[i]; }

var geneTemple = father[i]; father[i] = mother[i]; mother[i] = geneTemple; } break; } case HybridType.Ox:{ var k = pos2; var t = pos2; var s = 0; while (s < Length) { var check = false;

for(var i = pos1; i < pos2; i++){ if(chromosome.Genes[k].Code

==father[i].Code) check = true;

} if(!check) { father[t] = chromosome.Genes[k]; t++; if (t >= Length) t = 0; } k++; if (k >= Length) k = 0; s++; } k = pos2; t = pos2; s = 0; while (s < Length) var check = false;

for(var i = pos1; i < pos2; i++){

if(Genes[k].Code == mother[i].Code) check = true; } if(!check) { mother[t] = Genes[k]; t++; if (t >= Length) t = 0; } k++; if (k >= Length) k = 0; s++; } break; } }

var children = new Chromosome[2]; children[0] = new Chromosome(father); children[1] = new Chromosome(mother); return children;

3.1.3. Đối tượng Populations

public class Populations {

// thuộc tính

private readonly int _popsize; private readonly int _generation;

private readonly List<Gene> _listGenes; private List<Chromosome> _populations; public Chromosome XBest;

private readonly Random _ramdom; // khởi tạo quần thể

public Populations(int popsize, int generation, List<Gene> listGenes);

public Populations(List<Gene> listGenes); // Phương thức

private void CreatePopulations(); private void NaturalSelection(); private void HybridAndMutate();

public void GaFuntion(ProgressBar progressBar, out double miliSec);

private Chromosome CreateChromosome(); }

- Cài đặt phương thức CreateChromosome()

private Chromosome CreateChromosome() {

var listg = _listGenes.ToArray(); var k = 0;

while (k < listg.Length / 2) {

var pos1 = _ramdom.Next(listg.Length); var pos2 = _ramdom.Next(listg.Length); var geneTemple = listg[pos1];

listg[pos1] = listg[pos2]; listg[pos2] = geneTemple; k++;

}

return new Chromosome(listg); }

Đây là phương thức tạo ngẫu nhiên 1 cá thể, phương thức này được gọi khi khởi tạo quần thể ban đầu.

- Cài đặt phương thức CreatePopulations()

private void CreatePopulations() {

while (_populations.Count < _popsize) {

var s = CreateChromosome(); _populations.Add(s);

} }

Đây là phương thức khởi tạo quần thể ban đầu gồm _popsize cá thể ngẫu

nhiên.

- Cài đặt phương thức NaturalSelection()

private void NaturalSelection() {

var t = _populations.Count;

_populations = _populations.Distinct()

.OrderBy(p => p.Fitness).ToList();

var removeNumber = (t * (100 - Common.SelectionRate)) / 100; var d = t - _populations.Count;

removeNumber = removeNumber - d; if (removeNumber > 0)

{

var index = _populations.Count - removeNumber; _populations.RemoveRange(index, removeNumber); }

}

Trong đó Common.SelectionRate là tỉ lệ chọn lọc tự nhiên, việc chọn lọc tự

nhiên như sau: trước tiên dùng phương pháp loại bỏ những cá thể giống nhau trong quần thể. Sau đó tính toán số lượng cá thể cần loại bỏ theo tỉ lệ chọn lọc tự nhiên, rồi trừ đi những cá thể bi trùng lặp. Nếu con số này lớn hơn 0 thi loại bỏ bằng ấy cá thể xấu nhất trong quần thể sau đó mới thực hiện các toán tử lai ghép, đột biến.

- Cài đặt phương thức HybridAndMutate()

private void HybridAndMutate() {

var listChilds = new List<Chromosome>();

while (_populations.Count + listChilds.Count <= _popsize) { var c1 = _ramdom.Next(_populations.Count - 1); var c2 = _ramdom.Next(_populations.Count - 1); while (c1 == c2) { c1 = _ramdom.Next(_populations.Count - 1); c2 = _ramdom.Next(_populations.Count - 1); }

var type = (HybridType) _ramdom.Next(1, 2);

var childs = _populations[c1].Hybrid(_populations[c2], type);

foreach (var ch in childs) { ch.Mutate(); ch.Inversion(); } listChilds.AddRange(childs); } _populations.AddRange(listChilds); }

Thực hiện lai ghép cho tới khi kích thước quần thể bằng kích thước của quần thể ban đầu thì dừng lại, việc đột biến và hoán đổi trong khi các con cái được sinh ra, tỉ lệ đột biến và hoán đổi trên mỗi cá thể là như nhau.

- Cài đặt phương thức chính của giải thuật di truyền GaFuntion()

public void GaFuntion(ProgressBar progressBar, out double sec) { var tg = DateTime.Now; CreatePopulations(); var k = 0; var t = 1; _populations.Sort((a, b) => a.Fitness.CompareTo(b.Fitness)); XBest = _populations.FirstOrDefault(); progressBar.Minimum = 0; progressBar.Value = 0; progressBar.Maximum = _generation; progressBar.Step = 1;

while (k <= _generation) { NaturalSelection(); HybridAndMutate(); _populations.Sort((a, b) => a.Fitness .CompareTo(b.Fitness)); var x = _populations.FirstOrDefault();

if (x.Fitness < XBest.Fitness) XBest = x; progressBar.Increment(1);

k++; }

sec = (DateTime.Now - tg).TotalSeconds; }

Đây là thủ tục chính của giải thuật di truyền những tham số chính của giải thuật đều được truyền vào khi khởi tạo đối tượng, tham số này được lưu trong phần cài đặt của chương trình, ngoài ra thủ tục này còn có một tham số

đó là thanh Progress Bar (để thông báo tiến trình hoạt động cho người

dùng) và thời gian kết thúc giải thuật. Thủ tục thực hiện theo đúng sơ đồ của

giải thuật di truyền tiêu chuẩn đã nêu ở Chương I.

3.2. Cài đặt chương trình

Khi khởi động chương trình đối tượng GeneServices và đối tượng SettingServices được khởi tạo, sau đó những tham số của phần cài đặt được nạp vào thông qua đối tượng SettingServices, còn danh sách các địa chỉ cũng được tải lên thông qua đối tượng GeneServices.

3.2.1. Cài đặt lớp thao tác cơ sở dữ liệu

Việc lưu trữ và truy vấn thông tin của chương trình được lưu với định dạng XML bao gồm thông tin cài đặt của chương trình và thông tin quản lý địa chỉ.

Việc thao tác với dữ liệu thông qua hai lớp đó là :

Lớp GeneServices việc lấy, thêm, sửa, xóa và lưu thông tin

được thực hiện qua các phương thức sau: - ServicesResult<List<Gene>> GetAll();

- ServicesResult<Gene> GetByCode(string code);

- ServicesResult<bool> Edit(Gene gene);

- ServicesResult<bool> Remove(Gene gene);

- ServicesResult<bool> Remove(string code);

Lớp SettingServices việc truy vấn và lưu những thông tin cài

đặt của chương trình được thực hiện thông qua phương thức

get() và set() của các thuộc tính của lớp này bao gồm các

thuộc tính sau:

- public int MutateRate;

- public int SelectionRate;

- public int InversionRate;

- public int DefaultPopulationSize;

- public int DefaultGeneration;

3.2.2. Cài đặt các form

Như đã thiết kế ở phần giao diện người dùng phần xử lý cho các chức năng của các form được cài đặt như sau:

 Form chính

Phần xử lý quan trọng nhất của form này cũng như của chương

trình nằm trong sự kiện Click của nút tìm kiếm. Việc khởi tạo

quần thể và thiết lập một số tham số đầu vào của giải thuật di truyền đều được thực hiện trong sự kiện này.

private void btnSearch_Click(object sender, EventArgs e) {

Populations pop = null; if (_listGenes.Count > 0) {

int popSize; int generation;

if (int.TryParse(txtPopSize.Text,out popSize) && int.TryParse(txtGeneration.Text,out generation)) {

pop = new Populations(popSize,

generation, _listGenes); }

else {

if (MessageBox.Show("Số thế hệ hoặc số cá thể nhập vào không đúng định dạng.\nBạn có muốn tiếp tục với giá trị mặc định đã được cài đặt?","Thông báo",

MessageBoxButtons.YesNo) == DialogResult.Yes) {

pop = new Populations(_listGenes); }

}

if (pop != null) {

double sec;

pop.GaFuntion(progressBar1, out sec); _xBest = pop.XBest; OutPut(); } } else {

MessageBox.Show("Danh sách địa điểm trống,hãy thêm các địa điểm để bắt đầu!");

} }

 Form cài đặt

Việc lưu trữ các cài đặt của chương trình rất đơn giản được thực

hiện ở sự kiện Click của nút “lưu cài đặt” thông qua các phương thức get, set của thuộc tính trong đối tượng SettingServices:

private void btnSave_Click(object sender, EventArgs e) {

int inversionRate, maxGeneration, maxPopulationSize, mutateRate, selectionRate;

if (int.TryParse(txtInversionRate.Text, out inversionRate) && int.TryParse(txtMaxGeneration.Text,

out maxGeneration) &&

int.TryParse(txtMaxPopulationSize.Text, out maxPopulationSize) && int.TryParse(txtMutateRate.Text,

out mutateRate) && int.TryParse(txtSelectionRate.Text,

{ Services.SettingServices .InversionRate = inversionRate; Services.SettingServices .MutateRate = mutateRate; Services.SettingServices .SelectionRate = selectionRate; Services.SettingServices .DefaultGeneration = maxGeneration; Services.SettingServices .DefaultPopulationSize = axPopulationSize; MessageBox.Show("Lưu cài đặt thành công!"); Close();

} else {

MessageBox.Show("Các tham số không đúng định rạng! xin hãy kiểm tra lại.");

} }

 Form quản lý địa chỉ

Việc thêm sửa xóa địa chỉ được thực hiện thông qua đối tượng

GeneServices.

- Thêm và Sửa địa chỉ được xử lý chung trong một sự kiện: private void btnSave_Click(object sender, EventArgs e) {

double x, y;

if (!string.IsNullOrEmpty(txtName.Text) && double.TryParse(txtX.Text, out x) && double.TryParse(txtY.Text, out y)) {

if (string.IsNullOrEmpty(_codeEditing)) { var gene = new Gene

{ Name = txtName.Text, Latitude = x, Longitude = y }; Services.GeneServices.Add(gene); } else {

var gene = new Gene { Name = txtName.Text, Latitude = x, Longitude = y, Code = _codeEditing }; Services.GeneServices.Edit(gene); } this.Close(); } else {

MessageBox.Show("thông tin sai định rạng, hoạc trống, hay kiểm tra lại không tin để tiếp tục");

} }

-Xóa địa chỉ:

private void btnDelete_Click(object sender, EventArgs e) {

var row = gridList.SelectedRows; if (row.Count > 0)

{

if (MessageBox.Show("Bạn có chắc muốn" + " xóa bản ghi này?", "thông báo",

MessageBoxButtons.YesNo) == DialogResult.Yes) { var code=row[0].Cells[1].Value.ToString(); Services.GeneServices.Remove(code); _source.ResetBindings(true); } } else { MessageBox.Show("Không có bản ghi" + " nào được chọn!", "thông báo"); }

4. Kiểm thử ứng dụng

Kiểm thử ứng dụng với những bộ dữ liệu sau với cấu hình hệ thống: Hệ điều hành Windows 7 64bit, bộ vi xử lý Intel® Core™ i3 2,5GHZ, bộ nhớ trong 4 GB:

4.1. Bộ dữ liệu 1

4.2. Bộ dữ liệu 2

Hình 24

4.3. Bộ dữ liệu 3

Hình 26

C - KẾT LUẬN

Giải thuật di truyền là kỹ thuật chung giúp giải quyết bài toán bằng cách mô phỏng sự tiến hóa trong tự nhiên dựa theo thuyết tiến hóa của Darwin trong điều kiện quy định sẵn của môi trường. Mục tiêu của giải thuật di truyền không nhằm đưa ra lời giải chính xác mà giải thuật đưa ra lời giải tương đối tối ưu.

Kết quả chính của đồ án là tìm hiểu và nghiên cứu đưa ra những vấn đề sau:  Nghiên cứu giải thuật di truyền.

 Nghiên cứu bài toán Người đưa thư.

 Cài đặt ứng dụng mô tả giải thuật di truyền giải quyết bài toán Người đưa thư.

TÀI LIỆU THAM KHẢO

Trong quá trình thực hiện đồ án em đã tham khảo những nguồn tài liệu chính sau để hoàn thành đồ án của mình:

 Tài liệu của TS.Phạm Thanh Hà cung cấp

 Từ điển Bách khoa toàn thư Wikipedia website: http://wikipedia.org  Công cụ tìm kiếm Google Search website: http://google.com.vn

Một phần của tài liệu Giai thuật di truyền (Trang 29 - 50)

Tải bản đầy đủ (PDF)

(50 trang)