1. 程式人生 > >C++_活動安排問題

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;

}