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;
        }
Exemplo n.º 2
0
        // _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);
                //让用户无法进行导出,计算,验证
            }
        }
Exemplo n.º 3
0
        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;
        }