電梯調度算法模擬


說明:電梯調度算法的基本原則就是如果在電梯運行方向上有人要使用電梯則繼續往那個方向運動,如果電梯中的人還沒有到達目的地則繼續向原方向運動。具體而言,如果電梯現在朝上運動,如果當前樓層的上方和下方都有請求,則先響應所有上方的請求,然后才向下響應下方的請求;如果電梯向下運動,則剛好相反。

題目難度:較難

設計要求:模擬多人在不同樓層同時要求到各自目的地時電梯的響應順序,要求使用C語言編程,定義合適的數據結構。最后,需要說明設計思想,同時給出能夠運行的源程序,並給出對應的程序流程圖。

設計提示:可以用一個結構體表示乘電梯的人,其中內容包括人的姓名、起始樓層、目的樓層;建立一個結構體的數組模擬當前所有需要乘電梯的人。把這個結構體數組作為程序的輸入,通過對數組中每個人的起始樓層和目的樓層進行分析,確定每個人進出電梯的順序,並打印輸出。

比如: 當前樓層是4,結構體數組中共有3個人,A:7 → 3  B:6→10 C:7→8;

 則輸出應該是: 當前樓層為6,B進入

                當前樓層為7,C進入

                當前樓層為8,C出去

                當前樓層為10,B出去

                當前樓層為7,A進入

                當前樓層為3,A出去


解題思路:

      用戶結構體:{用戶姓名、起始樓層、目的樓層、方向};設置電梯運動的方向、電梯的起始樓層

1、創建乘客鏈表C,確定電梯運動方向

2、將與電梯運動方向一致的乘客按上電梯的順序組成鏈表A,將鏈表A中的乘客按下電梯的順序組成鏈表B(若該方向上沒有同方向的乘客,則確定電梯在該方向最終停留的樓層)

3、模擬電梯在該方向上乘客的變動情況,完成搭載的乘客的信息都從A、B、C中刪除,隨后確定電梯在該方向最終停留的樓層,並改變方向

如若C中還有乘客未搭載電梯,轉到2,循環執行

#include<iostream>
#include<stdlib.h>
using namespace std;
/*乘客的結構體*/
struct passenger
{
    char name;
    int start;
    int end;
    int dir;
};

/*鏈表結構*/
typedef struct LNode
{
    passenger P;
    struct LNode *next;
}LNode, *LinkList;

/*將節點LN插入到鏈表C中,插入到頭結點后面*/
void Insert(LNode *C, LNode *LN)
{
    LN->next = C->next;
    C->next = LN;
}

/*刪除LN后的第一個節點*/
void del(LNode *LN)
{
    LNode *next2 = LN->next;
    LN->next = next2->next;
    free(next2);
}

/*在鏈表C中查找到與LN節點相同的節點,並刪除*/
void finddel(LNode *LN, LinkList C)
{
    for (LNode *p = C; p->next != NULL; p = p->next)
    {
        if (p->next->P.name == LN->P.name)
        {
            del(p);
            break;
        }
    }
}

/*判斷鏈表是否為空*/
bool isempty(LinkList L)
{
    if (L->next == NULL)
        return 1;
    else
        return 0;
}

/*當電梯運行方向為dir時,
將C中要進入電梯的節點全部存放至A中,按照進入電梯的順序存放
並將其相應的存放在B中,按照離開電梯的順序存放*/
void Insert2(LinkList A, LinkList B, LinkList C, int dir, int floor)
{
    for (LNode *p = C->next; p != NULL; p = p->next)
    {
        if (dir == 1 && p->P.start >= floor && p->P.dir == 1)
        {//查找出C中方向相同且起始樓層在電梯上方的所有節點 
            LNode *r = (LNode*)malloc(sizeof(LNode));
            LNode *s = (LNode*)malloc(sizeof(LNode));
            r->P = p->P;
            s->P = p->P;
            for (LNode *q = A; ; q = q->next)
            {//將該節點插入A中,確保其起始樓層為升序的方式 
                if (q->next == NULL || q->next->P.start >= r->P.start)
                {
                    Insert(q, r);
                    break;
                }
            }
            for (LNode *q = B; ; q = q->next)
            {//將該節點插入B中,確保其目標樓層為升序的方式 
                if (q->next == NULL || q->next->P.end >= s->P.end)
                {
                    Insert(q, s);
                    break;
                }
            }
        }
        else if (dir == 0 && p->P.start <= floor && p->P.dir == 0)
        {
            LNode *r = (LNode*)malloc(sizeof(LNode));
            LNode *s = (LNode*)malloc(sizeof(LNode));
            r->P = p->P;
            s->P = p->P;
            for (LNode *q = A; ; q = q->next)
            {
                if (q->next == NULL || q->next->P.start <= r->P.start)
                {
                    Insert(q, r);
                    break;
                }
            }

            for (LNode *q = B; ; q = q->next)
            {
                if (q->next == NULL || q->next->P.end <= s->P.end)
                {
                    Insert(q, s);
                    break;
                }
            }
        }
    }
}

