1 BÀI TP LN MÔN: TRÍ TU NHÂN TO ĐỀ TÀI: A KT ĐỂ TÌM ĐƯỜNG ĐI TỐI ƯU CHO CẤU TRÚC CÂY Sinh viên thc hin: 1. Trnh Minh Châu. 2. Trn Th Minh Hi. 3. Nguyn Bá Nguyn. 4. 5. Phm Trng Toàn. Ging dn: Ths Trng. 2 LU 3 Phân tích bài toán 4 M 4 Cách làm. 5 Cu trúc d liu và cách biu din trng thái ca bài toán 7
Lng 7 Hàm to mu chui nhp vào 8 Hàm x lý chui nhp vào 9 nh t cho các nút v 11 Hàm v th 12 Hàm gii thut AKT 13 Các hàm cho gii thut 15 Giao di 19 Tài liu tham kho 20 3 LỜI NÓI ĐẦU Trí tu là gì? Theo t Trí tu là kh Phn ng thích hp li nhng tình hung mu chnh hành vi mt cách thích hp.
Hiu rõ mi liên h gia các s kin ca th gii bên ngoài nh nhng hành vi phù h c m Vy trí tu nhân to là gì? Thut ng trí tu nhân t trong hi tho t nhi nhau v trí tu nhân to. Vi trí tu nhân t i gii quyt các v mt cách thông minh nht. Ta s tìm hiu mt s
gii quyt v n. C th m trong không gian trng thái vi thut gii A KT . 4 1. Phân tích bài toán. 1.1. Mục đích bài toán. Gi s ta có m th d: Ta c m A J. Bit g(n) là chi phí thc t n 0 n. Thut gii A KT là m rng ca thut gii A T bng cách s dng thêc ng h(n). Thut gii A T là thut
gi nh và giá ca chúng (g). Tuy nhiên gii thut này không còn phù hp khi gp phi nhng bài toán phc tp do phi tháo mng nút ln(c n bùng n v t h khc phi ta s dng thêm các thông tin b sung xut phát t b nh có trin vng, t tp trung xung quanh t nht nu s
d t v bài toán. A B C D G E F I H J 5 Vc gi là các Heuristics: h(n) hay chính là ng t n G. Các k thut s dng h(n) gi là các mo gii, ta có th o gii sau: - Chn toán t xây dng cung sao cho có th loi bnh không liên nh có trin vng. - S dng thêm các thông tin b sung nhm xây dng tp MO và
cách ly các nh trong tp MO. c vii ta ph , tiêu chu m trin vng. Các hàm s dng các k thut này g ra mt s - Da vào xác sut c - Da vào khong cách, s sai khác ca trt vi tr hoc các thông tin liên quan ti tr d
ng ng f(n) và f(n) tt ca li gii. 1.2. Cách làm. Thuật giải A KT c 1: - Mt. - M u tiên S, gán g(S) = 0 - S dng tri thc b c tính hàm h(S) - Tính f(S) = g(S) + h(S) c 2: Chnh m có f là nh nht và gnh N - N nh N là ngn nht và và bng g(N). Dng (Success). - Nu không tn
tnh m nào: cây biu din v không tn ti i mc tiêu. Dng (Fail). Nnh m tr lên có cùng giá tr f nh nht: Chúng ta phi kim tra xem nh 6 o + Nng nh N là ngn nht và bng g(N). Dng (Success). o + Nu không có: chn ngu nhiên mnh c 3: - nh N, m mnh sau N. Vi mnh S sau N, tính:
- g(S) = g(N) + cost(SN) - S dng tri thc b tính h(S) và f(S): f(S) = g(S) + h(S) c 4: - Quay lc 2. Thủ tục tìm kiếm: Vào: - th nh, A là tp cung. - f : N R + ng). - u là n 0 và t Ra: - 0 n k : {MO = {n 0 }; tính f(n 0 ) = g(n 0 ) +
h(n 0 ) do {n getmoi(MO) // Lnh n sao cho f(n) min DONG = DONG U{n} If n If then For each m B(n) do 7 If m MO DONG then { MO =MO {m} Tính f(m) } Else if f cu (m) >f moi (m) then MO = MO {m} } } 2. Cấu trúc dữ liệu và cách biểu diễn trạng thái của bài toán 1. Lớp khai báo đối tượng
class Nut { protected string _Ten; private int _G; private int _H; protected int _ID; protected int _IDcha; public Nut(int id, int idcha, string ten, int g, int h) { _ID = id; _IDcha = idcha; _G = g; _H = h; _Ten = ten; } public string Ten { get { return _Ten; } set { _Ten = value; } } public int G { get { return _G; } set { _G = value; } } public int H
8 { get { return _H; } set { _H = value; } } public int ID { get { return _ID; } set { _ID = value; } } public int IDcha { get { return _IDcha; } set { _IDcha = value; } } public Object Tag; } Gi ng ca nút _Ten : Tên nút _ID : Mã nút _IDcha : Mã nút cha _G : g _H : h 2. Hàm tạo mẫu chuỗi nhập vào //Tạo một mẫu
mặc định public string TaoCayGia(int maxLen, string title) { int ser = 0,ser1=0,ser2=1; string text = ""; text = "ID\tID Cha\tTên Nut\tG\tH"; text += "\r\n_______\t_______\t_______\t_______\t_______"; for (int i = 0; i < maxLen; i++) { ser = rdNumber(maxLen, i, ser); ser1 = rdNumber(5, i, ser1); ser2 = rdNumber(58, i, ser2); text += string.Format("\r\n{0}\t{1}\t{2}{0}\t{3}\t{4}", i + 1, i > 0 && (i + ser) <= 0 ?
i : (i + ser), title, i > 0 && (i + ser1) <= 0 ? i : (i + ser1), 9 i > 0 && (i + ser2) <= 0 ? i : (i + ser2)); } return text; } //tạo lấy số private int rdNumber(int max, int i, int last) { int avr = max / 2; int mod = i % avr; int range = (mod - i) / avr; last += (range + (last % 2)); return last; } 3. Hàm xử lý chuỗi nhập vào //Xử lý chuỗi nhập vào public TreeNode
TaoCayTuChuoi(string text) { //loại bỏ các ký tự xuống dòng string[] lines = text.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); //trả về mảng chuỗi vẫn còn các ký tự tab return TaoCayTuChuoi(lines); } public TreeNode TaoCayTuChuoi(string[] lines) { //Bỏ qua 2 dòng đầu chứa các tiêu đề if (lines.Length <= 2) return null; TreeNode trNodes = new TreeNode(); SortedList<string, TreeNode>
sortnodes = new SortedList<string, TreeNode>(); for (int id = 2; id < lines.Length; id++) { string line = lines[id]; char[] tab = { '\t' }; //cắt chuỗi ở vị trí tab string[] chuoi = line.Split(tab, StringSplitOptions.RemoveEmptyEntries); //cắt khoảng trắng ở đầu cuối các chuỗi chuoi[0].Trim(); chuoi[1].Trim(); chuoi[2].Trim(); chuoi[3].Trim(); chuoi[4].Trim(); TreeNode curNode = null; try { curNode = sortnodes[chuoi[0]]; }
catch (Exception) { curNode = null; } if (curNode == null) { curNode = new TreeNode(chuoi[2]); sortnodes.Add(chuoi[0], curNode); } curNode.Text = chuoi[2]; //them nut 10 curNode.Tag = new Nut(int.Parse(chuoi[0]), int.Parse(chuoi[1]), curNode.Text, int.Parse(chuoi[3]), int.Parse(chuoi[4])); //kiểm tra trùng tên //if (kiemtratennut(chuoi[2])) break; // thêm vào mảng addnode(int.Parse(chuoi[0]), int.Parse(chuoi[1]),
curNode.Text, int.Parse(chuoi[3]), int.Parse(chuoi[4])); // TreeNode parentNode = null; try { parentNode = sortnodes[chuoi[1]]; } catch (Exception) { parentNode = null; } if (parentNode == null) { parentNode = new TreeNode(chuoi[1]); sortnodes.Add(chuoi[1], parentNode); } parentNode.Nodes.Add(curNode); } IEnumerator<KeyValuePair<string, TreeNode>> nodesEnum = sortnodes.GetEnumerator();
nodesEnum.Reset(); while (nodesEnum.MoveNext()) { TreeNode node = (TreeNode)nodesEnum.Current.Value; if (node.Level == 0) trNodes.Nodes.Add(node); } TreeNode lastNode = trNodes.Nodes.Count > 1 ? trNodes : trNodes.Nodes[0]; lastNode.Text = "Đồ thị"; return lastNode; } //hàm kiểm tra trùng tên //public bool kiemtratennut(string ten) //{ // for (int i = 0; i < ALLNut.Count; i++) // { // ArrayList anut =
ALLNut[i]; // string str = (string)anut[2]; // if (str == ten) // { // MessageBox.Show("Tên nút trùng nhau, xin hãy kiểm tra lại!"); // return true; // break; // } // } // return false; //} //them node vào arraylist chính private void addnode(int ID, int IDcha, string ten, int g, int h) { 11 int f = 0; ArrayList addn = new ArrayList(){ ID,IDcha,ten,g,h,f }; ALLNut.Add(addn); }
4. Hàm xác định tọa độ cho các nút vẽ //tọa độ public class ToaDo { public ToaDo(Object tag) { Tag = tag; } public Size sz;//text size public string Text; public Object Tag;//Tham chiếu đến đối tượng liên quan public static Font font = new Font("Times New Roman", 9); public static int KCgiuaTang = 60; public static int TangX = 10; public static int TangY = 10; public int delta = 0, kidsW = 0, prevW = 0; public
Point ViTri = new Point(0, 0); public Rectangle vien//hcn kích thước của text { get { int w = sz.Width + delta; return new Rectangle(ViTri.X + (w - sz.Width) / 2 - 1, ViTri.Y + TangY, sz.Width + 1, sz.Height); } } public Point diemDau { get { Rectangle rect = vien; return new Point(rect.Left + (rect.Width / 2), rect.Top); } } public Point diemCuoi { get { Rectangle rect = vien;
return new Point(rect.Left + (rect.Width / 2), rect.Bottom); } } } 12 5. Hàm vẽ đồ thị //Vẽ cây // public Bitmap VeCay(TreeNode node) { int tangX = ToaDo.TangX, kcachtang = ToaDo.KCgiuaTang, w = ToaDo.TangX, h = ToaDo.KCgiuaTang; Font fnt = ToaDo.font; Bitmap bmp = new Bitmap(w, h); Graphics gr = Graphics.FromImage(bmp); //vẽ nút LayNutCay laynut = (tnode) => { Boolean first = true; ToaDo
cb = new ToaDo(tnode); ((Nut)tnode.Tag).Tag = cb; cb.Text = " g= " + ((Nut)tnode.Tag).G.ToString() + "\n " + tnode.Text + "\n h= " + ((Nut)tnode.Tag).H.ToString(); cb.sz = Size.Ceiling(gr.MeasureString(cb.Text, fnt)); cb.delta = tangX;//tăng chiều rộng bởi thêm các nút con cb.ViTri = new Point(tangX / 2, ((tnode.Level - 1) * kcachtang)); //vòng lặp while (tnode.Parent != null && tnode.Parent.Tag != null) { ToaDo b =
(ToaDo)((Nut)tnode.Tag).Tag; TreeNode p = tnode.Parent; ToaDo pb = (ToaDo)((Nut)p.Tag).Tag; //Tăng chiều rộng của các nút cha bởi chiều rộng cung cấp int pbw = pb.sz.Width + pb.delta; int bw = b.sz.Width + b.delta; pb.kidsW -= !first ? b.prevW : 0; pb.delta += ((bw + pb.kidsW - pbw) + Math.Abs(bw + pb.kidsW - pbw)) / 2; pbw = pb.sz.Width + pb.delta; pb.kidsW += bw; b.prevW = bw; //Điều chỉnh vị trí if (first) { //các nút
con được vẽ sau nút cha nên điều chỉnh sẽ chính xác b.ViTri = new Point(pb.ViTri.X + pb.kidsW - bw, ((tnode.Level - 1) * kcachtang)); first = false; } // w = Math.Max(pb.ViTri.X + pbw + ToaDo.TangX / 2, w); h = Math.Max((((tnode.Level - 1) * kcachtang)) + kcachtang, h); // tnode = p; } if (first && w > tangX) 13 { cb.ViTri.Offset(w, 0); w = Math.Max(cb.ViTri.X + cb.sz.Width + cb.delta, w); } };
NutLap(node, laynut);//lặp lại các nút để lấy tọa độ các nút gr.Dispose(); bmp.Dispose(); bmp = new Bitmap(w, h); gr = Graphics.FromImage(bmp); LayNutCay draw = (tnode) => { Brush mau_nut = new SolidBrush(Color.Ivory); Brush mau_chu = new SolidBrush(Color.Black); Brush mau_trang = new SolidBrush(Color.White); Nut mpttNode = (Nut)tnode.Tag; int level = tnode.Level; ToaDo b = (ToaDo)((Nut)tnode.Tag).Tag; Rectangle rect =
b.vien; //Vẽ nhánh if (tnode.Parent.Tag != null) { gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; Pen pen = new Pen(new SolidBrush(Color.Red), 1.0F); gr.DrawLine(pen, ((ToaDo)((Nut)tnode.Parent.Tag).Tag).diemCuoi, b.diemDau); } //Vẽ nút LinearGradientBrush brush = new LinearGradientBrush(rect, Color.White, Color.DodgerBlue, LinearGradientMode.ForwardDiagonal); gr.FillEllipse(brush, rect); gr.DrawEllipse(new
Pen(new SolidBrush(Color.Brown)), rect); //viết tên nút, g,h using (StringFormat sf = new StringFormat()) { sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Center; gr.DrawString(b.Text, fnt, mau_chu, rect, sf); } }; NutLap(node, draw);//lặp lại các nút trong cây gr.Dispose(); return bmp; } 6. Hàm giải thuật AKT public List<ArrayList> ALLNut = new List<ArrayList>();//mảng chính
List<ArrayList> nodeBn = new List<ArrayList>(); List<ArrayList> MO = new List<ArrayList>(); List<ArrayList> DONG = new List<ArrayList>(); 14 public int dem = 0; public void akt_search(string root,string nodesearch,ListView lv) { if (dem == 0) { tinhF_Bn(); dem++; } ListViewItem itemlv; if (Tontainut(nodesearch)) { if (root == "")//nếu chưa có nút nào mở thì thêm nút gốc {
themMO(laygoc()); itemlv = new ListViewItem(root); lv.Items.Add(itemlv); itemlv.SubItems.Add(""); itemlv.SubItems.Add(layMO()); itemlv.SubItems.Add(""); akt_search(laynutMo(), nodesearch, lv); } else { if (root != nodesearch) { daduyet(root);//xóa nút ra khỏi MO themBn(root); themMO(); themDONG(root); itemlv = new ListViewItem(root); lv.Items.Add(itemlv); itemlv.SubItems.Add(laybn());
itemlv.SubItems.Add(layMO()); itemlv.SubItems.Add(layDONG()); akt_search(laynutMo(), nodesearch, lv); } else { themDONG(root); itemlv = new ListViewItem(root); lv.Items.Add(itemlv); itemlv.SubItems.Add("Đích"); itemlv.SubItems.Add(""); itemlv.SubItems.Add(layDONG()); } } } else MessageBox.Show("Không tồn tại nút này!"); } 15 7. Các hàm cho giải thuật //lấy nút gốc public ArrayList
laygoc() { ArrayList goc = null; for (int i = 0; i < ALLNut.Count; i++) { ArrayList node = ALLNut[i]; if ((int)node[1] == 0) return node; } return goc; } //xóa nút đã duyệt khỏi MO public void daduyet(string tennut) { for (int i = 0; i < MO.Count; i++) { ArrayList ar = MO[i]; if ((string)ar[2]==tennut) MO.RemoveAt(i); } } //Lấy tên nút có F nhỏ nhất trong MO public string
laynutMo() { string st = ""; for (int j = 0; j < MO.Count; j++) { ArrayList arr1 = MO[j]; if ((int)arr1[5] == lay_min_f()) st=(string)arr1[2]; } return st; } public int lay_min_f() { int min = 1000000; for (int i = 0; i < MO.Count; i++) { ArrayList arr1 = MO[i]; min = (int)arr1[5] <= min ? (int)arr1[5] : min; } return min; } //lấy chuỗi để add vào listview // //
//lay ten nut goc public string layten() 16 { string ten = ""; ArrayList ar = laygoc(); ten = (string)ar[2]; return ten; } //lay cac nut trong bn public string laybn() { string st=""; for (int i = 0; i < nodeBn.Count; i++) { ArrayList nut = nodeBn[i]; string ten = (string)nut[2]; st += ten + "(F= " + nut[5].ToString() + ")\r\n"; } return st; } //lay cac nut trong MO public
string layMO() { string st = ""; for (int i = 0; i < MO.Count; i++) { ArrayList nut = MO[i]; string ten = (string)nut[2]; st += ten + "(F= " + nut[5].ToString() + ")\r\n"; } return st; } //lay cac nut trong DONG public string layDONG() { string st = ""; for (int i = 0; i < DONG.Count; i++) { ArrayList nut = DONG[i]; string ten = (string)nut[2]; st += ten + "(F= " + nut[5].ToString() + ") ";
} return st; } //tính F của các nút // public void tinhF_Bn() { for (int i = 0; i < ALLNut.Count; i++) { ArrayList root = ALLNut[i]; if ((int)root[1] == 0) root[5] = root[4]; for (int j = 0; j < ALLNut.Count; j++) { ArrayList rootchild = ALLNut[j]; int idcha = (int)rootchild[1]; if (idcha == (int)root[0]) { rootchild[3] = (int)root[3] + (int)rootchild[3]; 17 rootchild[5] =
(int)rootchild[3] + (int)rootchild[4]; } } } } //Thêm các phần tử vào các mảng con Bn,MO,DONG public void themBn(string nut) { //xóa sạch bn nodeBn.Clear(); for (int i = 0; i < ALLNut.Count; i++) { //lấy nút n ArrayList anut = ALLNut[i]; string tennut = (string)anut[2]; if (tennut == nut)//nếu phần tử trong mảng có tên là n { for (int j = 0; j < ALLNut.Count; j++) {//thêm vào bn phần tử từ mảng
gốc ArrayList node = ALLNut[j]; int idcha = (int)node[1]; if (idcha == (int)anut[0]) { nodeBn.Add(node); } } } } } public void themMO() { //MO sẽ thêm từ Bn for (int i = 0; i < nodeBn.Count; i++) { MO.Add(nodeBn[i]); } } //thêm phần tử vào MO nếu chưa có phần tử nào public void themMO(ArrayList n) { MO.Add(n); } public void themDONG(string nutduyet) {
for (int i = 0; i < ALLNut.Count; i++) { ArrayList ar = ALLNut[i]; if (nutduyet == (string)ar[2]) { DONG.Add(ar); } } } 18 //kiểm tra tồn tại nút // public bool Tontainut(string nuttim) { for (int i = 0; i < ALLNut.Count; i++) { ArrayList anut = ALLNut[i]; string str = (string)anut[2]; if (str == nuttim)//nếu có phần tử nào trong mảng đầu có tên trùng { return true; } }
return false; } //Hàm lấy đường đi và chi phí public int f=0; string st = ""; public string duongdi_chiphi(string nodesearch) { string s1=" > "; string s = nodesearch; //ArrayList az; for (int i = 0; i < ALLNut.Count; i++) { ArrayList nuts = ALLNut[i]; if (s == (string)nuts[2]) { if (f == 0) f = (int)nuts[3]; for (int j = 0; j < ALLNut.Count; j++) { ArrayList az = ALLNut[j]; if
((int)az[0] == (int)nuts[1]) { if ((int)az[1] == 0) { st = String.Concat(az[2].ToString(), s1, nuts[2].ToString(), st); } else { st = String.Concat(s1, nuts[2].ToString(), st); } s = (string)az[2]; duongdi_chiphi(s); } } } } return st; } 19 3. sGiao diện chương trình 20 Tài liệu tham khảo 1. Trng_Giáo trình slide TRÍ TU NHÂN TO(Artificial Intellegence
AI) 2. Geogre F. Luger, William A. Stubblefield Albuquerque Artifical Intelligence Wesley Pubblishing Conpany, Inc 1997 (Chapter 1) 3. Bùi Xuân Toi Trng Gia Vit (Biên dch) Trí tu nhân to Các cu trúc và chin lc gii quyt vn - NXB Thng kê, 2000 (Phn 1) 4. PTS. Nguyn Thanh Thy Trí tu nhân to Các phng pháp gii quyt vn và k thut x lí tri thc NXB Giáo dc, 1995 (Chng 1) 5. Wikipedia Bách khoa toàn th m - Lch s
ngành Trí tu nhân to 6. www.codeproject.com 7. www.congdongcviet.com |