Пример #1
0
 public Member(string[] data)
 {
     _data = data;
     _allocatedCompartment = null;
     _ListGroup            = new List <Group>();
     _exclude = false;
 }
Пример #2
0
        /// <summary>
        /// 作業用区画作成
        /// </summary>
        public void BuildWorkCompartment()
        {
            //現在保持しているリストを初期化
            _ListWorkCompartment = new List<Compartment>();

            //区画情報から作業用区画作成
            for (int j = 1; j < _compartmentInfo.Rows.Count; j++)
            {
                string[] tmpCompartmentData = _compartmentInfo.Rows[j];
                Compartment tmpCompartment = new Compartment(tmpCompartmentData);
                if (tmpCompartment.Name != "")
                {
                    _ListWorkCompartment.Add(tmpCompartment);
                }
            }

        }
Пример #3
0
        /// <summary>
        /// リストの中で最もメンバーの少ない部屋を探す
        /// </summary>
        /// <param name="listCompartment"></param>
        /// <returns></returns>
        private Compartment FindFewestMemberAllocatedCompartmentFromList(List <Compartment> listCompartment)
        {
            Compartment result = null;

            if (listCompartment.Count > 0)
            {
                Compartment min = listCompartment[0];
                foreach (Compartment c in listCompartment)
                {
                    if (min.MemberCount > c.MemberCount)
                    {
                        min = c;
                    }
                }
                result = min;
            }
            return(result);
        }
Пример #4
0
        /// <summary>
        /// 区画リストかすでに割り当てられている同じメンバーの区画を探す
        /// </summary>
        /// <param name="mem"></param>
        /// <param name="listCompartment"></param>
        /// <returns></returns>
        private Compartment GetAllocatedCompartment(AttendeeAllocator.Member mem, List <Compartment> listCompartment)
        {
            //すでに割り当てられていることがわかっている場合
            if (mem.IsAllocated == true)
            {
                return(mem.AllocatedCompartment);
            }

            //不明な場合は区画リストから探し出す
            Compartment result = null;

            foreach (Compartment cmp in listCompartment)
            {
                if (cmp.IsInMember(mem) == true)
                {
                    result = cmp;
                    break;
                }
            }
            return(result);
        }
Пример #5
0
        /// <summary>
        /// 割り当て後の区画データからCSVデータ作成
        /// </summary>
        /// <param name="listCompartment"></param>
        public Layouter(List <Compartment> listCompartment, AttendeeInfo attInfo)
        {
            _listItem = new List <int>();

            //名簿見出し行でレイアウトに使用する項目数
            int layoutItems = FindItemFromAttendeeInfo(attInfo);

            //列数の算出
            //最大の列数 = LayoutXの最大値 + 名簿見出しアイテム数 + 1
            //行数の算出
            //最大行数 = LayoutYの最大値 + LayaoutY最大値となる区画の最大収容人数
            int         max_x           = 0;
            int         max_y           = 0;
            Compartment maxyCompartment = listCompartment[0];

            foreach (Compartment c in listCompartment)
            {
                if (c.X > max_x)
                {
                    max_x = c.X;
                }
                if ((c.Y + c.Max) > max_y)
                {
                    max_y           = c.Y + c.Max;
                    maxyCompartment = c;
                }
            }
            max_x += layoutItems + 1;//+1は区画名が入るため

            //m_dgv = new DataGridView();
            //m_dgv.RowCount = max_x;
            //m_dgv.ColumnCount = max_y;

            //CSVデータ用の文字列を空白で埋める
            _rows = new List <string[]>();

            //見出し行の作成
            string[] tmpRow       = new string[max_x];
            string[] attInfoTitle = attInfo.Rows[0];

            //int topItems = FindTopItems(listCompartment);
            List <Compartment> listTopCompartment = FindTopCompartment(listCompartment);

            if (listTopCompartment.Count < 1)
            {
                //ERROR
                return;
            }
            int topItems = listTopCompartment.Count;

            foreach (Compartment c in listTopCompartment)
//          for (int i = 0; i < topItems; i++)
            {
                //int curBaseX = (_listItem.Count + 1) * i;
                int curBaseX = c.X;
                tmpRow[curBaseX] = "区画名";
                for (int j = 0; j < _listItem.Count; j++)
                {
                    string title;
                    string tmpTitle = attInfoTitle[_listItem[j]];
                    if (tmpTitle[0] == '*')
                    {
                        title = tmpTitle.Remove(0, 1);
                    }
                    else
                    {
                        title = tmpTitle;
                    }
                    tmpRow[j + curBaseX + 1] = title;
                }
            }
            _rows.Add(tmpRow);

            //とりあえず空の行を作って埋める
            for (int i = 0; i < max_y; i++)
            {
                tmpRow = new string[max_x];
                _rows.Add(tmpRow);
            }

            //区画毎に内容を埋めていく
            foreach (Compartment c in listCompartment)
            {
                for (int i = 0; i < c.MemberCount; i++)
                {
                    tmpRow          = _rows[c.Y + i + 1]; //+1は見出し行補正
                    tmpRow[0 + c.X] = c.Name;
                    Member mem = c.ListMember[i];

                    for (int j = 0; j < _listItem.Count; j++)
                    {
                        tmpRow[0 + c.X + j + 1] = mem.Data[_listItem[j]]; //+1は区画名補正
                    }

                    //内容反映
                    _rows[c.Y + i + 1] = tmpRow;//+1は見出し行補正
                }
            }
        }
