Chương 3 : Xây dựng bài toán ứng dụng
3.2. Mô tả cách áp dụng thuật toán vào bài toán cụ thể
Thuật toán: sử dụng logic mờ để giải quyết bài tốn điều khiển máy giặt.
3.2.1. Xây dựng các biến ngơn ngữ cùng trạng thái a. Với biến ngơn ngữ khối lượng quần áo có các tập mờ
- Nhẹ (K.nhẹ)
- Trung bình (K.trung bình) - Nặng (K.nặng)
b. Với biến ngơn ngữ Độ bẩn có các tập mờ - Bẩn ít (D.bẩn ít)
- Bẩn nhiều (D.bẩn nhiều)
c. Với biến ngôn ngữ kết luận xác định lượng nước có các tập mờ - Ít (T.ít)
- Vừa (T.vừa) - Cao (T.cao)
d. Với biến ngôn ngữ kết luận xác định lượng bột giặt có các tập mờ
- Ít (G.ít) - Vừa (G.vừa) - Nhiều (G.cao)
e. Với biến ngôn ngữ kết luận xác định tốc độ quay - Chậm (N.chậm)
- Vừa (N.vừa) - Nhanh (N.nhanh)
f. Với biến ngôn ngữ kết luận xác định thời gian giặt - Rất nhanh (B.rất nhanh)
- Nhanh (B.nhanh) - Vừa (B.vừa)
- Lâu (B.lâu)
- Rất lâu (B.rất lâu)
Tập luật
R1. Nếu Khối lượng = Nhẹ và Độ bẩn = Bẩn ít=> Lượng nước = Thấp
R2. Nếu Khối lượng = Nhẹ và Độ bẩn = Bẩn nhiều=> Lượng nước = Vừa
R3. Nếu Khối lượng = Trung bình và Độ bẩn = Bẩn ít=> Lượng nước = Vừa
R4. Nếu Khối lượng = Trung bình và Độ bẩn = Bẩn nhiều=> Lượng nước = Cao
R5. Nếu Khối lượng = Nặng và Độ bẩn = Bẩn ít=> Lượng nước = Vừa
R6. Nếu Khối lượng = Nặng và Độ bẩn = Bẩn nhiều=> Lượng nước = Cao
3.2.2. Hàm thuộc
a. Hàm thuộc của khối lượng quần áo
b. Hàm thuộc của Độ bẩn Gọi độ bẩn là x
c. Hàm kết luận xác định lượng nước
Giải mờ bằng phương pháp hình thang Ta có các giá trị a, b, m1, m2, h
T= M =
Từ các luật ta có lượng nước cần :
3.3.4. Áp dụng vào bài toán cụ thể
Bài toán: Lượng quần áo = 2.5 và độ bẩn = 37.5. Tính lượng nước cần. Suy diễn mờ Suy luật mờ Theo luật r1: Theo luật r2: Theo luật r3: Theo luật r2: Theo luật r5: Theo luật r6:
Các luật tham gia vào hệ suy diễn để xác định lượng nước là: r1, r2, r3, r4
Luật r1:
H = 0.5
H = 0.5
Vậy lượng nước cần dùng cho 2.5kg đồ và 37.5% độ bẩn là 60.321 (l) nước. Thiết kế một số giải thuật
Thiết kế và sử dụng giải thuật– áp dụng trong các tập mờ hình thang với biểu diễn bộ 4 số:
- Giải thuật tìm hàm thuộc: Đầu vào: tập mờ A = {a, b, c, d}
Thông tin đối tượng x Đầu ra: Giá trị hàm thuộc
float hamthuoc() {
if( x < a || x > d) return 0;
else if((b!=c && x <= c && x >= b) || (b == c && x == b)) return 1;
else if( x <= b && x >= a) { if(b-a) return (x - a)/(b-a);
else return -2;//-2 sẽ bị loại khi đưa vào hàm main. }
else if( x <= d && x >= c) {
if(d-c)return (d - x)/(d-c); else return -2;
} else return -2; }
- Giải thuật tìm tử số, mẫu số của một luật tham gia: Đầu vào: lượng thuốc A={a, b, c, d} tương ứng với luật
H = = x (giá trị hàm thuộc của luật) Đầu ra: TU va MAU
float timm (t, u, v) { z = abs(t-u);
if(z) return v*z; else return 0;
}
float timtu(h, m1, m2, t, u){
return (h/6)*(3*m2*m2 – 3*m1*m1 + u*u - t*t + 3*m2*u + 3*m1*a);
}
float timmau(h, m1, m2, t, u){
return (h/2)*(2*m2 – 2*m1 + t + u); } void timtumau() { ka = timm(a, b, x); m1= a + ka; kb = timm(c, d, x); m2= d - kb; TU = timtu(x, m1, m2, ka, kb); MAU = timmau(x, m1, m2, ka, kb); }
3.3. Cài đặt chương trình 3.4.1. Mơi trường cài đặt
Ngơn ngữ cài đặt : C# Hệ điều hành : Windows 10 Nền tảng : NetFramework 3.0
Công cụ sử dụng : Visual Studio 2017
Để đảm bảo khả năng tương thích cao nhất cho các phiên bản kể cả khi cài đặt chương trình trên các máy tính khác mà khơng bị lỗi, nhóm đã quyết định sử dụng bản NetFramework 3.0 thay vì những bản mới hơn, việc này sẽ giúp chương trình được cà đặt dễ dàng hơn kể cả ở những máy có cấu hình thấp chỉ cần hỗ trợ NetFramework 3.0 trở lên.
3.4.2. Giao diện chương trình
Tên điều khiển Loại điều khiển Text
txtKhoiluong Textbox
txtDoban Textbox
txtLuongnuoc Textbox
btnTinh Button Tính lượng nước
btnClear Button Xóa
3.4.3. Mã nguồn chương trình
3.4.3.1. Khai báo các biến lưu trữ hàm thuộc và tập luật const int MIN_NHIET = 37;
const int MIN_TUOI = 0; const int MAX_NHIET = 41;
Dictionary<string, string[]> tap_mo = new Dictionary<string, string[]>(); Dictionary<string, float> tap_suy_dien = new Dictionary<string, float>(); Dictionary<string, float[]> tuoi = new Dictionary<string, float[]>(); Dictionary<string, float[]> nhiet = new Dictionary<string, float[]>(); Dictionary<string, float[]> thuoc = new Dictionary<string, float[]>(); Dictionary<string, string[]> luat = new Dictionary<string, string[]>(); Dictionary<string, float> doTuoi = new Dictionary<string, float>(); Dictionary<string, float> nhietDo = new Dictionary<string, float>(); ArrayList tu = new ArrayList();
ArrayList mau = new ArrayList();
3.4.3.2. Hàm khởi tạo public Form1()
{
InitializeComponent();
string[] age = { "TRE", "TN", "GIA" }; string[] temp = { "SN", "SC" }; string[] medicin = { "TT", "TB", "TC" }; tap_mo.Add("tuoi", age); tap_mo.Add("nhietdo", temp); tap_mo.Add("thuoc", medicin); /* Trẻ(0, 20, 20, 40) TN(20, 40, 40, 60) Già(40, 60, 60, 80) (Tuổi) SN(37, 38, 38, 39) SC(38, 39, 41, 41) (Nhiệt độ) TT(0, 20, 40, 60) TB(40, 60, 80, 100) TC(80, 100, 120, 120) (Đơn vị thuốc) */ float[] tuoiTre = { 0, 20, 20, 40 }; float[] trungNien = { 20, 40, 40, 60 }; float[] tuoiGia = { 40, 60, 60, 80 }; tuoi.Add("TRE", tuoiTre); tuoi.Add("TN", trungNien); tuoi.Add("TG", tuoiGia); float[] sotNhe = { 37, 38, 38, 39 }; float[] sotCao = { 38, 39, 41, 41 }; nhiet.Add("SN", sotNhe); nhiet.Add("SC", sotCao);
float[] thuocThap = { 0, 20, 40, 60 }; float[] thuocTB = { 40, 60, 80, 100 }; float[] thuocCao = { 80, 100, 120, 120 }; thuoc.Add("TT", thuocThap); thuoc.Add("TB", thuocTB); thuoc.Add("TC", thuocCao); /*
1.Nếu Tuổi = Trẻ và Sốt = Nhẹ(SN) thì lượng thuốc = thấp(TT) 2.Nếu Tuổi = Trẻ và Sốt = Cao(SC) thì lượng thuốc = trung bình(TB) 3.Nếu Tuổi = Trung Niên(TN) và Sốt = Nhẹ thì lượng thuốc = trung bình 4.Nếu Tuổi = Trung niên và Sốt = Cao thì lượng thuốc = cao(TC)
5.Nếu Tuổi = Già và Sốt = Nhẹ thì lượng thuốc = trung bình 6.Nếu Tuổi = Già và Sốt = Cao thì lượng thuốc = cao */ string[] r1 = { "TRE", "SN", "TT" }; string[] r2 = { "TRE", "SC", "TB" }; string[] r3 = { "TN", "SN", "TB" }; string[] r4 = { "TN", "SC", "TC" }; string[] r5 = { "TG", "SN", "TB" }; string[] r6 = { "TG", "SC", "TC" }; luat.Add("r1", r1); luat.Add("r2", r2); luat.Add("r3", r3); luat.Add("r4", r4); luat.Add("r5", r5); luat.Add("r6", r6); } 3.4.3. Mã nguồn chương trình
public partial class Form1 : Form
{
public Form1() {
InitializeComponent();
< Khai báo các biến lưu trữ hàm thuộc và tập luật >
< Hàm khởi tạo>
private float hamthuoc(float x, float[] mang) {
float b = mang[1]; float c = mang[2]; float d = mang[3]; if (x <= c && x >= b) return 1; else if (x <= b && x >= a) { if (b - a != 0) return ((x - a) / (b - a)); else return 1; } else if (x <= d && x >= c) { if (d - c != 0) return (d - x) / (d - c); else return 1; } else return 0; }
private float timm(float t, float u, float v) {
float z = Math.Abs(t - u); if (z != 0) return v * z; else return 0;
}
private float timtu(float h, float m1, float m2, float t, float u) {
return (h / 6) * (3 * m2 * m2 - 3 * m1 * m1 + u * u - t * t + 3 * m2 * u + 3 * m1 * t);
}
private float timmau(float h, float m1, float m2, float t, float u) {
return (h / 2) * (2 * m2 - 2 * m1 + t + u); }
void timtumau(float[] mang, float x) {
float a = mang[0]; float b = mang[1];
float c = mang[2]; float d = mang[3]; float ka = timm(a, b, x); float m1 = a + ka; float kb = timm(c, d, x); float m2 = d - kb;
float TU = timtu(x, m1, m2, ka, kb); tu.Add(TU);
float MAU = timmau(x, m1, m2, ka, kb); mau.Add(MAU);
}
private Boolean KiemTraDauVao(float tuoi_in, float nhiet_do_in, object sender, EventArgs e)
{
if (nhiet_do_in < 0 || tuoi_in < 0) {
MessageBox.Show("Tuổi và nhiệt độ phải là số thực dương."); return false;
}
else if (nhiet_do_in < MIN_NHIET) {
MessageBox.Show("Bệnh nhân không bị sốt, không cần uống thuốc."); return false;
}
else if (tuoi_in < MIN_TUOI) {
MessageBox.Show("Bệnh nhân q trẻ, khơng thể chuẩn đốn."); return false;
}
else if (tuoi_in > MAX_TUOI) {
MessageBox.Show("Bệnh nhân đã q tuổi để chuẩn đốn, khơng có dữ liệu.");
return false; }
else if (nhiet_do_in > MAX_NHIET) {
return false; }
return true; }
private void btnCLear_Click(object sender, EventArgs e) {
txtTuoi.Text = ""; txtNhietDo.Text = ""; txtLuongThuoc.Text = ""; }
private void btnTinh_Click(object sender, EventArgs e) {
float tuoi_input, nhietdo_input; try
{
tuoi_input = float.Parse(txtTuoi.Text.ToString());
nhietdo_input = float.Parse(txtNhietDo.Text.ToString()); if (KiemTraDauVao(tuoi_input, nhietdo_input, sender, e)) {
nhietDo.Clear(); doTuoi.Clear(); //tinh ham thuoc
float nhe = hamthuoc(nhietdo_input, nhiet["SN"]); if (nhe >= 0) nhietDo.Add("SN", nhe);
float cao = hamthuoc(nhietdo_input, nhiet["SC"]); if (cao >= 0) nhietDo.Add("SC", cao);
float tre = hamthuoc(tuoi_input, tuoi["TRE"]); if (tre >= 0) doTuoi.Add("TRE", tre);
float tn = hamthuoc(tuoi_input, tuoi["TN"]); if (tn >= 0) doTuoi.Add("TN", tn);
float gia = hamthuoc(tuoi_input, tuoi["TG"]); if (tn >= 0) doTuoi.Add("TG", gia);
IDictionaryEnumerator contro = luat.GetEnumerator(); tap_suy_dien.Clear();
int dem = 0;
{
string[] noi_dung = luat[contro.Key.ToString()]; float min = 2;
if (min > doTuoi[noi_dung[0]] && doTuoi[noi_dung[0]] >= 0) {
min = doTuoi[noi_dung[0]]; }
if (min > nhietDo[noi_dung[1]] && nhietDo[noi_dung[1]] >= 0) { min = nhietDo[noi_dung[1]]; } if (min > 0) { dem++; tap_suy_dien.Add(contro.Key.ToString(), min); } } if (dem == 0) {
MessageBox.Show("Dữ liệu hiện có khơng đủ để suy diễn."); } else { tu.Clear(); mau.Clear(); contro = tap_suy_dien.GetEnumerator(); while (contro.MoveNext()) {
string luat_dung = contro.Key.ToString();
float ham_thuoc_luat = tap_suy_dien[luat_dung]; string[] noi_dung = luat[luat_dung];
string thuoc_gi = noi_dung[2];
timtumau(thuoc[thuoc_gi], ham_thuoc_luat); }
float tu_so = 0, mau_so = 0;
foreach (float i in tu) { tu_so += i; } foreach (float i in mau) { mau_so += i; } if (mau_so == 0)
{
MessageBox.Show("Bệnh nhân không cần phải uống thuốc."); }
else if (tu_so == 0) {
MessageBox.Show("Bệnh nhân không cần phải uống thuốc."); }
else {
txtLuongThuoc.Text = (tu_so / mau_so).ToString(); }
} } else {
MessageBox.Show("Tuổi và nhiệt độ không phù hợp."); }
}
catch (FormatException) {
MessageBox.Show("Tuổi và nhiệt độ phải là số thực dương."); }
catch (Exception a) {
MessageBox.Show("Nhập sai định dạng hoặc có lỗi!" + a); }
} }
KẾT LUẬN
Việc đưa ra một liều lượng nước đầu ra với khối lượng và độ bẩn đã có là mục tiêu chương trình hướng đến, để từ đó ta có thể tự động hóa điều khiện máy giặt giúp con người tiện nghi hơn.
TÀI LIỆU THAM KHẢO
Tiếng Việt
[1] Trường Đại học Cơng nghiệp Hà Nội (2015), Giáo trình Hệ chun gia, NXB Khoa học và Kỹ thuật.
[2] Bùi Công Cường (2001), N.D. Phước, Hệ mờ, Mạng Nơron và ứng dụng (Tuyển tập các bài giảng), NXB Khoa học và Kỹ thuật.
Tiếng Anh
[3] I.H. Kuo, et al, “An improved method for forecasting enrollments based on fuzzy time series and particle swarm optimization”, Expert systems with
applications, 36 (2009) 6108–6117.
[4] K. Huarng , “Effective length of interval to improve forecasting in fuzzy time series”, Fuzzy set and Systems, (2001) vol. 123, pp. 387-394.
[5] U. Yolcu et. Al, “A new approach for determining the length of intervals for fuzzy time series”, Applied Soft Computing , (2009) vol. 9, pp. 647-651.