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;
        }
        private void btnCheck_Click(object sender, EventArgs e)
        {
            DataLayer   dl         = new DataLayer();
            DataTable   dt         = dl.CreateTchArrangeDt(_teacherArrangeSolve, dl.getDictFromStatistics());//这个过程就是自原始表格中获取两个竖列
            DataTable   dtS        = dl.Total(dt);
            string      checkSolve = "";
            DataChecker dc         = new DataChecker(dl.getDictFromStatistics(), dl.getStaffList(), dt, dl.totalIndex);

            dc.Check();
            dc.TextOutput(ref checkSolve);
            FrmChecker checker = new FrmChecker(checkSolve);

            checker.ShowDialog();
        }
        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;
        }