例題:百雞問題:有一個人有一百塊錢,打算買一百隻雞。到市場一看,公雞三塊錢一隻,母雞兩塊錢一個,小雞一塊錢三隻。現在,請你編一程式,幫他計劃一下,怎麼樣買法,才能剛好用一百塊錢買一百隻雞? 按照枚舉演算法的思路,首先應該構造可能解的集合:S={(x,y,z)|0≤x,y,z≤100},其中三元組(x,y,z)表示買公雞x只,母雞y只和小雞z只。因為一共需要買100隻雞,因此,買公雞、母雞和小雞的數量都不會超過100。然後確定驗證解的條件:x+y+z=100 and 3x+2y+z/3=100。 下面是解這百雞問題的程式:
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int i,j,k;
for(i=0;i<100;i++)
for(j=0;j<100;j++)
for(k=0;k<100;k++)
{
if((i+j+k==100)&&(i*3+j*2+k/3==100)&&(k%3==0))
cout<<"買"<<i<<"公雞,"<<"買"<<j<<"母雞,"<<"買"<<k<<"小雞"<<endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
按照上面的程式,程式需要迴圈1003次,即|S|=1003。我們通過條件x+y+z=100來約束求解空間,縮小可能解的集合的規模,請看下面的程式:
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int i,j,k;
for(i=0;i<100;i++)
for(j=0;j<100-i;j++)
{
k=100-i-j;
if((i+j+k==100)&&(i*3+j*2+k/3==100)&&(k%3==0))
cout<<"買"<<i<<"公雞,"<<"買"<<j<<"母雞,"<<"買"<<k<<"小雞"<<endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
程式運行結果相同,但是迴圈次數為(100*101/2),是程式1迴圈次數的1/200左右。 從上面的對比可以看出,對於枚舉演算法,程式最佳化的主要考慮方向是:通過加強約束條件,縮小可能解的集合的規模。