int finds(int m, LinkList C, int dir)
{//確定出電梯行駛方向最后停留的樓層 
    if (dir == 1)
    {
        for (LNode *p = C->next; p != NULL; p = p->next)
        {
            if (m<p->P.start)
                m = p->P.start;
        }
    }
    else
    {
        for (LNode *p = C->next; p != NULL; p = p->next)
        {
            if (m>p->P.start)
                m = p->P.start;
        }
    }
    return m;
}

int main()
{
    LinkList C = (LNode*)malloc(sizeof(LNode));
    C->next = NULL;//C為存儲所有的乘客信息的鏈表 
    LinkList A = (LNode*)malloc(sizeof(LNode));
    A->next = NULL;//A為存儲某個行駛方向上,上電梯的所有乘客信息 
    LinkList B = (LNode*)malloc(sizeof(LNode));
    B->next = NULL;//B為A中乘客的按下電梯順序排列 
    int floor;//記錄電梯選擇運行方向時所在的樓層 
    int dir;//記錄電梯運行的方向 
    cout << "請輸入電梯所在樓層:";
    while (cin >> floor)
    {
        /*輸入乘客信息並創建鏈表,電梯運行的初始方向根據只要上方有乘客則向上*/
        cout << "請依次輸入乘客代號、起始樓層、目標樓層、行駛方向:" << endl;
        char a;
        dir = 0;
        while (cin >> a)
        {
            LinkList x = (LNode*)malloc(sizeof(LNode));
            x->P.name = a;
            cin >> x->P.start >> x->P.end >> x->P.dir;
            Insert(C, x);
            if (x->P.start >= floor)
                dir = 1;
        }
        /*while(cin>>str)語句在結束輸入時使用了Ctrl+Z,告訴cin用戶已經結束了輸入,
        為了讓程序正常運行,調用cin.clear()讓cin的所有條件狀態位復位*/
        cin.clear();
        /*模擬電梯行駛過程*/
        while (!isempty(C))
        {//有乘客未乘坐電梯 
            Insert2(A, B, C, dir, floor);//將C中滿足條件的乘客放入A、B中 
                                         /*乘客上下*/
            if (isempty(B))
                floor = finds(floor, C, dir);
            while (!isempty(B))
            {//模擬電梯往某個特定方向行駛的過程 
                if (dir == 1)
                {//當電梯是向上行駛時 
                    if ((A->next == NULL) || (A->next->P.start > B->next->P.end))
                    {//出電梯的情況 
                        cout << "當前樓層為" << B->next->P.end << ""
                            << B->next->P.name << "出電梯" << endl;
                        finddel(B->next, C);//刪除C中對應的乘客信息 
                        del(B);//刪除鏈表中該乘客的信息 
                    }
                    else
                    {//進電梯的情況 
                        cout << "當前樓層為" << A->next->P.start << ""
                            << A->next->P.name << "進電梯" << endl;
                        del(A);//刪除鏈表中該乘客的信息
                    }
                }
                else
                {//當電梯是向下行駛時 
                    if ((A->next == NULL) || (A->next->P.start < B->next->P.end))
                    {
                        cout << "當前樓層為" << B->next->P.end << ""
                            << B->next->P.name << "出電梯" << endl;
                        finddel(B->next, C);
                        del(B);
                    }
                    else
                    {
                        cout << "當前樓層為" << A->next->P.start << ""
                            << A->next->P.name << "進電梯" << endl;
                        del(A);
                    }
                }
                if (B->next != NULL && B->next->next == NULL)
                {
                    floor = finds(B->next->P.end, C, dir);

                }
            }
            dir = !dir;//改變行駛方向
        }
        /**/
        cout << endl << endl;
        cout << "請輸入電梯所在樓層:";
    }
    system("pause");
}

運行效果如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM