怎樣進(jìn)入建設(shè)通網(wǎng)站怎樣做網(wǎng)站
隊(duì)列的應(yīng)用
- 1.基于隊(duì)列的醫(yī)院掛號(hào)模擬系統(tǒng)
- 2.隊(duì)列的運(yùn)用
1.基于隊(duì)列的醫(yī)院掛號(hào)模擬系統(tǒng)
代碼實(shí)現(xiàn)分享
2.隊(duì)列的運(yùn)用
問題描述:某運(yùn)動(dòng)會(huì)設(shè)立N個(gè)比賽項(xiàng)目,每個(gè)運(yùn)動(dòng)成員可以參加1~3個(gè)項(xiàng)目。試問如何安排比賽日程,既可以使同一運(yùn)動(dòng)員參加的項(xiàng)目不安排在同一時(shí)間進(jìn)行,又可以使總的競(jìng)賽項(xiàng)目日程最短。
若將此問題抽象成數(shù)學(xué)模型,則歸屬于“劃分子集問題”,即將集合A劃分成k個(gè)不想交的子集:A1,A2…,Ak(K<=n),使得同一子集中的元素均無沖突關(guān)系,并要求劃分子集數(shù)目盡可能地少。
也可以把這個(gè)問題表述為:同一子集的項(xiàng)目為可以同時(shí)進(jìn)行的項(xiàng)目,并且希望運(yùn)動(dòng)會(huì)的日程盡可能的短。
解決劃分子集問題可利用“過篩”的方法。從第一個(gè)元素考慮起,凡不和第一個(gè)元素發(fā)生沖突的元素都可以和它分在同一子集中,然后再“過篩”出一批互補(bǔ)沖突的元素為第二子集,依此類推,直至所有元素都進(jìn)入某個(gè)子集為止。
為了更好地描述用“過篩”的方法劃分子集,用隊(duì)列保存待選項(xiàng)目編號(hào),用一維數(shù)組case保存待選項(xiàng)編號(hào)與已入選子集的項(xiàng)目編號(hào)的沖突情況。排在隊(duì)頭的項(xiàng)目編號(hào)i是當(dāng)前的待選項(xiàng)目,能否入選由case[i]的值來決定,值為0表示與當(dāng)前子集的項(xiàng)目無沖突,i出隊(duì)并加入子集;反之則有沖突,i出隊(duì)并重新排隊(duì),等待下一個(gè)子集的篩選。
下面給出劃分第1個(gè)子集A1的主要步驟。
(1)將項(xiàng)目編號(hào)0~8依次進(jìn)隊(duì)列。將隊(duì)頭的項(xiàng)目編號(hào)0出隊(duì),放入子集A1中,將沖突數(shù)組與項(xiàng)目0對(duì)應(yīng)的行取出放入一維數(shù)組case中。此時(shí)case中的每個(gè)元素的值表示元素下標(biāo)的項(xiàng)目與項(xiàng)目0的沖突情況。
(2)當(dāng)前隊(duì)頭是項(xiàng)目1,項(xiàng)目1能否加入子集A1由case[1]的值來決定。當(dāng)前case[1]是1,表示項(xiàng)目1與子集A1中的項(xiàng)目0有沖突,項(xiàng)目1不能加入子集A1,出隊(duì)后直接入隊(duì)。
(3)當(dāng)前隊(duì)頭是項(xiàng)目2,項(xiàng)目2能否加入子集A1由case[2]的值來決定。當(dāng)前case[2]是0,表明項(xiàng)目2與子集A1中的已有項(xiàng)目沒有沖突,項(xiàng)目2出隊(duì)后加入子集A1?,F(xiàn)在A1中已經(jīng)有了2個(gè)項(xiàng)目,后來入選的項(xiàng)目必須與A1中的2個(gè)項(xiàng)目都沒有沖突,為此將沖突表中與剛?cè)脒x的項(xiàng)目2對(duì)應(yīng)的行按下標(biāo)與case數(shù)組相加,用兩者的和更新case數(shù)組,此時(shí)的case數(shù)組是后續(xù)待選項(xiàng)目能否入選的依據(jù)。
(4)當(dāng)前隊(duì)頭是項(xiàng)目3,項(xiàng)目3能否加入子集A1由case[3]的值來決定。當(dāng)前case[3]是0,表明項(xiàng)目3與子集A1中的已有項(xiàng)目沒有沖突,項(xiàng)目3出隊(duì)后加入子集A1。現(xiàn)在A1中已經(jīng)有3個(gè)項(xiàng)目,后來入選的項(xiàng)目必須與A1中的3個(gè)項(xiàng)目都沒有沖突,為此將沖突表中與剛?cè)脒x的項(xiàng)目3對(duì)應(yīng)的行按小標(biāo)與case數(shù)組相加,用兩者的和更新case數(shù)組。此時(shí)的case數(shù)組是后續(xù)待選項(xiàng)目能否入選的依據(jù)。
(5)當(dāng)前隊(duì)頭是項(xiàng)目4,項(xiàng)目4能否加入子集A1由case[4]的值來決定。當(dāng)前case[4]是1,表明項(xiàng)目4與子集A1中的已有項(xiàng)目有沖突,項(xiàng)目不能加入子集A1,出隊(duì)后直接進(jìn)隊(duì)。
(6)當(dāng)前隊(duì)頭是項(xiàng)目5,項(xiàng)目5能否加入子集A1由case[5]的值來決定。當(dāng)前case[5]是2,表明項(xiàng)目5與子集A1中的已有項(xiàng)目沖突,項(xiàng)目5不能加入子集A1,出隊(duì)后直接入隊(duì)。
(7)當(dāng)前隊(duì)頭是項(xiàng)目6,項(xiàng)目6能否加入子集A1由case[6]的值來決定。當(dāng)前是1,表明6與子集A1中的已有項(xiàng)目沖突,項(xiàng)目6不能加入子集A1,出隊(duì)后直接入隊(duì)。
(8)當(dāng)前的隊(duì)頭是項(xiàng)目7,項(xiàng)目7能否加入子集A1由case[7]的值來決定。當(dāng)前case[7]是0與子集A1中的已有項(xiàng)目沒有沖突,項(xiàng)目7出隊(duì)后放入子集A1。現(xiàn)在A1中已經(jīng)有4個(gè)項(xiàng)目,后來的項(xiàng)目必須與A1中的4個(gè)項(xiàng)目都沒有沖突,為此將沖突表中與剛?cè)脒x的項(xiàng)目7對(duì)應(yīng)的行按下標(biāo)與case數(shù)組相加,用兩者的和更新case數(shù)組,此時(shí)的case數(shù)組后續(xù)待選項(xiàng)能否入選的依據(jù)。
(9)當(dāng)前隊(duì)頭是項(xiàng)目8,項(xiàng)目8能否加入子集A1由case[8]的值來決定。當(dāng)前case[8]是1,表明項(xiàng)目8與子集A1中的已有項(xiàng)目有沖突,項(xiàng)目8不能加入子集A1,出隊(duì)后直接入隊(duì)。
當(dāng)排在隊(duì)頭的項(xiàng)目編號(hào)小于剛加入子集的項(xiàng)目編號(hào)時(shí),表示隊(duì)列中的所有項(xiàng)目都被“過篩”一遍,第一個(gè)子集劃分完成。用同樣的方法劃分其他子集,直到隊(duì)列為空。
劃分子集算法的基本思想如下。
pre = n;組號(hào) = 0;//n為數(shù)據(jù)元素的個(gè)數(shù)
全體成員入棧
while(隊(duì)列不能為空)
{ //隊(duì)頭元素i出隊(duì)列;
if(i<pre)//開辟新的組
{
組號(hào)++;
case 數(shù)組初始化;
}
if(i能入組)//i與該組的元素沒有沖突
{
i入組,記下序號(hào)為i的元素所屬組號(hào);
修改case數(shù)組;
}
else i重新入隊(duì)列;
pre=i;//前一個(gè)出隊(duì)列的元素序號(hào)
}