C++_活動安排問題

問題描述、

問題描述:有一個由n個活動組成的集合S = {a1, ..., an}

1. 這些活動使用同一個資源,而這個資源在某一時刻只供一個活動使用

2. 每個活動都有一個開始和結束時間si/fi;如果被選中,則任務ai發生在半開時間區間[si, fi)

3. 如果兩個活動ai和aj不重疊,則稱兩個活動兼容

活動選擇問題,希望選出一個最大兼容活動集

設計思路

設計思路:採用回溯求解算法,用數組s[N]來存放事件的開始及其結束時間,m[N]存放當前得到的最大兼容活動集,v[N]存放當前最大兼容活動集的開始機器結束時間,Vmax表示當前最大兼容活動集的活動數。若事件可進棧(與已在棧中元素無時間衝突),則進棧,若無事件可繼續進棧,則此時活動總數與Vmax比較,若大於Vmax,則替換Vmax和v[N]和m[N],若i>n,則需退棧,若此時棧空,則結束運行並輸出此時Vmax, v[N], m[N]。

數據結構:

s[N]來存放事件的開始及其結束時間,

m[N]存放當前得到的最大兼容活動集,

v[N]存放當前最大兼容活動集的開始機器結束時間

a[N]爲工作數組,存放當前棧內活動,

Vmax表示當前最大兼容活動集的活動數

算法描述:

ARRANGE(s[N], m[N], v[N], a[N], Vmax)

Input(s[N])

Top<-0; i<-1;c<-0;

While(i<N) do

  For j=0 to top

    If(s[i]∈a[j]) then c=1, end(for)

    If(c!=1) then

      {a[top]=s[i];b[top]=I;top++;vi++}

    C<-0;

    If(vi>Vmax) then { Vmax=vi; v[t]=a[t]; m[t]=b[t]}

    Else { if (i=N-1 AND top>0) then top--;i=b[top];vi--}

  I++

End(while)

Output(Vmax, v[i], m[i])

測試用例及結果說明

事件總數:N=10;

測試事件開始及其結束時間:

第1件活動的開始時間爲: 1

結束時間爲: 9

第2件活動的開始時間爲: 1

結束時間爲: 2

第3件活動的開始時間爲: 2

結束時間爲: 3

第4件活動的開始時間爲: 3

結束時間爲: 4

第5件活動的開始時間爲: 4

結束時間爲: 5

第6件活動的開始時間爲: 5

結束時間爲: 6

第7件活動的開始時間爲: 6

結束時間爲: 7

第8件活動的開始時間爲: 7

結束時間爲: 8

第9件活動的開始時間爲: 4

結束時間爲: 6

第10件活動的開始時間爲: 8

結束時間爲: 9

測試結果:

最大兼容活動包含8件活動

最大兼容活動集合爲

起始時間爲 1結束時間爲 2的第 2件事

起始時間爲 2結束時間爲 3的第 3件事

起始時間爲 3結束時間爲 4的第 4件事

起始時間爲 4結束時間爲 5的第 5件事

起始時間爲 5結束時間爲 6的第 6件事

起始時間爲 6結束時間爲 7的第 7件事

起始時間爲 7結束時間爲 8的第 8件事

起始時間爲 8結束時間爲 9的第 10件事

設計及測試過程

第一步:提出問題;

第二步:問題轉換;

第三步:算法構思;

第四步:僞碼描述;

第五步:代碼編寫;

第六步:代碼測試;

第七步:代碼修正;

遇到問題及解決方法:

遇到問題:端點值難以辨別,

解決方法:理清思路,逐步分析,合理調整變量之間關係。

參考題目:揹包問題,揹包最大可容價值問題。

評價和改進

算法優點:能夠準確找到最大可容納事件數目

算法缺點:如果多組事件總數相同且均爲最大事件總數,則只能輸出第一組事件序號

功能拓展:可以再建立一個存儲空間存放所有能夠構成最大事件總數的組合

功能應用:可以方便人們解決一些數據量巨大的最優解問題

附:源程序

#include<iostream>

#define N 10

using namespace std;

struct node

{

    int s;

    int f;

}s[N],v[N],a[N];

int main()

{

    int i,j,k,t,m[N],vi=0,top=0,b[N],Vmax=0,c=0;

    cout<<"請輸入各個項目開始及結束時間"<<endl;;

    for(i=0;i<N;i++)

    {

         cout<<"第"<<i+1<<"件活動的開始時間爲: ";

         cin>>s[i].s;

         cout<<"結束時間爲: ";

         cin>>s[i].f;

    }

    a[0].s=0;

    a[0].f=0;

    i=0;

    while(i<N)

    {

         for(j=0;j<=top;j++)

             if((s[i].s>=a[j].s&&s[i].s<a[j].f)||(s[i].f>a[j].s&&s[i].f<=a[j].f))

             {

                  c=1;

                  break;

             }

         if(c!=1)

         {

             a[top+1]=s[i];

             b[top+1]=i;

             top++;

             vi++;

         }

         c=0;

         if(vi>Vmax)

         {

             Vmax=vi;

             for(t=0;t<vi;t++)

             {

                  v[t]=a[t+1];

                  m[t]=b[t+1]+1;

             }

         }

         else

         {

         if(i==N-1&&top>=0)

         {

             top--;

             i=b[top+1];

             vi--;

         }

         }

         i++;

    }

    cout<<"最大兼容活動包含"<<Vmax<<"件活動"<<endl<<"最大兼容活動集合爲"<<endl;

    for(i=0;i<Vmax;i++)

         cout<<"起始時間爲 "<<v[i].s<<"結束時間爲 "<<v[i].f<<"的第 "<<m[i]<<"件事"<<endl;

    system("pause");

    return 0;

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章