Trang 1 MÔN : CÁC MẪU THIẾT KẾ H ỚNG ỐI T ỢNG Bài thực hành số 7.1 : Tiến hóa các biểu thức về biểu thức mục tiêu I. Mục tiêu : Giúp SV làm quen cách áp dụng gi i thuật tiến hóa vào lo i cá thể xác ịnh : biểu thức i số. II. Nội dung : Áp dụng thuật gi i tiến hóa tổng quát ể thử tiến hóa các cá thể có giá trị ặc tr ng là biểu thức ngẫu nhiên ban ầu về biểu thức mục tiêu theo nghĩa giá trị của chúng gần bằng với giá trị của biểu thức mục tiêu nhất. 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ế ợc dùng trong bài thực hành này ể có thể dùng l i các mẫu này trong bất kỳ vị trí nào của ch ng trình mới cần xây dựng. IV. Qui trình xây dựng ch ng trình 1. Ch y 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 ph i, thiết lập th mục chứa Project trong listbox "Location", nhập tên Project vào textbox "Name:" (td. BaiTH7), click button OK ể t o 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à quá trình lặp 4 thao tác t o mới/xóa/hiệu chỉnh thuộc tính/t o hàm xử lý sự kiện cho từng ối t ợng cần dùng trong form. Ta s xây dựng form giao diện ứng dụng sau. 4. Dùng l i th viện miêu t thuật gi i tiến hóa tổng quát ở bài thực hành 5.1 : cách chính quy nhất là sử dụng file *.dll miêu t th viện. Tuy nhiên ở ây ta chỉ dừng l i ở mức dùng l i mã nguồn của th viện. ph i chuột vào nó ể hiển thị menu lệnh, chọn chức n ng Add.New Folder ể t o 1 folder mới. ặt tên cho folder này là GenLib. Click ph i chuột vào folder mới vừa t o và chọn option Add.Existing Item, duyệt chọn các file *.cs trong th mục GenLib trong project BaiTH5 ã có ể copy chúng vào folder hiện hành. 5. Dùng l i phân hệ miêu t biểu thức ở bài thực hành 6.1 : cách chính quy nhất là sử dụng file *.dll miêu t phân hệ này. Tuy nhiên ở ây ta chỉ dừng l i ở mức dùng l i mã nguồn của phân hệ. ph i chuột vào nó ể hiển thị menu lệnh, chọn chức n ng Add.New Folder ể t o 1 folder mới. ặt tên cho folder này là Expression. Click ph i chuột vào folder mới vừa t o và chọn option Add.Existing Item, duyệt chọn các file *.cs trong th mục Expression trong project BaiTH6 ã có ể copy chúng vào
Trang 2 folder hiện hành (l u ý không copy file MyRandom.cs và dùng file này trong th mục GenLib ã có). 6. Hiện thực class ExprIndividual miêu t 1 cá thể có thuộc tính giá trị ặc tr ng là 1 biểu thức i số. ph i chuột vào nó ể hiển thị menu lệnh, chọn chức n ng Add.Class ể hiển thị cửa sổ Add New Item, chọn mục Class, hiệu chỉnh tên class là ExprIndividual.cs, chọn button Add ể máy t o 1 class mới. Viết code cho class này nh sau (l u ý các file mã nguồn ợc t o mới trong ứng dụng ều ph i dùng 2 lệnh : using BaiTH5.GenLib; using BaiTH6.Expression; vì chúng có dùng các phần tử trong 2 namespace cũ này): class ExprIndividual : AbstractIndividual //giá trị ặc tr ng là 1 biểu thức private IExpression specval; private static IExpressionFactory ef = new ExpressionFactory(); //hàm t o cá thể 1 cách ngẫu nhiên public ExprIndividual() specval = ef.createrandomexpression(); //hàm t o cá thể có giá trị ặc tr ng xác ịnh public ExprIndividual(IExpression specval) this.specval = specval; //hiện thực thuộc tính SpecValue public override Object SpecValue get return specval; set specval = (IExpression)value; //hàm gi i mã ối t ợng thành chuỗi v n b n public override String ToString() //return String.Format("vp=0:f4, fit=1:f4",valeurpropre, fitness); return String.Format("vp=0:s fp=1:f5\r\n", specval.tostring(), Fitness); //hàm phối giống với other public override IIndividual cross(iindividual other)
Trang 3 // on accã de directement à la valeur propre, pas la peine d'utiliser d'accesseur. IExpression e2 = other.specvalue as IExpression; if (e2!= null) IExpression ek = ef.createbinaryop(operator.div, ef.createbinaryop(operator.plus, specval, e2), ef.createconstant(2)); return new ExprIndividual(ek.simplify()); return clone(); //hàm ột biến public override void muter() //t o biểu thức mới ngẫu nhiên IExpression e2 = ef.createrandomexpression(); //theo trung bình cộng của mình với biểu thức mới specval = ef.createbinaryop(operator.div, ef.createbinaryop(operator.plus, specval, e2), ef.createconstant(2)); specval = specval.simplify(); //hàm nhân b n theo mẫu Prototype public override IIndividual clone() IIndividual ei = new ExprIndividual(specVal); ei.fitness = Fitness; return ei; 7. Hiện thực ối t ợng mục tiêu mà các biểu thức muốn hội tụ về. ph i chuột vào nó ể hiển thị menu lệnh, chọn chức n ng Add.Class ể hiển thị cửa sổ Add New Item, chọn mục Class, hiệu chỉnh tên class là FuncTarget.cs, chọn button Add ể máy t o 1 class mới. Viết code cho class này nh sau : class FuncTarget : ITarget //giá trị mục tiêu private double value; //danh sách trị của các biến ợc dùng private IVarList env; // ối t ợng t o số ngẫu nhiên duy nhất trong toàn ch ng trình private static MyRandom rnd = MyRandom.getInstance();
Trang 4 private static IExpressionFactory ef = new ExpressionFactory(); //hàm khởi t o public FuncTarget() value = rnd.rnddouble(); env = ef.createrandomvarlist(); //hàm tính toán giá trị cá thể public double getval(iindividual i) IExpression e = i.specvalue as IExpression; if (e == null) return 0; return e.eval(env); //hàm tính toán cá thể public double eval(iindividual i) IExpression e = i.specvalue as IExpression; if (e == null) return 0; double r1 = e.eval(env); return 1 / ((value - r1) * (value - r1)); //hàm gi i mã ối t ợng thành chuỗi v n b n public override String ToString() return String.Format("Ta tìm biểu thức có giá trị : 0:f5 nếu dùng giá trị các biến 1:s", value, env.tostring()); 8. Hiện thực class Factory chuyên t o thế hệ các cá thể mà mỗi cá thể có giá trị ặt tr ng là biểu thức. ph i chuột vào nó ể hiển thị menu lệnh, chọn chức n ng Add.Class ể hiển thị cửa sổ Add New Item, chọn mục Class, hiệu chỉnh tên class là ExprPopFactory.cs, chọn button Add ể máy t o 1 class mới. Viết code cho class này nh sau : class ExprPopFactory : IPopulationFactory //hàm t o ối t ợng mục tiêu public ITarget createtarget() return new FuncTarget(); //hàm t o thế hệ có size cá thể ngẫu nhiên public IPopulation createrandompopulation(int size)
Trang 5 IPopulation pop = new Population(); for (int i = 0; i < size; i++) pop.add(new ExprIndividual()); return pop; 9. Nếu cửa sổ ToolBox ch a 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 ph i cửa sổ ToolBox ể chuyển nó về chế ộ hiển thị th ờng trực. 10. 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 l i thuộc tính Text = "Start", thuộc tính (Name) = btnstart. T o hàm xử lý sự kiện Click trên Button rồi viết o n code kiểm thử gi i thuật tiến hóa các biểu thức i số nh sau : private void btnstart_click(object sender, EventArgs e) int popsize = 20; //số cá thể trong từng thế hệ int nbgens = 10; //số thế hệ cần tiến hóa //t o ối t ợng qu n 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ể"); //t o ối t ợng Factory cho ứng dụng IPopulationFactory pf = new ExprPopFactory(); //nhờ Factory t o ngẫu nhiên thế hệ ầu tiên IPopulation pop = pf.createrandompopulation(popsize); //nhờ Factory t o ố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 giá trị thế hệ hiện hành ra file ofile.writeline("thế hệ " + i + ":"); OutExprPop(oFile, pop, vc); pop = pop.evoluer(vc); //xuất giá trị thế hệ cuối cùng ra file ofile.writeline("kết qu : "); OutExprPop(oFile, pop, vc); //xuất thế hệ cuối cùng ra file ofile.writeline("các biểu thức kết qu : " + pop); ofile.writeline("=========================================================="); // óng file
Trang 6 ofile.close(); private void OutExprPop(StreamWriter ofile, IPopulation pop, ITarget vc) int cnt = pop.size(); FuncTarget ft = (FuncTarget)vc; for (int i = 0; i < cnt; i++) ofile.writeline(ft.getval(pop[i]) + ", "); 11. Thêm các lệnh using sau vào ầu file Form1.cs : using BaiTH6.GenLib; using BaiTH7.Expression; using System.IO; 12. Dịch và ch y ch ng trình. Nếu có lỗi thì sửa, nếu hết lỗi thì ch ng trình s ch y. Mỗi lần ng ời dùng click chuột vào button, ch ng trình s t o 1 biểu thức ngẫu nhiên làm mục tiêu tiến hóa ến, sau ó ch ng trình t o thế hệ ban ầu gồm nhiều cá thể mà giá trị ặc tr ng là biểu thức ngẫu nhiên. Cuối cùng ch ng trình thử ch y gi i thuật tiến hóa trên thế hệ ban ầu nhiều lần. Cuối cùng ch ng trình xuất thế hệ cuối cùng ra file ể ta kiểm tra kết qu và ánh giá mức ộ hội tụ của gi i thuật tiến hóa. 13. Dùng trình WordPad mở file data.txt trong th mục chứa file kh thi của ch ng trình, quan sát xem các biểu thức kết qu và giá trị của chúng có gần giống với biểu thức mục tiêu không.