Пример #1
0
 //Sắp xếp lại các cặp Tháp gửi nhận tăng dần theo chi phí
 private void SapXepCacCapThap()
 {
     for (int i = 1; i < this.CacCapThap.Length; i++)
     {
         CapThap tam = this.CacCapThap[i];
         int     j   = i - 1;
         while ((j >= 0) && (tam.ChiPhi < this.CacCapThap[j].ChiPhi))
         {
             this.CacCapThap[j + 1] = this.CacCapThap[j];
             j--;
         }
         this.CacCapThap[j + 1] = tam;
     }
 }
Пример #2
0
    //Thuật giải Tháp Hà Nội, thực hiện khi nhấp nút chuyển
    private void ThuatGiaiThapHaNoi(object o, EventArgs e)
    {
        //Khi thanhcong ==true thi 2 dừng
        bool thanhcong = false;

        while (thanhcong == false)
        {
            //Khi chuyển được 1 đĩa thì số lần chuyển tăng lên
            this.SoLanChuyen++;
            this.LbSoDia.Text = "Số lần đã chuyển: " + this.SoLanChuyen;
            this.LbSoDia.Refresh();
            //Tạo ra các cặp Tháp gửi-nhận
            int k = 0;
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (j != i)
                    {
                        this.CacCapThap[k].ThapGui    = i;
                        this.CacCapThap[k++].ThapNhan = j;
                    }
                }
            }
            //Tính chi phí cho từng cặp Tháp
            for (int i = 0; i < this.CacCapThap.Length; i++)
            {
                this.CacCapThap[i].ChiPhi = TinhChiPhi(this.CacCapThap[i].ThapGui, this.CacCapThap[i].ThapNhan);
            }
            //Lấy ra các cặp có chi phí nhỏ nhất
            int[] cacmin = CatDoan(0);
            bool  dung   = false;
            int   s      = 1;
            //Nếu đúng ==true tức là gửi được đĩa thì dừng
            while (dung == false)
            {
                bool co = false;
                int  min, x;
                //Nếu kiểm tra hết đoạn min thì chuyển sang đoạn lớn hơn min 1, lớn hơn min 2..
                if (cacmin.Length == 0)
                {
                    cacmin = CatDoan(s);
                    s++;
                    continue;
                }
                //Nếu chưa hết thì lấy ngẫu nhiên 1 chỉ số trong mãng chỉ số đó
                else
                {
                    Random so = new Random();
                    x      = so.Next(0, cacmin.Length);
                    min    = cacmin[x];
                    cacmin = RutGonMang(cacmin, x);
                }
                //Khi gửi đi thì không được gửi lại
                //Trừ khi Tháp C không có đĩa nào sai
                if ((this.CacCapThap[min].ThapNhan == ChuongTrinh.CapTruoc.ThapGui) && (this.CacCapThap[min].ThapGui == ChuongTrinh.CapTruoc.ThapNhan))
                {
                    if (this.CacThap[0].CacDia.Length != 0 || this.CacThap[2].CacDia.Length != this.CacThap[2].SoDiaDung(int.Parse(this.TbSoDia.Text)))
                    {
                        continue;
                    }
                }
                //Tháp A không được quay trở lại như lúc khởi đầu
                if (this.CacCapThap[min].ThapNhan == 0 && this.CacThap[0].CacDia.Length == int.Parse(this.TbSoDia.Text) - 1)
                {
                    continue;
                }
                //Chỉ gửi được khi Tháp gửi có đĩa
                if (this.CacThap[this.CacCapThap[min].ThapGui].CacDia.Length == 0)
                {
                    continue;
                }
                //Kiểm tra nhận được hay không
                else
                {
                    co = this.CacThap[this.CacCapThap[min].ThapNhan].NhanDia(this.CacThap[this.CacCapThap[min].ThapGui].CacDia[0]);
                }
                //Nều nhận cũng được luôn thì bắt đầu thực hiện gửi-nhận
                if (co == true)
                {
                    ChuongTrinh.CapTruoc = this.CacCapThap[min];
                    this.CacThap[this.CacCapThap[min].ThapGui].ChoDia();
                    this.Controls.Add(this.CacThap[this.CacCapThap[min].ThapGui]);
                    dung = true;
                    this.LbSoDiaDung.Text = "Số đĩa đã chuyển hoàn thành: " + this.CacThap[2].SoDiaDung(int.Parse(this.TbSoDia.Text));
                    this.LbSoDiaDung.Refresh();
                    this.BtDiChuyen.Hide();
                }
            }
            //Nếu chi phí ==0 thì thành công
            if (this.CacThap[2].SoLanItNhat(int.Parse(this.TbSoDia.Text)) == 0)
            {
                thanhcong = true;
            }
        }
        this.Controls.Add(this.LbThanhCong);
    }