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