Microsoft Word Bai 9 1 docx Trang 1 MÔN CÁC MẪU THIẾT KẾ HỚNG ỐI TỢNG Bài thực hành số 9 1 Tiến hóa các tập luật chi ể tìm ờng i trong mê cung I Mục tiêu Giúp SV làm quen cách áp dụng gii t[.]
Trang MÔN : CÁC MẪU THIẾT KẾ HỚNG ỐI TỢNG Bài thực hành số 9.1 : Tiến hóa tập luật chi ể tìm ờng i mê cung I Mục tiêu : Giúp SV làm quen cách áp dụng gii thuật tiến hóa vào loi cá thể xác ịnh : tập luật miêu t ờng i agent mê cung II Nội dung : Tổng hợp kết qu thực hành 5.1 8.1 ể thử tiến hóa tập luật miêu t ờng i agent mê cung ban ầu tập luật tối u III Chuẩn ầu : Nắm vững tính chất, cơng dụng mẫu thiết kế ợc dùng thực hành ể dùng li mẫu vị trí chng trình cần xây dựng IV Qui trình xây dựng chng trình Chy VS Net, chọn menu File.Open.Project ể mở li Project thực hành 8.1 Copy li file mã nguồn ã viết thực hành 7.1 sang project hành : Dời chuột phần tử gốc Project cửa sổ “Solution Explorer”, ấn phi chuột vào ể hiển thị menu lệnh, chọn chức nng Add.New Folder ể to folder ặt tên cho folder BaiTH5 Click phi chuột vào folder vừa to chọn option Add.Existing Item, duyệt chọn file *.cs th mục qun lý project BaiTH7 ã có ể copy chúng vào folder hành (chú ý không cần copy file Program.cs, Form1.cs) Vào folder BaiTH5 Project BaiTH81, duyệt xem hiệu chỉnh (nếu cần) nội dung file mã nguồn theo nội dung nh sau : //nội dung file IEnvironment.cs interface IEnvironment { //tác vụ tính toán trị cá thể double getVal(IIndividual ind); //tác vụ tính tốn cá thể double eval(IIndividual ind); } //nội dung file IIndividual.cs interface IIndividual : IComparable { //thuộc tính luận lý SpecValue : ọc Object SpecValue { get; set; } //thuộc tính luận lý Fitness : ọc/ghi double Fitness { get; set; } //thuộc tính miêu t bị ột biến bool Muted { get; set; } //hàm phối giống với other Trang IIndividual cross(IIndividual other); //hàm ột biến void muter(); //hàm to ối tợng 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(); } //nội dung file Individual.cs class Individual : IIndividual { //giá trị ặc trng cá thể private MyDouble spVal; //ộ thích nghi 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 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 public Individual() { this.spVal = new MyDouble(rnd.RndDouble()); } //hàm khởi to cá thể có giá trị ặc trng xác ịnh public Individual(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 Trang { 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ụ 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 MyDouble o2 = other.SpecValue as MyDouble;//giá trị ặc trng ối tác //to cá thể if (o1 == null && o2 == null) return new Individual(new MyDouble(0)); if (o1 == null) return other; if (o2 == null) return this; return new Individual(new MyDouble((o1.Val + o2.Val) / 2)); } //hàm ột biến cá thể hành public void muter() { //ột biến tối a 10% biên ộ giá trị ặc trng // spVal += (rnd.RndDouble() < 0.5 ? : -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(); } Trang //hàm to ối tợng theo c chế nhân bn vơ tính (dùng mẫu Prototype) public IIndividual clone() { return new Individual(spVal); } } //nội dung file IPopulation.cs interface IPopulation { //hàm tr số cá thể int size(); //hàm thêm cá thể vào hệ void add(IIndividual individu); //hàm xuất giá trị các thể String OutValue(IEnvironment cible); //hàm gii mã ối tợng thành chuỗi vn bn String ToString(); //hàm tiến hóa sang hệ IPopulation evoluer(IEnvironment cible); } //nội dung file IPopulationFactory.cs interface IPopulationFactory { IPopulation createRandomPopulation(int size); } //nội dung file MyDouble.cs 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 chuỗi vn bn public override String ToString() { String buf = String.Format("{0:f5}", val); return buf; } } //nội dung file MyRandom.cs class MyRandom { //hàm khởi to private ể cấm bên to ối tợng MyRandom private MyRandom() { } Trang //thông tin dùng chung class private static MyRandom myrnd = new MyRandom(); public static MyRandom getInstance() { return myrnd; } //thông tin ối tợng private Random rnd = new Random(); public int RndInt() { return rnd.Next(); } public int RndInt(int n) { return rnd.Next(n); } public double RndDouble() { return rnd.NextDouble(); } } //nội dung file Population.cs class Population : IPopulation { //qun lý hệ cá thể class List NET private List individus = new List(); //dùng ối tợng to số ngẫu nhiên tồn chng trình private static MyRandom rnd = MyRandom.getInstance(); //hàm tr số cá thể public int size() { return individus.Count(); } //hàm thêm cá thể vào hệ public void add(IIndividual individu) { individus.Add(individu); } //hàm gii mã ối tợng thành chuỗi vn bn public String OutValue(IEnvironment target) { String buf = "["; bool fstart = true; for (int i = 0; i < individus.Count(); i++) if (fstart) { fstart = false; buf += String.Format("{0:f5}", target.getVal(individus[i])); } else buf += ", " + String.Format("{0:f5}", target.getVal(individus[i])); return buf + "]"; } //hàm gii mã ối tợng thành chuỗi vn bn public override String ToString() { String buf = "["; bool fstart = true; for (int i = 0; i < individus.Count(); i++) Trang if (fstart) { fstart = false; buf += individus[i].ToString(); } else buf += ", " + individus[i].ToString(); return buf + "]"; } //hàm tiến hóa sang hệ public IPopulation evoluer(IEnvironment cible) { //tính ộ thích nghi cá thể xếp chúng evaluer(cible); //to hệ Population pop = reproduire(); //cho 5% cá thể bị ột biến pop.muter(0.1); //tính li ộ thích nghi cá thể xếp chúng //pop.evaluer(cible); return pop; } //hàm tính ộ thích nghi cá thể xếp cá thể theo ộ thích nghi chúng private void evaluer(IEnvironment cible) { //lặp tính ộ thích nghi cá thể foreach (IIndividual ind in individus) { ind.Fitness = cible.eval(ind); } //sắp xếp cá thể theo ộ thích nghi chúng Sort(); } //hàm xếp thự tự 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) { List subl = individus.GetRange(1, individus.Count - 1); //chọn ngẫu nhiên cá thể thực ột biến foreach (IIndividual ind in subl) { if (rnd.RndDouble() < ratio) ind.muter(); Trang } } //hàm to hế private Population reproduire() { //chọn 20% cá thể có ộ thích nghi tốt int max = individus.Count() / 5; Population pop = new Population(); //cho chúng thành cá thể hệ for (int i = 0; i < max; i++) { pop.add(individus[i].clone()); } //lặp phối giống cặp cá thể ã có (chọn ngẫu nhiên) ể to thêm 80% cá thể 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; } } //nội dung file PopulationFactory.cs class PopulationFactory { public IPopulation createRandomPopulation(int size) { //to hệ rỗng IPopulation pop = new Population(); //lặp thêm cá thể vào hệ for (int i = 0; i < size; i++) { pop.add(new Individual()); } return pop; } } //nội dung file Target.cs class Target : IEnvironment { //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 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 Target() { val = rnd.RndDouble(); Trang } //hàm khởi to giá trị mục tiêu xác ịnh public Target(double d) { val = d; } //hàm tính ộ thích nghi ối tợng theo ngữ nghĩa mong muốn //càng gần với mục tiêu có ộ thích nghi cao public double eval(IIndividual i) { MyDouble o1 = i.SpecValue as MyDouble; if (o1 == null) return 0; return / ((o1.Val - val) * (o1.Val - val)); } //tác vụ tính toán trị cá thể public double getVal(IIndividual i) { MyDouble o1 = i.SpecValue as MyDouble; if (o1 == null) return 0; return o1.Val; } //hàm tr giá trị mục tiêu public double getValue() { return val; } //hàm gii mã ối tợng mục tiêu chuỗi vn bn public override String ToString() { String buf = String.Format("Giá trị mong muốn : {0:f5}", val); return buf; } } //nội dung file AbstractIndividual.cs abstract class AbstractIndividual : IIndividual { protected double fitness = 0.0; protected bool muted = false; public AbstractIndividual() { } //thuộc tính luận lý SpecValue : ọc public abstract Object SpecValue { get; set; } Trang 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ụ 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 theo mẫu Prototype public abstract IIndividual clone(); //hàm ột biến public abstract void muter(); //hàm phối giống với other public abstract IIndividual cross(IIndividual other); } Ở th mục gốc Project, thực class Score miêu t iểm tích lũy agent Viết code cho class nh sau (lu ý file mã nguồn ợc to ều phi dùng lệnh using BaiTH6; using BaiTH81.EditLaby; chúng có dùng phần tử namespace cũ này): class Score { //ịnh nghĩa cần dùng private const int DEFAULT_SCORE = 1; private const int DEFAULT_INCREMENT = 1; //iểm private int score; //hàm khởi to public Score() { score = DEFAULT_SCORE; } Trang 10 //hàm tham kho iểm public int getScore() { return score; } //hàm tng iểm public void incrementScore() { score += DEFAULT_INCREMENT; } } Ở th mục gốc Project, thực class Rule miêu t luật i agent Viết code cho class nh sau : class Rule : IComparable { //bng thông tin iều khiển private LabyItem[] conditions; //chiều di chuyển private Direction action; //hàm khởi to luật không xác ịnh public Rule() { conditions = new LabyItem[8]; } //hàm khởi to luật theo tham số xác ịnh public Rule(LabyItem[] cond, Direction dir) { conditions = cond; action = dir; } //hàm khởi to luật theo tham số xác ịnh chuỗi public Rule(String contenu, Direction dir) { conditions = new LabyItem[8]; for (int i = 0; i < contenu.Length; i++) { char symbol = contenu[i]; switch (symbol) { case '?': conditions[i] = LabyItem.ANY; break; case '.': conditions[i] = LabyItem.POINT; break; case ' ': Trang 13 }*/ public override bool Equals(Object obj) { if (this == obj) return true; if (obj == null) return false; Rule other = obj as Rule; if (other == null) return false; if (action == null) { if (other.action != null) return false; } else if (!action.Equals(other.action)) return false; if (!Array.Equals(conditions, other.conditions)) return false; return true; } //tác vụ so sánh tổng quát CompareTo public int CompareTo(Object obj) { if (this == obj) return 0; if (obj == null) return 1; Rule other = obj as Rule; if (other == null) throw new ArgumentException("Object is not a Item"); return -1; } } Ở th mục gốc Project, thực interface IController class Controller miêu t tập luật i agent Viết code cho interface class nh sau : interface IController { //chọn chiều di chuyển theo thơng tin dị ờng Direction ChooseAction(LabyItem[] sensors); //nhân bn vơ tính theo mẫu Prototype IController clone(); //ột biến luật void muter(double d); //to ối tợng Controller IController CreateSon(IController controller, double d); Trang 14 //hàm tr kích thớc tập luật int Size(); //hàm thêm luật vào danh sách luật bool add(Rule rule); //ịnh nghĩa indexer Rule this[int i] { get; set; } } class Controller : IController { //sử dụng ối tợng to số ngẫu nhiên theo mẫu Singleton private static MyRandom rnd = MyRandom.getInstance(); //tập luật Controller private List ruleset = new List(); //hàm chọn hớng i thích hợp public Direction ChooseAction(LabyItem[] sensors) { foreach (Rule r in ruleset) { if (r.matches(sensors)) return r.Action; } return Direction.STOP; } //hàm ột biến public void muter(double proba) { for (int i = 0; i < Size(); i++) { if (rnd.RndDouble() < proba) { ruleset[i] = ControlFactory.generateRandomRule(); } } } public Rule this[int i] { get { return ruleset[i]; } set { ruleset[i] = value; } } //hàm copy public IController copieCroisee(IController parent) { IController pere = (IController)parent; IController retour = clone(); int cr1 = rnd.RndInt(Size()); int cr2 = rnd.RndInt(pere.Size()); retour[cr1] = pere[cr2]; Trang 15 return retour; } //hàm to ối tợng ột biến public IController CreateSon(IController expr, double proba) { IController son = copieCroisee(expr); son.muter(proba); return son; } //hàm nhân bn vơ tính theo mẫu Prototype public IController clone() { IController retour = new Controller(); foreach (Rule r in ruleset) { retour.add(r.clone()); } return retour; } //hàm thêm luật vào danh sách luật public bool add(Rule rule) { try { ruleset.Add(rule); return true; } catch (Exception e) { return false; } } //hàm gi mã ối tợng thành chuỗi vn bn public override String ToString() { return ruleset.ToString(); } public List getRuleset() { return ruleset; } public void setRuleset(List ruleset) { this.ruleset = ruleset; } //hàm tr kích thớc tập luật public int Size() { return ruleset.Count; } Trang 16 //tác vụ tính giá trị hashcode cho phần tử public override int GetHashCode() { //tính giá trị hashcode cho phần tử tr return base.GetHashCode(); } /*public int hashCode() { const int prime = 31; int result = 1; result = prime * result + ((ruleset == null) ? : ruleset.hashCode()); return result; }*/ public bool Equals(Object obj) { if (this == obj) return true; if (obj == null) return false; Controller other = obj as Controller; if (other == null) return false; if (ruleset == null) { if (other.ruleset != null) return false; } else if (!ruleset.Equals(other.ruleset)) return false; return true; } } Ở th mục gốc Project, thực class ControlFactory phục vụ việc to ối tợng Controller Viết code cho interface class nh sau : class ControlFactory { //sử dụng ối tợng to số ngẩu nhiên theo mẫu Singleton private static MyRandom rnd = MyRandom.getInstance(); //hàm to ối tợng Controller public static IController CreateController(int nbRules) { IController c = new Controller(); for (int i = 0; i < nbRules; i++) { c.add(generateRandomRule()); } return c; Trang 17 } //hàm to luật ngẫu nhiên static public Rule generateRandomRule() { Rule retour = new Rule(); for (int i = 0; i < 8; i++) { double rand = rnd.RndDouble(); if (rand > 0.20) // 80% joker retour.setCondition(i, LabyItem.ANY); else if (rand > 0.15) // 5% mur retour.setCondition(i, LabyItem.WALL); else if (rand > 0.05) // 10% bonus retour.setCondition(i, LabyItem.POINT); else // 5% blanc retour.setCondition(i, LabyItem.NULL); } retour.Action = (Direction)rnd.RndInt(4); return retour; } } Ở th mục gốc Project, thực class ControllerIndividual miêu t cá thể có giá trị ặc trng tập luật i agent Viết code cho class nh sau : class ControllerIndividual : AbstractIndividual { private IController specval; //hàm khởi to public ControllerIndividual(IController controller) { this.specval = controller; } //hàm khởi to public ControllerIndividual(int nbRules) { this.specval = ControlFactory.CreateController(nbRules); } //hàm gii mã ối tợng dng chuỗi gợi nhớ public override String ToString() { String ret = "" + Fitness + ":" + SpecValue; return ret; Trang 18 } //hiện thực thuộc tính SpecValue public override Object SpecValue { get { return specval; } set { specval = (IController)value; } } public override IIndividual cross(IIndividual other) { ControllerIndividual o2 = other as ControllerIndividual; return new ControllerIndividual(specval.CreateSon((IController)o2.SpecValue, 0.05)); } public override void muter() { specval.muter(0.05); } public override IIndividual clone() { IIndividual ret = new ControllerIndividual(specval.clone()); ret.Fitness = Fitness; return ret; } } Ở th mục gốc Project, thực class ControllerIndividualFactory có chức nng to cá thể có giá trị ặc trng tập luật i agent Viết code cho class nh sau : class ControlIndividualFactory { private static MyRandom rnd = MyRandom.getInstance(); // hàm to cá thể chứa tập luật có nbRules luật ngẫu nhiên public IController createController(int nbRules) { IController c = new Controller(); for (int i = 0; i < nbRules; i++) { c.add(generateRandomRule()); } return c; } //hàm to luật ngẫu nhiên private Rule generateRandomRule() { Rule retour = new Rule(); for (int i = 0; i < 8; i++) { double rand = rnd.RndDouble(); if (rand > 0.20) // 80% joker Trang 19 retour.setCondition(i, LabyItem.ANY); else if (rand > 0.15) // 5% mur retour.setCondition(i, LabyItem.WALL); else if (rand > 0.05) // 10% bonus retour.setCondition(i, LabyItem.POINT); else // 5% blanc retour.setCondition(i, LabyItem.NULL); } retour.Action = (Direction)rnd.RndInt(4); return retour; } } 10 Ở th mục gốc Project, thực class CtrlPopFactory có chức nng to hệ cá thể có giá trị ặc trng tập luật i agent Viết code cho class nh sau : class CtrlPopFactory { public IPopulation createRandomPopulation(int size, int nbRules, bool isSensor) { IPopulation pop = new Population(); for (int i = 0; i < size; i++) { pop.add(createIndividu(nbRules)); } return pop; } public IIndividual createIndividu(int nbRules) { return new ControllerIndividual(nbRules); } public IEnvironment createEnvironment(Labyrinth laby, int nbsteps) { return new MazeSimuEnvironment(laby, nbsteps); } } 11 Ở th mục gốc Project, thực class Agent miêu t ngời chi (agent) Viết code cho class nh sau : class Agent { // private LabyItem[] capteurs; //Agent biết mê cung mà phi chi private Labyrinth laby; //vị trí agent mê cung private MyPoint position; //luật chi agent Trang 20 private IController controleur; //bng iểm agent private Score score; //hàm khởi to agent public Agent(MyPoint p, Labyrinth m, IController c) { position = p; capteurs = new LabyItem[8]; controleur = c; score = new Score(); laby = m; } //hàm khởi to agent public Agent(MyPoint p, Labyrinth m) { position = p; capteurs = new LabyItem[8]; controleur = ControlFactory.CreateController(0); score = new Score(); laby = m; } //hàm khởi to agent public Agent(int y, int x, Labyrinth m) { position = new MyPoint(y, x); capteurs = new LabyItem[8]; controleur = ControlFactory.CreateController(0); score = new Score(); laby = m; } //hàm tham kho thơng tin dị ờng agent public LabyItem[] getSensorsArray() { return capteurs; } //Thiết lập bng thông tin dị ờng agent theo vị trí hành mê cung //qui ớc nh sau : // = Bắc, = ông bắc, = ông, = ông nam, = Nam, = Tây nam, = Tây, = Tây bắc private void UpdateCapteurs() { capteurs[0] = laby.getContenuCase(Position.y - 1,Position.x); capteurs[1] = laby.getContenuCase(Position.y - 1, Position.x + 1); capteurs[2] = laby.getContenuCase(Position.y, Position.x + 1); capteurs[3] = laby.getContenuCase(Position.y + 1, Position.x + 1); capteurs[4] = laby.getContenuCase(Position.y + 1, Position.x); capteurs[5] = laby.getContenuCase(Position.y + 1, Position.x - 1); capteurs[6] = laby.getContenuCase(Position.y,Position.x - 1);