Ejemplo n.º 1
0
 // 构造函数
 public Table(PersonStream ps)
 {
     reallytimeUpperbound = new double[7] { 2.0f, 1.0f, 2.0f, 2.0f, 1.5f, 2.0f, 4.0f };
     timeUpperbound = new int[7] { 4, 3, 3, 3, 3, 2, 4 };
     weekendPersonbound = new int[3] { 2, 2, 4 };
     weekendUpperbound = new double[3] { 5.0f, 5.5f, 4.0f };
     // 对每天
     for (int i = 0; i < 5; i++)
     {
         iTable.Add(new List<Cell>());
         // 对每个时段
         for (int j = 0; j < 7; j++)
         {
             Cell p1 = new Cell((TimePeriod)(i * 7 + j));
             p1.upperbound = timeUpperbound[j];
             // 找可填入的人
             for (int k = 0; k < ps.pstream.Count; k++)
             {
                 for (int m = 0; m < ps.pstream[k].validTimePeriod.Count; m++)
                 {
                     if (ps.pstream[k].validTimePeriod[m] == p1.cid)
                     {
                         p1.candidate.Add(ps.pstream[k]);
                         break;
                     }
                 }
             }
             iTable[i].Add(p1);
         }
     }
 }
Ejemplo n.º 2
0
Archivo: Core.cs Proyecto: rinkako/MOA
        // 核心算法:寻找排班的解
        public string Dash(out string pt, out bool vl)
        {
            // 获得一份排班时间表的拷贝
            List<Cell> proc = new List<Cell>();
            for (int i = 0; i < myTable.iTable.Count; i++)
            {
                for (int j = 0; j < myTable.iTable[i].Count; j++)
                {
                    proc.Add(myTable.iTable[i][j]);
                }
            }
            // 将格子从可用人数从小到大排序
            proc.Sort((x, y) =>
            {
                if (x.candidate.Count - x.upperbound < y.candidate.Count - y.upperbound)
                {
                    return -1;
                }
                else if ((x.candidate.Count - x.upperbound == y.candidate.Count - y.upperbound) &&
                    x.candidate.Count < y.candidate.Count)
                {
                    return -1;
                }
                else if (x.candidate.Count - x.upperbound > y.candidate.Count - y.upperbound)
                {
                    return 1;
                }
                else
                {
                    return 0;
                }
            });
            // 迭代搜索解
            foreach (Cell c in proc)
            {
                // 对每个格子的候选人做排序
                c.candidate.Sort((x, y) =>
                {
                    // 0:如果此人已满直接逆向调整
                    if (x.isOK() == true) {
                        return 1;
                    }
                    // 1:优先排可用时间少的人
                    if (x.validTimePeriod.Count < y.validTimePeriod.Count)
                    {
                        return -1;
                    }
                    else if (x.validTimePeriod.Count == y.validTimePeriod.Count)
                    {
                        // 2:优先排已有时间少的人
                        if (x.currentTime < y.currentTime)
                        {
                            return -1;
                        }
                        else if (x.currentTime == y.currentTime)
                        {
                            // 3:优先排B组
                            if (x.groupType == GroupType.B && y.groupType != GroupType.B)
                            {
                                return -1;
                            }
                            // 4:优先排A组
                            else if (x.groupType == GroupType.A && y.groupType != GroupType.A)
                            {
                                return -1;
                            }
                            // 5:最后再考虑C组,但不改变顺序
                            else
                            {
                                return 0;
                            }
                        }
                        // 逆向调整
                        else
                        {
                            return 1;
                        }
                    }
                    // 逆向调整
                    else
                    {
                        return 1;
                    }
                });
                // 标记并更新
                if ((int)c.cid % 7 == 0 && c.cid < TimePeriod.SAT1)
                {
                    // A不行
                    if (((int)c.cid / 7) % 2 == 0)
                    {
                        int encounter = 0;
                        for (int i = 0; i < c.candidate.Count; i++)
                        {
                            if (c.candidate[i].isOK() != true && c.candidate[i].groupType != GroupType.A)
                            {
                                c.candidate[i].currentTime += Table.reallytimeUpperbound[(int)c.cid % 7];
                                c.currentList.Add(c.candidate[i]);
                                encounter++;
                            }
                            if (encounter >= c.upperbound)
                            {
                                break;
                            }
                        }
                    }
                    // B不行
                    else
                    {
                        int encounter = 0;
                        for (int i = 0; i < c.candidate.Count; i++)
                        {
                            if (c.candidate[i].isOK() != true && c.candidate[i].groupType != GroupType.B)
                            {
                                c.candidate[i].currentTime += Table.reallytimeUpperbound[(int)c.cid % 7];
                                c.currentList.Add(c.candidate[i]);
                                encounter++;
                            }
                            if (encounter >= c.upperbound)
                            {
                                break;
                            }
                        }
                    }
                }
                else
                {
                    int encounter = 0;
                    for (int i = 0; i < c.candidate.Count; i++)
                    {
                        if (c.candidate[i].isOK() != true)
                        {
                            c.candidate[i].currentTime += Table.reallytimeUpperbound[(int)c.cid % 7];
                            c.currentList.Add(c.candidate[i]);
                            encounter++;
                        }
                        if (encounter >= c.upperbound)
                        {
                            break;
                        }
                    }
                }
            }
            // 接下来排周六日
            List<Cell> weekend = new List<Cell>();
            for (int i = 0; i < 6; i++)
            {
                Cell nc = new Cell((TimePeriod)35 + i);
                nc.upperbound = Table.weekendPersonbound[i % 3];
                weekend.Add(nc);
            }
            for (TimePeriod t = TimePeriod.SAT1; t <= TimePeriod.SUN3; t++)
            {
                for (int i = 0; i < myStream.pstream.Count; i++)
                {
                    for (int j = 0; j < myStream.pstream[i].validTimePeriod.Count; j++)
                    {
                        if (myStream.pstream[i].validTimePeriod[j] == t)
                        {
                            weekend[(int)t - (int)TimePeriod.SAT1].candidate.Add(myStream.pstream[i]);
                        }
                    }
                }
            }
            // 迭代搜索
            foreach (Cell c in weekend)
            {
                c.candidate.Sort((x, y) =>
                {
                        if (x.currentTime < y.currentTime) return -1;
                        else if (x.currentTime == y.currentTime) return 0;
                        else return 1;
                });
                // 标记并更新
                int encounter = 0;
                for (int i = 0; i < c.candidate.Count; i++)
                {
                    if (c.candidate[i].currentTime + Table.weekendUpperbound[((int)c.cid % 7) % 3] < Table.cynthia && c.candidate[i].groupType == GroupType.C)
                    {
                        c.candidate[i].currentTime += Table.weekendUpperbound[((int)c.cid % 7) % 3];
                        c.currentList.Add(c.candidate[i]);
                        encounter++;
                    }
                    if (encounter >= c.upperbound)
                    {
                        break;
                    }
                }
                for (int i = 0; i < c.candidate.Count && encounter < c.upperbound; i++)
                {
                    if (c.candidate[i].currentTime + Table.weekendUpperbound[((int)c.cid % 7) % 3] < Table.cynthia && c.candidate[i].groupType != GroupType.C)
                    {
                        c.candidate[i].currentTime += Table.weekendUpperbound[((int)c.cid % 7) % 3];
                        c.currentList.Add(c.candidate[i]);
                        encounter++;
                    }
                }
            }
            foreach (Cell c in weekend)
            {
                proc.Add(c);
            }
            // 时间少的排到前面
            foreach (Person p in myStream.pstream)
            {
                myStream.pstream.Sort((x, y) =>
                {
                    if (x.currentTime < y.currentTime) return -1;
                    else if (x.currentTime > y.currentTime) return 1;
                    else return 0;
                });
            }
            // 处理输出信息
            string str = "";
            string cel = "";
            foreach(Person p in myStream.pstream)
            {
                str += p.name + "\t" + p.groupType.ToString() + "\t" + p.currentTime.ToString() + Environment.NewLine;
            }

            proc.Sort((x, y) =>
            {
                if (x.cid < y.cid) return -1;
                else if (x.cid > y.cid) return 1;
                else return 0;
            });

            foreach(Cell c in proc)
            {
                cel += c.cid.ToString() + "\t";
                foreach (Person p in c.currentList)
                {
                    cel += p.name + p.groupType.ToString() + "\t";
                }
                cel += Environment.NewLine;
                if ((int)(c.cid + 1) % 7 == 0)
                {
                    cel += Environment.NewLine;
                }
            }
            pt = str;
            vl = this.isValuable(proc);
            return cel;
        }