/// <click button> /// 开始计算渡河方案 —— 按钮 /// </click button> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { m_fun.Clear(); index = 0; numpass = 0; c_count = 0; y_count = 0; chuan = 2; str = ""; richTextBox1.Text = "此程序仅仅实现计算效过,寻找出所有可执行方案,并未进行优化。\n因此当计算数据过大时,会造成程序停止响应,不用担心,程序依旧在后台运算。\n当程序使用足够时间运行完毕后,程序将会重新响应并展示所有的可行方案!\n计算需要一定的时间,请耐心等待···\n\n\t\t\t\t\t\tby Jayvee"; // 判断用户选择渡河人数是否正确 if (ccount.Value <= 0 && upcount.Value <= 0) { MessageBox.Show("error:请输入正确的渡河人数!"); return; } else { if (ccount.Value > 3 || upcount.Value > 3) { if (MessageBox.Show("warning:【警告】此运算人数过多,预计可执行方案过大,计算过程中将占用大量CPU造成系统卡顿,界面暂停服务至计算完成重新恢复,过程不可正常中止,是否继续计算?", "重要提醒", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK) { // 传教士个数 c_count = int.Parse(ccount.Value.ToString()); // 野人个数 y_count = int.Parse(ccount.Value.ToString()); // 设置船的最大载客量 chuan = int.Parse(upcount.Value.ToString()); mfun m = new mfun(); m_fun.Add(m); // 设置左岸传教士人数 m_fun[index].left_c = c_count; // 设置左岸野人数量 m_fun[index].left_y = y_count; // 右边传教士人数 m_fun[index].right_c = 0; // 右边野人数量 m_fun[index].right_y = 0; // 船的位置 m_fun[index].boat_location = 1; // 调用递归算法 mCalculation(m_fun[index]); } else { richTextBox1.Text = "计算终止"; return; } } else { // 传教士个数 c_count = int.Parse(ccount.Value.ToString()); // 野人个数 y_count = int.Parse(ccount.Value.ToString()); // 设置船的最大载客量 chuan = int.Parse(upcount.Value.ToString()); mfun m = new mfun(); m_fun.Add(m); // 设置左岸传教士人数 m_fun[index].left_c = c_count; // 设置左岸野人数量 m_fun[index].left_y = y_count; // 右边传教士人数 m_fun[index].right_c = 0; // 右边野人数量 m_fun[index].right_y = 0; // 船的位置 m_fun[index].boat_location = 1; // 调用递归算法 mCalculation(m_fun[index]); } } richTextBox1.Text = "一共计算出 " + numpass + " 条度河方案\n" + str; }
/// <click button> /// 开始计算渡河方案 —— 按钮 /// </click button> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { m_fun.Clear(); index = 0; numpass = 0; c_count = 0; y_count = 0; str = ""; richTextBox1.Text = ""; // 判断用户选择渡河人数是否正确 if (ccount.Value <= 0 && ycount.Value <= 0) { MessageBox.Show("error:请输入正确的渡河人数!"); return; } else { if (ccount.Value > 3 || ycount.Value > 3) { if (MessageBox.Show("warning:【警告】此运算人数过多,预计可执行方案过大,计算过程中将占用大量CPU造成系统卡顿,界面暂停服务至计算完成重新恢复,过程不可正常中止,是否继续计算?", "重要提醒", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK) { // 传教士个数 c_count = int.Parse(ccount.Value.ToString()); // 野人个数 y_count = int.Parse(ycount.Value.ToString()); mfun m = new mfun(); m_fun.Add(m); // 设置左岸传教士人数 m_fun[index].left_c = c_count; // 设置左岸野人数量 m_fun[index].left_y = y_count; // 右边传教士人数 m_fun[index].right_c = 0; // 右边野人数量 m_fun[index].right_y = 0; // 船的位置 m_fun[index].boat_location = 1; // 调用递归算法 mCalculation(m_fun[index]); } else { return; } } else { // 传教士个数 c_count = int.Parse(ccount.Value.ToString()); // 野人个数 y_count = int.Parse(ycount.Value.ToString()); mfun m = new mfun(); m_fun.Add(m); // 设置左岸传教士人数 m_fun[index].left_c = c_count; // 设置左岸野人数量 m_fun[index].left_y = y_count; // 右边传教士人数 m_fun[index].right_c = 0; // 右边野人数量 m_fun[index].right_y = 0; // 船的位置 m_fun[index].boat_location = 1; // 调用递归算法 mCalculation(m_fun[index]); } } richTextBox1.Text = "一共计算出 " + numpass + " 条度河方案\n" + str; }
/// <summary> /// 递归算法 /// </summary> /// <returns></returns> public int mCalculation(mfun m) { // 是否达到渡河目标状态 if (m.right_c == c_count && m.right_y == y_count) { // 找到第numpass条渡河方案 numpass++; str += "\n\t方案" + numpass + ":\n\t\t左传\t左野\t右传\t右野\t船\n"; // 循环遍历每个方案的每个步骤 for (int i = 0; i <= index; i++) { str += "\t\t" + m_fun[i].left_c + "\t" + m_fun[i].left_y + "\t" + m_fun[i].right_c + "\t" + m_fun[i].right_y + "\t" + m_fun[i].boat_location + "\n"; } return(0); } // 是否重复操作 for (int i = 0; i < index; i++) { if (m.left_c == m_fun[i].left_c && m.left_y == m_fun[i].left_y) { if (m.boat_location == m_fun[i].boat_location) { return(0); } } } // 人数是否合理 if (m.left_c < 0 || m.left_y < 0 || m.right_c < 0 || m.right_y < 0) { return(0); } // 传教士的人数是否大于等于野人 if ((m.left_c < m.left_y && m.left_c != 0) || (m.right_c < m.right_y && m.right_c != 0)) { return(0); } //渡河中间变量 mfun mm = new mfun(); // 递归算法 for (int cchuan = chuan; cchuan >= 0; cchuan--) { for (int ychuan = chuan; ychuan >= 0; ychuan--) { if ((cchuan >= ychuan && cchuan + ychuan <= chuan && cchuan + ychuan > 0) || (cchuan < ychuan && cchuan == 0)) { mm.left_c = m.left_c - cchuan * m.boat_location; mm.left_y = m.left_y - ychuan * m.boat_location; mm.right_c = m.right_c + cchuan * m.boat_location; mm.right_y = m.right_y + ychuan * m.boat_location; mm.boat_location = (-m.boat_location); index = index + 1; m_fun.Insert(index, mm); mCalculation(m_fun[index]); index = index - 1; } } } return(0); }
/// <summary> /// 递归算法 /// </summary> /// <returns></returns> public int mCalculation(mfun m) { // 是否达到渡河目标状态 if (m.right_c == c_count && m.right_y == y_count) { // 找到第numpass条渡河方案 numpass++; str += "\n\t方案" + numpass + ":\n\t\t左传\t左野\t右传\t右野\t船\n"; // 循环遍历每个方案的每个步骤 for (int i = 0; i <= index; i++) { str += "\t\t" + m_fun[i].left_c + "\t" + m_fun[i].left_y + "\t" + m_fun[i].right_c + "\t" + m_fun[i].right_y + "\t" + m_fun[i].boat_location + "\n"; } return(0); } // 是否重复操作 for (int i = 0; i < index; i++) { if (m.left_c == m_fun[i].left_c && m.left_y == m_fun[i].left_y) { if (m.boat_location == m_fun[i].boat_location) { return(0); } } } // 人数是否合理 if (m.left_c < 0 || m.left_y < 0 || m.right_c < 0 || m.right_y < 0) { return(0); } // 传教士的人数是否大于等于野人 if ((m.left_c < m.left_y && m.left_c != 0) || (m.right_c < m.right_y && m.right_c != 0)) { return(0); } //渡河中间变量 mfun mm = new mfun(); // 两个传教士过河 mm.left_c = m.left_c - 2 * m.boat_location; mm.left_y = m.left_y; mm.right_c = m.right_c + 2 * m.boat_location; mm.right_y = m.right_y; mm.boat_location = (-m.boat_location); index = index + 1; m_fun.Insert(index, mm); mCalculation(m_fun[index]); index = index - 1; // 两个野人过河 mm.left_c = m.left_c; mm.left_y = m.left_y - 2 * m.boat_location; mm.right_c = m.right_c; mm.right_y = m.right_y + 2 * m.boat_location; mm.boat_location = (-m.boat_location); index = index + 1; m_fun.Insert(index, mm); mCalculation(m_fun[index]); index = index - 1; // 一个传教士,一个野人过河 mm.left_c = m.left_c - 1 * m.boat_location; mm.left_y = m.left_y - 1 * m.boat_location; mm.right_c = m.right_c + 1 * m.boat_location; mm.right_y = m.right_y + 1 * m.boat_location; mm.boat_location = (-m.boat_location); index = index + 1; m_fun.Insert(index, mm); mCalculation(m_fun[index]); index = index - 1; // 一个传教士过河 mm.left_c = m.left_c - 1 * m.boat_location; mm.left_y = m.left_y; mm.right_c = m.right_c + 1 * m.boat_location; mm.right_y = m.right_y; mm.boat_location = (-m.boat_location); index = index + 1; m_fun.Insert(index, mm); mCalculation(m_fun[index]); index = index - 1; // 一个野人过河 mm.left_c = m.left_c; mm.left_y = m.left_y - 1 * m.boat_location; mm.right_c = m.right_c; mm.right_y = m.right_y + 1 * m.boat_location; mm.boat_location = (-m.boat_location); index = index + 1; m_fun.Insert(index, mm); mCalculation(m_fun[index]); index = index - 1; return(0); }