//Tính Mahattan private void TinhDoSaiLech(int viTri, ref int[] tongCuaCacViTri) { int sum = 0; int dongDung = -1, cotDung = -1, dongSai = -1, cotSai = -1; for (int i = 1; i <= PuzzelArray.GetLength(0) * PuzzelArray.GetLength(0) - 1; i++) { TimKiemViTriSai(i, ref dongSai, ref cotSai, PuzzelArray); TimKiemViTriDung(i, ref dongDung, ref cotDung); sum += Convert.ToInt32(Math.Abs(dongDung - dongSai) + Math.Abs(cotDung - cotSai)); } tongCuaCacViTri[viTri] = sum; }
/*private void TinhDoSaiLechGoc(ref int saiLechGoc) * { * int sum = 0; * double dongDung = -1, cotDung = -1, dongSai = -1, cotSai = -1; * for (int i = 1; i <= PuzzelArray.GetLength(0) * PuzzelArray.GetLength(0) - 1; i++) * { * TimKiem(i, ref dongSai, ref cotSai, PuzzelArray); * TimKiem(i, ref dongDung, ref cotDung, PerfectPuzzel); * sum += Convert.ToInt32(Math.Abs(dongDung - dongSai) + Math.Abs(cotDung - cotSai)); * } * saiLechGoc = sum; * }*/ public void GiaiRoiInKetQua(string path) { if (!TimCapNguoc()) { //g là tầng của cây int g = 0; //Tránh trường hợp di chuyển mãi 1 ô int viTriVuaChon = -1; while (!DaHoanThanh()) { viTriSoKhong = new int[2]; //Kiem So 0 bool chuaKiemThaySoKhong = true; for (int i = 0; i < kichThuoc && chuaKiemThaySoKhong; i++) { for (int j = 0; j < kichThuoc; j++) { if (PuzzelArray[i, j] == 0) { viTriSoKhong[0] = i; viTriSoKhong[1] = j; chuaKiemThaySoKhong = false; break; } } } int[,] viTriXungQuanh = new int[4, 2]; //Theo thu tu la /* * Tren dong|cot * Duoi dong|cot * Trai dong|cot * Phai dong|cot */ for (int i = 0; i < viTriXungQuanh.GetLength(0); i++) { for (int j = 0; j < viTriXungQuanh.GetLength(1); j++) { viTriXungQuanh[i, j] = -1; } } //Trên int check = viTriSoKhong[0] - 1; if (check >= 0) { viTriXungQuanh[0, 0] = viTriSoKhong[0] - 1; viTriXungQuanh[0, 1] = viTriSoKhong[1]; } //Dưới check = viTriSoKhong[0] + 1; if (check <= PuzzelArray.GetLength(0) - 1) { viTriXungQuanh[1, 0] = viTriSoKhong[0] + 1; viTriXungQuanh[1, 1] = viTriSoKhong[1]; } //Trái check = viTriSoKhong[1] - 1; if (check >= 0) { viTriXungQuanh[2, 0] = viTriSoKhong[0]; viTriXungQuanh[2, 1] = viTriSoKhong[1] - 1; } //Phải check = viTriSoKhong[1] + 1; if (check <= PuzzelArray.GetLength(1) - 1) { viTriXungQuanh[3, 0] = viTriSoKhong[0]; viTriXungQuanh[3, 1] = viTriSoKhong[1] + 1; } //Giai thuat Heuristic dung thuat toan Manhattan int[] tongCuaCacViTri = { -1, -1, -1, -1 }; // Lan luot la Tren Duoi Trai Phai //Gia Dinh Tren Duoi Trai Phai // Ben tren thi chuyen xuong roi tinh doSaiLechCuaMoiSo roi tinh tong cua mang doSaiLechCuaMoiSo roi gan vao tongCuaCacViTri[0] va tuong tu // Tim do sai lech cua ma tran //int saiLech = 0; //TinhDoSaiLechGoc(ref saiLech); //Sau do tinh do sai lech khi di chuyen cac mieng ghep xung quanh if (!(viTriXungQuanh[0, 0] == -1 && viTriXungQuanh[0, 1] == -1)) { //Chuyen ben tren xuong PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]] = PuzzelArray[viTriXungQuanh[0, 0], viTriXungQuanh[0, 1]]; PuzzelArray[viTriXungQuanh[0, 0], viTriXungQuanh[0, 1]] = 0; //Tinh do sai lech cua TH nay TinhDoSaiLech(0, ref tongCuaCacViTri); //Gan lai TH cu PuzzelArray[viTriXungQuanh[0, 0], viTriXungQuanh[0, 1]] = PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]]; PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]] = 0; } if (!(viTriXungQuanh[1, 0] == -1 && viTriXungQuanh[1, 1] == -1)) { //Chuyen ben duoi len PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]] = PuzzelArray[viTriXungQuanh[1, 0], viTriXungQuanh[1, 1]]; PuzzelArray[viTriXungQuanh[1, 0], viTriXungQuanh[1, 1]] = 0; //Tinh do sai lech cua TH nay TinhDoSaiLech(1, ref tongCuaCacViTri); //Gan lai TH cu PuzzelArray[viTriXungQuanh[1, 0], viTriXungQuanh[1, 1]] = PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]]; PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]] = 0; } if (!(viTriXungQuanh[2, 0] == -1 && viTriXungQuanh[2, 1] == -1)) { //Chuyen ben trai qua PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]] = PuzzelArray[viTriXungQuanh[2, 0], viTriXungQuanh[2, 1]]; PuzzelArray[viTriXungQuanh[2, 0], viTriXungQuanh[2, 1]] = 0; //Tinh do sai lech cua TH nay TinhDoSaiLech(2, ref tongCuaCacViTri); //Gan lai TH cu PuzzelArray[viTriXungQuanh[2, 0], viTriXungQuanh[2, 1]] = PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]]; PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]] = 0; } if (!(viTriXungQuanh[3, 0] == -1 && viTriXungQuanh[3, 1] == -1)) { //Chuyen ben phai qua PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]] = PuzzelArray[viTriXungQuanh[3, 0], viTriXungQuanh[3, 1]]; PuzzelArray[viTriXungQuanh[3, 0], viTriXungQuanh[3, 1]] = 0; //Tinh do sai lech cua TH nay TinhDoSaiLech(3, ref tongCuaCacViTri); //Gan lai TH cu PuzzelArray[viTriXungQuanh[3, 0], viTriXungQuanh[3, 1]] = PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]]; PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]] = 0; } //Tong cua cac vi tri cong voi so tang g for (int i = 0; i < tongCuaCacViTri.Length; i++) { if (tongCuaCacViTri[i] != -1) { tongCuaCacViTri[i] += g; } } int min = int.MaxValue; int viTriMin = -1; for (int i = 0; i < tongCuaCacViTri.Length; i++) { if (tongCuaCacViTri[i] <= min && tongCuaCacViTri[i] != -1 && viTriVuaChon != i) { min = tongCuaCacViTri[i]; viTriMin = i; } } switch (viTriMin) { case 0: PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]] = PuzzelArray[viTriXungQuanh[0, 0], viTriXungQuanh[0, 1]]; PuzzelArray[viTriXungQuanh[0, 0], viTriXungQuanh[0, 1]] = 0; Down(PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]]); viTriVuaChon = 1; break; case 1: PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]] = PuzzelArray[viTriXungQuanh[1, 0], viTriXungQuanh[1, 1]]; PuzzelArray[viTriXungQuanh[1, 0], viTriXungQuanh[1, 1]] = 0; Up(PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]]); viTriVuaChon = 0; break; case 2: PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]] = PuzzelArray[viTriXungQuanh[2, 0], viTriXungQuanh[2, 1]]; PuzzelArray[viTriXungQuanh[2, 0], viTriXungQuanh[2, 1]] = 0; Right(PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]]); viTriVuaChon = 3; break; case 3: PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]] = PuzzelArray[viTriXungQuanh[3, 0], viTriXungQuanh[3, 1]]; PuzzelArray[viTriXungQuanh[3, 0], viTriXungQuanh[3, 1]] = 0; Left(PuzzelArray[viTriSoKhong[0], viTriSoKhong[1]]); viTriVuaChon = 2; break; default: break; } //Tang len so tang g++; } StreamWriter sw = new StreamWriter(path); sw.WriteLine("So buoc can de ra ket qua : {0} ", ketQua.Count); foreach (var item in ketQua) { sw.WriteLine(item); } sw.Close(); } else { StreamWriter sw = new StreamWriter(path); sw.WriteLine("Khong co loi giai"); sw.Close(); } }
/* * private bool TimCapNguoc(int kichThuoc) * { * if (kichThuoc % 2 == 0) * { * int viTriSoKhong = -1; * int soCapNguoc = 0; * for (int i = 0; i < PuzzelArray.GetLength(0); i++) * { * for (int j = 0; j < PuzzelArray.GetLength(1); j++) * { * if (j == PuzzelArray.GetLength(1) - 1) * { * for (int k = i + 1; k < PuzzelArray.GetLength(0); k++) * { * for (int l = 0; l < PuzzelArray.GetLength(1); l++) * { * if (PuzzelArray[i, j] > PuzzelArray[k, l] && PuzzelArray[i, j] != 0 && PuzzelArray[k, l] != 0) * { * soCapNguoc++; * } * else if (PuzzelArray[i, j] == 0) * { * viTriSoKhong = i; * } * else if (PuzzelArray[k, l] != 0) * { * viTriSoKhong = k; * } * } * } * } * else if (i == PuzzelArray.GetLength(0) && j == PuzzelArray.GetLength(1)) * { * break; * } * else * { * for (int k = i; k < PuzzelArray.GetLength(0); k++) * { * for (int l = j++; l < PuzzelArray.GetLength(1); l++) * { * if (PuzzelArray[i, j] > PuzzelArray[k, l] && PuzzelArray[i, j] != 0 && PuzzelArray[k, l] != 0) * { * soCapNguoc++; * } * else if (PuzzelArray[i, j] == 0) * { * viTriSoKhong = i; * } * else if (PuzzelArray[k, l] != 0) * { * viTriSoKhong = k; * } * } * } * } * } * } * if (soCapNguoc % 2 + viTriSoKhong == 0) * { * return false; * } * else * { * return true; * } * } * else * { * int soCapNguoc = 0; * for (int i = 0; i < PuzzelArray.GetLength(0); i++) * { * for (int j = 0; j < PuzzelArray.GetLength(1); j++) * { * if (j == PuzzelArray.GetLength(1) - 1) * { * for (int k = i + 1; k < PuzzelArray.GetLength(0); k++) * { * for (int l = 0; l < PuzzelArray.GetLength(1); l++) * { * if (PuzzelArray[i, j] > PuzzelArray[k, l] && PuzzelArray[i, j] != 0 && PuzzelArray[k, l] != 0) * { * soCapNguoc++; * } * } * } * } * else if (i == PuzzelArray.GetLength(0) && j == PuzzelArray.GetLength(1)) * { * break; * } * else * { * for (int k = i; k < PuzzelArray.GetLength(0); k++) * { * for (int l = j++; l < PuzzelArray.GetLength(1); l++) * { * if (PuzzelArray[i, j] > PuzzelArray[k, l] && PuzzelArray[i, j] != 0 && PuzzelArray[k, l] != 0) * { * soCapNguoc++; * } * * } * } * } * } * } * if (soCapNguoc % 2 == 0) * { * return true; * } * else * { * return false; * } * } * } */ private bool TimCapNguoc() { int[] mang1Chieu = new int[kichThuoc * kichThuoc - 1]; int k = 0; for (int i = 0; i < PuzzelArray.GetLength(0); i++) { for (int j = 0; j < PuzzelArray.GetLength(1); j++) { if (PuzzelArray[i, j] != 0) { mang1Chieu[k] = PuzzelArray[i, j]; k++; } } } int soCapNguoc = 0; if (kichThuoc % 2 == 0) { bool chuaKiemThaySoKhong = true; int viTri = -1; for (int i = 0; i < kichThuoc && chuaKiemThaySoKhong; i++) { for (int j = 0; j < kichThuoc; j++) { if (PuzzelArray[i, j] == 0) { viTri = i; chuaKiemThaySoKhong = false; break; } } } for (int i = 0; i < mang1Chieu.Length - 1; i++) { for (int j = i + 1; j < mang1Chieu.Length; j++) { if (mang1Chieu[i] > mang1Chieu[j]) { soCapNguoc++; } } } if ((soCapNguoc + viTri) % 2 == 0) { return(true); //Khong giai duoc } else { return(false); //Giai duoc } } else { for (int i = 0; i < mang1Chieu.Length - 1; i++) { for (int j = i + 1; j < mang1Chieu.Length; j++) { if (mang1Chieu[i] > mang1Chieu[j]) { soCapNguoc++; } } } if (soCapNguoc % 2 == 0) { return(false); //Giai duoc } else { return(true); //Khong giai duoc } } }