Пример #6
0
        /// <summary>
        /// 条件に最も近い区画をリストから探す
        /// </summary>
        /// <param name="listCompartment"></param>
        /// <param name="number"></param>
        /// <returns></returns>
        private Compartment GetMatchCompartment(List <Compartment> listCompartment, int number)
        {
            Compartment mostNearSpaceCompartmentL = null;
            Compartment mostNearSpaceCompartmentS = null;

            foreach (Compartment cmp in listCompartment)
            {
                //必要とする空きと一致する区画が見つかった場合
                if (cmp.RemainSpace == number)
                {
                    //この区画に排他属性の他のグループのメンバーが割り当てられていないか確認
                    if (cmp.IsAlreadyAllocatedExclusiveGroupMenber(this, null) == false)
                    {
                        //そういう人は居なかった
                        return(cmp);
                    }
                }
                else
                {
                    //必要とする空きとの差が一番近い区画を覚えておく
                    //空き人数の方が必要とするメンバー数を上回っている部屋の記憶
                    int diff = cmp.RemainSpace - number;
                    if (diff > 0)
                    {
                        if (mostNearSpaceCompartmentL == null)
                        {
                            mostNearSpaceCompartmentL = cmp;
                        }
                        else
                        {
                            if ((mostNearSpaceCompartmentL.RemainSpace - number) > diff)
                            {
                                mostNearSpaceCompartmentL = cmp;
                            }
                        }
                    }
                    else
                    {
                        //とにかく一番空き人数が近い部屋の記憶
                        if (mostNearSpaceCompartmentS == null)
                        {
                            mostNearSpaceCompartmentS = cmp;
                        }
                        else
                        {
                            int diffAbs = Math.Abs(cmp.RemainSpace - number);
                            if (Math.Abs(mostNearSpaceCompartmentS.RemainSpace - number) > diffAbs)
                            {
                                mostNearSpaceCompartmentS = cmp;
                            }
                        }
                    }
                }
            }
            if (mostNearSpaceCompartmentL != null)
            {
                return(mostNearSpaceCompartmentL);
            }
            else
            {
                return(mostNearSpaceCompartmentS);
            }
        }
