public static void ForceCalc(DataTable origionRawDtArrange, DataTable origionRawDtStatistics, out DataTable finalDt, out DataTable finalStatistic, out int range) { List <List <List <Teacher> > > _teacherArrangeSolve = null; //执行让数据层处理数据的步骤 DataLayer dl = new DataLayer(); //给其中全局静态变量赋初值 DataLayer.DtRawTchArrange = origionRawDtArrange; DataLayer.DtRawStatistics = origionRawDtStatistics; //处理数据变成字典形式 dl.GetInfoFromRaw(); //首次赋值并计算 AlgorithmLayer al = new AlgorithmLayer(dl.getDictFromStatistics(), dl.getStaffList()); _teacherArrangeSolve = al.CalcTeacherArrange(); DataTable thisTimeDtArrange = null; DataTable thisTimeDtStatistic = null; ////外层循环控制主副均 //while (true) //{ //使理论折腾率与实际折腾率相等 while (true) { DataTable dt = dl.CreateTchArrangeDt(_teacherArrangeSolve, dl.getDictFromStatistics()); DataTable dtS = dl.Total(dt); DataChecker dc = new DataChecker(dl.getDictFromStatistics(), dl.getStaffList(), dt, dl.totalIndex); if (dc.Check()) { break; } al = new AlgorithmLayer(dl.getDictFromStatistics(), dl.getStaffList()); _teacherArrangeSolve = al.CalcTeacherArrange(); } //暴力主副均 thisTimeDtArrange = dl.CreateTchArrangeDt(_teacherArrangeSolve, dl.getDictFromStatistics()); thisTimeDtStatistic = dl.Total(thisTimeDtArrange); bool majorMinorBalance = true; int majorMinorThreshold = 3; //主副间最多差3 DataTable dtMajorMinor = thisTimeDtStatistic.GetCols(8, 2); //一列是主,另一列是副 foreach (DataRow dr in dtMajorMinor.Rows) { int thisTchMajorCnt = int.Parse(dr.ItemArray[0].ToString()); int thisTcnMinorCnt = int.Parse(dr.ItemArray[1].ToString()); int threshold = Math.Abs(thisTchMajorCnt - thisTcnMinorCnt); if (threshold > majorMinorThreshold) { majorMinorBalance = false; //只要有一位老师的主副不均就达不到目标 继续进行循环 } } // if(majorMinorBalance) break; //} //赋值退出 finalDt = thisTimeDtArrange; finalStatistic = thisTimeDtStatistic; range = al.Range; }
// _teacherArrangeSolve = null;//窗体保存结果的引用 private void tbtnCalc_Click(object sender, EventArgs e) { //计算不能写死直接在窗体dgv上面取数据,有可能是二次计算 //计算部分需要干两件事,一个是判断状态,存数据到内存,以供撤回 //另一个是利用数据调用模块来计算 //自等待计算过来,说明是根据导入,第一次计算 if (status.Equals(Status.WaitToCalc)) { StatusChange(Status.Processing); this._origionRawDtArrange = ((DataTable)this.dgvArrange.DataSource).Copy(); this._origionRawDtStatistics = ((DataTable)this.dgvStatistic.DataSource).Copy(); } StatusChange(Status.Processing); System.Diagnostics.Stopwatch swForUser = new System.Diagnostics.Stopwatch(); double loopInterval = -1; swForUser.Start(); //UI主线程执行运算,子线程弹出等待界面 Thread t = new Thread(() => new FrmWait().ShowDialog()); t.Start(); try { //这三个参数用来接收ForceCalc返回的结果 DataTable finalDt; DataTable finalStatistic; int range = 0; //将计算提取到Algorithm中的一个函数,循环求解的函数都在AlgorithmLayer中查看 AlgorithmLayer.ForceCalc(this._origionRawDtArrange, this._origionRawDtStatistics, out finalDt, out finalStatistic, out range); //添加一些代码将计算完成的表添加到dgv中 this.dgvArrange.FillDt(6, finalDt); this.dgvStatistic.FillDt(2, finalStatistic); //关闭前不让主线程sleep可能会出现不稳定的情况 Thread.Sleep(500); swForUser.Stop(); loopInterval = Math.Round(double.Parse(swForUser.ElapsedMilliseconds.ToString()) / 1000, 2); t.Abort(); MessageBoxEx.Show("耗时" + loopInterval + "秒,监考次数极差为" + range + "\n导出后对结果不满意,可再点击排班", "执行结果"); StatusChange(Status.WaitToOutput); } catch (Exception ex) { Thread.Sleep(500);//关闭前不让主线程sleep可能会出现不稳定的情况 t.Abort(); swForUser.Stop(); MessageBoxEx.Show(ex.Message, "错误"); StatusChange(Status.WaitToCalc); //让用户无法进行导出,计算,验证 } }
private void workButton_Click(object sender, EventArgs e) { System.Diagnostics.Stopwatch swForUser = new System.Diagnostics.Stopwatch(); double loopInterval = -1; swForUser.Start(); AlgorithmLayer al = null; //UI主线程执行运算,子线程弹出等待界面 Thread t = new Thread(() => new FrmWait().ShowDialog()); t.Start(); this.Enabled = false; try { _teacherArrangeSolve = null; DataLayer dl = new DataLayer();//数据层生成的同时,执行数据分析,数据清洗等操作 al = new AlgorithmLayer(dl.getDictFromStatistics(), dl.getStaffList()); _teacherArrangeSolve = al.CalcTeacherArrange(); //使理论折腾率与实际折腾率相等 while (true) { DataTable dt = dl.GetEmptyTeacherArrangeDt(); DataTable dtS = dl.Total(dt); DataChecker dc = new DataChecker(dl.getDictFromStatistics(), dl.getStaffList(), dt, dl.totalIndex); dc.Check(); List <double[]> checkSolve = dc.CheckSolve; //实际值与理论值不等就不跳出循环重新运算 bool therialEqualsReality = true; foreach (double[] oneDayCheck in checkSolve) { if (oneDayCheck[2] != oneDayCheck[3]) { therialEqualsReality = false; } } if (therialEqualsReality) { break; } al = new AlgorithmLayer(dl.getDictFromStatistics(), dl.getStaffList()); _teacherArrangeSolve = al.CalcTeacherArrange(); } Thread.Sleep(500);//关闭前不让主线程sleep可能会出现不稳定的情况 swForUser.Stop(); loopInterval = Math.Round(double.Parse(swForUser.ElapsedMilliseconds.ToString()) / 1000, 2); exportButton.Enabled = true; t.Abort(); MessageBox.Show("耗时" + loopInterval + "秒,监考次数极差为" + al.Range + "\n导出后对结果不满意,可再点击排班", "执行结果"); btnCheck.Enabled = true; } catch { Thread.Sleep(500);//关闭前不让主线程sleep可能会出现不稳定的情况 t.Abort(); swForUser.Stop(); MessageBox.Show("数据格式不符合要求", "错误"); //让用户无法进行导出,计算,验证 workButton.Enabled = false; exportButton.Enabled = false; btnCheck.Enabled = false; } this.Enabled = true; }