Пример #7
0
        /// <summary>
        /// メンバーを区画へ割り当てる
        /// </summary>
        /// <param name="listCompartment"></param>
        /// <returns></returns>
        public bool AllocateMemberToCompartment(List <Compartment> listCompartment)
        {
            bool result = true;

            //=================================================
            //グループ属性に「除外」がある場合
            //=================================================
            //割り当てしない
            if (_exclude == true)
            {
                return(true);
            }

            //=================================================
            //割り当ての準備
            //=================================================
            //優先設定されている部屋のリストを作る
            List <Compartment> listPriorityCompartment = listCompartment.Where(c => c.PriorityGroup == _groupName).ToList();

            listPriorityCompartment = listCompartment.Where(c => c.PriorityGroup == _groupName).ToList();

            //優先設定されていない部屋のリストを作る
            List <Compartment> listNormalCompartment = listCompartment.Where(c => c.PriorityGroup == "").ToList();

            //割り当てなければいけないメンバーのリストを作成
            //List<Member> listRemainMembers = new List<Member>();
            List <Member> listRemainMembers = _members.Where(m => m.IsAllocated != true).ToList();
            //foreach (Member member in _members)
            //{
            //    listRemainMembers.Add(member);
            //}

            int remainMemberCount = listRemainMembers.Count;

            //=================================================
            //グループ属性に「集合」がある場合
            //=================================================
            if (_gather == true)
            {
                //まずは優先設定されている部屋への割り当てを試みる
                AllocatePriorityCompartmentGather(listPriorityCompartment, listRemainMembers);

                //優先設定区画割り当て後の残りの未割り当てメンバーを算出
                remainMemberCount = GetNotAllocatedRemainmemberCount(listRemainMembers);

                //通常区画の最大空き人数を算出
                if (remainMemberCount > 0)
                {
                    int normalCompartmentMaxRemainSpace = GetNumberOfMaxSpace(listNormalCompartment);
                    int moreNeed = remainMemberCount - normalCompartmentMaxRemainSpace;
                    if (moreNeed > 0)
                    {
                        _errorMessages.Add(string.Format("[エラー]グループ[{0}]用の{1}人分の区画がありませんでした。", this.Name, remainMemberCount));
                    }
                    else
                    {
                        moreNeed = 0;
                    }


                    //未割り当てメンバーがいなくなるまで(または、収容可能最大人数に達するまで)マッチする部屋へ割り当てる
                    int maxLoop = remainMemberCount;
                    for (int i = 0; i < maxLoop; i++)
                    {
                        if (remainMemberCount > 0)
                        {
                            Compartment matchCompartment = GetMatchCompartment(listNormalCompartment, remainMemberCount);
                            foreach (Member mem in listRemainMembers)
                            {
                                if (mem.IsAllocated == false)
                                {
                                    matchCompartment.AllocateExclusiveMember(mem, this);
                                    mem.AllocatedCompartment = matchCompartment;
                                }
                            }
                            remainMemberCount = GetNotAllocatedRemainmemberCount(listRemainMembers);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
            //=================================================
            //グループ属性に「分散」がある場合
            //=================================================
            else if (_scatter == true)
            {
                //まずは優先設定されている部屋への割り当てを試みる
                AllocatePriorityCompartmentScatter(listPriorityCompartment, listRemainMembers);

                //普通の部屋の中から割り当られているメンバーが最小かつ、排他グループがいない部屋を探す
                AllocatePriorityCompartmentScatter(listNormalCompartment, listRemainMembers);

                //未割り当ての人が居るならエラー
                remainMemberCount = GetNotAllocatedRemainmemberCount(listRemainMembers);
                if (remainMemberCount > 0)
                {
                    foreach (Member m in listRemainMembers)
                    {
                        if (m.IsAllocated == false)
                        {
                            _errorMessages.Add(string.Format("[エラー]グループ{0}に所属するキーコード{1}を割り当てる事ができませんでした。", _groupName, m.Key));
                        }
                    }
                }
            }
            //=================================================
            //グループ属性が無い場合(いまのところ分散と同じ方法で割り当て)
            //=================================================
            else
            {
                //まずは優先設定されている部屋への割り当てを試みる
                //AllocatePriorityCompartmentScatter(listPriorityCompartment, listRemainMembers);
                AllocatePriorityCompartmentGather(listPriorityCompartment, listRemainMembers);

                //普通の部屋の中から割り当られているメンバーが最小かつ、排他グループがいない部屋を探す
                AllocatePriorityCompartmentScatter(listNormalCompartment, listRemainMembers);

                //どこでもいいから開いている(排他グループのメンバーがいない)開いている部屋をさがす
                AllocateCompartment(listNormalCompartment, listRemainMembers);

                //未割り当ての人が居るならエラー
                remainMemberCount = GetNotAllocatedRemainmemberCount(listRemainMembers);
                if (remainMemberCount > 0)
                {
                    foreach (Member m in listRemainMembers)
                    {
                        if (m.IsAllocated == false)
                        {
                            _errorMessages.Add(string.Format("[エラー]グループ{0}に所属するキーコード{1}を割り当てる事ができませんでした。", _groupName, m.Key));
                        }
                    }
                }
            }
            return(result);
        }