導航:首頁 > 源碼編譯 > 貪婪演算法的應用實例

貪婪演算法的應用實例

發布時間:2022-06-01 17:44:30

『壹』 貪心演算法

#include <stdio.h>

#define M 100

void main()

{

int i,j,k,temp,m,n;

int t[M]={2,14,4,16,6,5,3},p[M]={1,2,3,4,5,6,7},s[M],d[M]={0};

m=3;n=7;

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

for(j=0;j<7-i;j++)

if(t[j]<t[j+1])

{

temp=t[j];

t[j]=t[j+1];

t[j+1]=temp;

temp=p[j];

p[j]=p[j+1];

p[j+1]=temp;

}

for(i=0;i<m;i++) //求時間。

{

s[i]=p[i];

d[i]=t[i];

}

for(k=0;k<m;k++)

printf(" %d",d[k]);

printf("\n");

for(i=m;i<n;i++)

{

for(k=0;k<m-1;k++) //求最小。

{

temp=d[k];

if(temp>d[k+1])

{temp=d[k+1];j=k+1;}

}

printf("這是最小下標的: %d\n",j);

printf("最小的值: %d\n",temp);

for(k=0;k<m;k++)

printf(" %d",d[k]);

printf("\n");

//j=temp;

s[j]=s[j]+p[i];

d[j]=d[j]+t[i];

}

printf("\n");

for(k=0;k<7;k++)

printf(" %d",t[k]);

printf("\n");

for(k=0;k<7;k++)

printf(" %d",p[k]);

printf("\n");

for(k=0;k<m;k++)

printf(" %d",s[k]);

printf("\n");

for(k=0;k<m;k++)

printf(" %d",d[k]);

printf("\n");

}

『貳』 貪心演算法的例題分析

例題1、
[0-1背包問題]有一個背包,背包容量是M=150。有7個物品,物品不可以分割成任意大小。
要求盡可能讓裝入背包中的物品總價值最大,但不能超過總容量。
物品 A B C D E F G
重量 35kg 30kg 6kg 50kg 40kg 10kg 25kg
價值 10$ 40$ 30$ 50$ 35$ 40$ 30$
分析:
目標函數:∑pi最大
約束條件是裝入的物品總重量不超過背包容量:∑wi<=M(M=150)
⑴根據貪心的策略,每次挑選價值最大的物品裝入背包,得到的結果是否最優?
⑵每次挑選所佔重量最小的物品裝入是否能得到最優解?
⑶每次選取單位重量價值最大的物品,成為解本題的策略。
值得注意的是,貪心演算法並不是完全不可以使用,貪心策略一旦經過證明成立後,它就是一種高效的演算法。
貪心演算法還是很常見的演算法之一,這是由於它簡單易行,構造貪心策略不是很困難。
可惜的是,它需要證明後才能真正運用到題目的演算法中。
一般來說,貪心演算法的證明圍繞著:整個問題的最優解一定由在貪心策略中存在的子問題的最優解得來的。
對於例題中的3種貪心策略,都是無法成立(無法被證明)的,解釋如下:
⑴貪心策略:選取價值最大者。
反例:
W=30
物品:A B C
重量:28 12 12
價值:30 20 20
根據策略,首先選取物品A,接下來就無法再選取了,可是,選取B、C則更好。
⑵貪心策略:選取重量最小。它的反例與第一種策略的反例差不多。
⑶貪心策略:選取單位重量價值最大的物品。
反例:
W=30
物品:A B C
重量:28 20 10
價值:28 20 10
根據策略,三種物品單位重量價值一樣,程序無法依據現有策略作出判斷,如果選擇A,則答案錯誤。
【注意:如果物品可以分割為任意大小,那麼策略3可得最優解】
對於選取單位重量價值最大的物品這個策略,可以再加一條優化的規則:對於單位重量價值一樣的,則優先選擇重量小的!這樣,上面的反例就解決了。
但是,如果題目是如下所示,這個策略就也不行了。
W=40
物品:A B C
重量:25 20 15
價值:25 20 15
附:本題是個DP問題,用貪心法並不一定可以求得最優解,以後了解了動態規劃演算法後本題就有了新的解法。
例題2、
馬踏棋盤的貪心演算法
123041-23 XX
【問題描述】
馬的遍歷問題。在8×8方格的棋盤上,從任意指定方格出發,為馬尋找一條走遍棋盤每一格並且只經過一次的一條路徑。
【初步設計】
首先這是一個搜索問題,運用深度優先搜索進行求解。演算法如下:
⒈ 輸入初始位置坐標x,y;
⒉ 步驟 c:
如果c> 64輸出一個解,返回上一步驟c--
(x,y) ← c
計算(x,y)的八個方位的子結點,選出那些可行的子結點
循環遍歷所有可行子結點,步驟c++重復2
顯然⑵是一個遞歸調用的過程,大致如下:
C++程序: #defineN8voiddfs(intx,inty,intcount){inti,tx,ty;if(count>N*N){output_solution();//輸出一個解return;}for(i=0;i<8;i++){tx=hn[i].x;//hn[]保存八個方位子結點ty=hn[i].y;s[tx][ty]=count;dfs(tx,ty,count+1);//遞歸調用s[tx][ty]=0;}}Pascal程序: ProgramYS;ConstFXx:array[1..8]of-2..2=(1,2,2,1,-1,-2,-2,-1);FXy:array[1..8]of-2..2=(2,1,-1,-2,-2,-1,1,2);VarRoad:array[1..10,1..10]ofinteger;x,y,x1,y1,total:integer;ProcereFind(x,y:integer);varNx,Ny,i:integer;BeginFori:=1to8dobegin{8個方向}If(x+FXx[i]in[1..8])and(y+FXy[i]in[1..8])Then{確定新坐標是否越界}IfRoad[x+Fxx[i],y+Fxy[i]]=0Thenbegin{判斷是否走過}Nx:=x+FXx[i];Ny:=y+FXy[i];Road[Nx,Ny]:=1;{建立新坐標}If(Nx=x1)and(Ny=y1)Theninc(total)elseFind(Nx,Ny);{遞歸}Road[Nx,Ny]:=0{回朔}endendEnd;BEGIN{Main}Total:=0;FillChar(Road,sizeof(road),0);Readln(x,y);{讀入開始坐標}Readln(x1,y1);{讀入結束坐標}If(x>10)or(y>10)or(x1>10)or(y1>10)Thenwriteln('Error'){判斷是否越界}ElseFind(x,y);Writeln('Total:',total){打出總數}END.這樣做是完全可行的,它輸入的是全部解,但是馬遍歷當8×8時解是非常之多的,用天文數字形容也不為過,這樣一來求解的過程就非常慢,並且出一個解也非常慢。
怎麼才能快速地得到部分解呢?
【貪心演算法】
其實馬踏棋盤的問題很早就有人提出,且早在1823年,J.C.Warnsdorff就提出了一個有名的演算法。在每個結點對其子結點進行選取時,優先選擇『出口』最小的進行搜索,『出口』的意思是在這些子結點中它們的可行子結點的個數,也就是『孫子』結點越少的越優先跳,為什麼要這樣選取,這是一種局部調整最優的做法,如果優先選擇出口多的子結點,那出口少的子結點就會越來越多,很可能出現『死』結點(顧名思義就是沒有出口又沒有跳過的結點),這樣對下面的搜索純粹是徒勞,這樣會浪費很多無用的時間,反過來如果每次都優先選擇出口少的結點跳,那出口少的結點就會越來越少,這樣跳成功的機會就更大一些。這種演算法稱為為貪心演算法,也叫貪婪演算法或啟發式演算法,它對整個求解過程的局部做最優調整,它只適用於求較優解或者部分解,而不能求最優解。這樣的調整方法叫貪心策略,至於什麼問題需要什麼樣的貪心策略是不確定的,具體問題具體分析。實驗可以證明馬遍歷問題在運用到了上面的貪心策略之後求解速率有非常明顯的提高,如果只要求出一個解甚至不用回溯就可以完成,因為在這個演算法提出的時候世界上還沒有計算機,這種方法完全可以用手工求出解來,其效率可想而知。

『叄』 收集各類貪心演算法(C語言編程)經典題目

舉個例子,假如你買東西,老闆需要找給你99分錢,他有上面面值分別為25分,10分,5分,1分的硬幣(都是假如,不符合實際),他得找你3個25分,2個10分的,4個1分的才為最佳方案!
用貪心演算法編寫程序實現!
main()
{
int
i,a[5],b[4],c[4];
/*
define
the
type
of
the
money*/
a[1]=25;
a[2]=10;
a[3]=5;
a[4]=1;
printf("please
input
you
money
(fen):\n");
scanf("%d",&b[0]);
for
(i=1;i<=4;i++)
{
b[i]=b[i-1]%a[i];
/*take
n
25
off
and
money
left*/
c[i]=(b[i-1]-b[i])/a[i];
/*
n
*/
printf("%d
is
%d\n",a[i],c[i]);
}
getch();
}

『肆』 5.貪心演算法的核心思想。6.什麼是遞歸什麼是迭代兩者的區別,舉例說明。7.回溯的含義是什麼舉例

1、貪心演算法主要是把問題分成很多局部問題,用局部最優解合成整體最優解。因此使用這種演算法需要此問題滿足兩個條件,一個是能夠分成多個能夠求解的局部問題,第二個就是局部問題的解能夠合成最優解。和動態規劃、回溯等相比差別就是再不回溯的前提下找出整體最優解或者接近最優解,速度快但應用有比較大的限制。

2、迭代也叫遞推,通過重復執行某一步驟或者函數來求得計算結果
遞歸是指函數中直接或者間接調用自身
舉例:
求a乘以2的10次方等於幾
迭代:
for (i=0;i<10;i++)
a *= 2;

遞歸:
int db(int a,int num)
{
if (num<10)
return 2 * db(a,num+1);
else
return 1;
}

db(a,0);

3、回溯的含義就是在搜索問題的狀態過程中,如果不能繼續前進,再向後回到岔口,換一條路繼續搜索,直到搜索完所有狀態或者查找到需要的狀態。
舉例:(最典型的就是樹的深度搜索,下面舉一個簡單的例子)
int a[10]={5,3,7,9,3,2,5,6,9,1};//從3開始查找1
int read[10]=(0);//是否查找過
int readNum = 0;//查找過的個數
int forward = 1;//1為左,2為右
int tmp = 0,index = 5;

tmp = a[index];
read[index] = 1;
readNum++;
while (tmp != 1 || readNum != 10)
{
if (forward == 1)
index --;
else
index++;
if (!read[index])
{
tmp = a[index];
read[index] = 1;
readNum++;
}

if (index <=0 || index>=9)
forward = 3 - forward;
}

『伍』 適度貪婪的成功事例

演算法中的貪婪演算法,很著名的一個例子是使用貪婪演算法解馬踏棋盤

『陸』 什麼是貪心演算法,用實例分析貪心演算法是如何解決實際問題

比如: int a=3,b=4,c; c=a+++b; 將被解釋為 c=(a++)+b; 而不會被解釋為 c=a+(++b); 貪心演算法的主要意義是從左至右依次解釋最多的符號!

『柒』 貪心演算法的數學應用

如把3/7和13/23分別化為三個單位分數的和
【貪心演算法】
設a、b為互質正整數,a<b 分數a/b 可用以下的步驟分解成若干個單位分數之和:
步驟一: 用b 除以a,得商數q1 及余數r1。(r1=b - a*q1)
步驟二:把a/b 記作:a/b=1/(q1+1)+(a-r1)/b(q1+1)
步驟三:重復步驟2,直到分解完畢
3/7=1/3+2/21=1/3+1/11+1/231
13/23=1/2+3/46=1/2+1/16+1/368
以上其實是數學家斐波那契提出的一種求解埃及分數的貪心演算法,准確的演算法表述應該是這樣的:
設某個真分數的分子為a,分母為b;
把b除以a的商部分加1後的值作為埃及分數的某一個分母c;
將a乘以c再減去b,作為新的a;
將b乘以c,得到新的b;
如果a大於1且能整除b,則最後一個分母為b/a;演算法結束;
或者,如果a等於1,則,最後一個分母為b;演算法結束;
否則重復上面的步驟。
備註:事實上,後面判斷a是否大於1和a是否等於1的兩個判斷可以合在一起,及判斷b%a是否等於0,最後一個分母為b/a,顯然是正確的。
PHP代碼: classtanxin{public$weight;public$price;publicfunction__construct($weight=0,$price=0){$this->weight=$weight;$this->price=$price;}}//生成數據$n=10;for($i=1;$i<=$n;$i++){$weight=rand(1,20);$price=rand(1,10);$x[$i]=newtanxin($weight,$price);}//輸出結果functiondisplay($x){$len=count($x);foreach($xas$val){echo$val->weight,'',$val->price;echo'<br>';}}//按照價格和重量比排序functiontsort(&$x){$len=count($x);for($i=1;$i<=$len;$i++){for($j=1;$j<=$len-$i;$j++){$temp=$x[$j];$res=$x[$j+1]->price/$x[$j+1]->weight;$temres=$temp->price/$temp->weight;if($res>$temres){$x[$j]=$x[$j+1];$x[$j+1]=$temp;}}}}//貪心演算法functiontanxin($x,$totalweight=50){$len=count($x);$allprice=0;for($i=1;$i<=$len;$i++){if($x[$i]->weight>$totalweight)break;else{$allprice+=$x[$i]->price;$totalweight=$totalweight-$x[$i]->weight;}}if($i<$len)$allprice+=$x[$i]->price*($totalweight/$x[$i]->weight);return$allprice;}tsort($x);//按非遞增次序排序display($x);//顯示echo'0-1背包最優解為:';echotanxin($x);java源代碼 packagemain;importjava.util.ArrayList;importjava.util.Collections;importjava.util.Comparator;importjava.util.List;importjava.util.Random;publicclassMain{/***測試*/publicstaticvoidmain(String[]args){//1.隨機構造一批任務List<Pair<Integer>>inputList=newArrayList<Pair<Integer>>();Randomrand=newRandom();for(intn=0;n<20;++n){Integerleft=rand.nextInt(100);Integerright=left+rand.nextInt(100)+1;Pair<Integer>pair=newPair<Integer>(left,right);inputList.add(pair);}//將任務列表按結束時間排序(也就是根據right欄位進行排序)sortByRight(inputList);printPairList(inputList);//執行演算法List<Pair<Integer>>outputList=algorithm(inputList);System.out.println();printPairList(outputList);}/***貪心演算法**@paraminputList*@return使數量最多的任務方案*/publicstatic<TextendsComparable<T>>List<Pair<T>>algorithm(List<Pair<T>>inputList){if(null==inputList||inputList.size()==0||inputList.size()==1){returninputList;}sortByRight(inputList);List<Pair<T>>outputList=newArrayList<Pair<T>>();intlast=0;outputList.add(inputList.get(last));intintputSize=inputList.size();for(intm=1;m<intputSize;++m){Pair<T>nextPair=inputList.get(m);TnextLeft=nextPair.getLeft();Pair<T>lastOutPair=inputList.get(last);TlastRight=lastOutPair.getRight();intflag=nextLeft.compareTo(lastRight);if(flag>=0){outputList.add(nextPair);last=m;}}returnoutputList;}/***對傳入的List<Pair<T>>對象進行排序,使Pair根據right從小到大排序。**@paraminputList*/privatestatic<TextendsComparable<T>>voidsortByRight(List<Pair<T>>inputList){CompareByRight<T>comparator=newCompareByRight<T>();Collections.sort(inputList,comparator);}/***列印一個List<Pair<T>>對象。**@paraminputList*/privatestatic<TextendsComparable<T>>voidprintPairList(List<Pair<T>>inputList){for(Pair<T>pair:inputList){System.out.println(pair.toString());}}}/***根據Pair.right比較兩個Pair。用於Conlections.sort()方法。**@param<T>*/classCompareByRight<TextendsComparable<T>>implementsComparator<Pair<T>>{/*@Override*/publicintcompare(Pair<T>o1,Pair<T>o2){Tr1=o1.getRight();Tr2=o2.getRight();intflag=r1.compareTo(r2);returnflag;}}/***代表一個任務對象。有點裝逼用模板來寫了。left表示開始時間,right表示結束時間。**@param<T>*/classPair<TextendsComparable<T>>{privateTleft;privateTright;publicPair(Tleft,Tright){this.left=left;this.right=right;}@OverridepublicStringtoString(){return[left=+left.toString()+','+right=+right.toString()+']';}publicTgetLeft(){returnleft;}publicvoidsetLeft(Tleft){this.left=left;}publicTgetRight(){returnright;}publicvoidsetRight(Tright){this.right=right;}}

『捌』 怎樣應用貪心演算法求得最優解

動態規劃要求。。具有最優子結構,記f[i]最優時,f[i - 1]的解也最優。。。最終可以得到最優解

貪心演算法,一般只能得到近優解或者局部最優解。。

『玖』 求背包問題貪心演算法實例結果

找零錢問題:以人民幣1元,2元,5元,10元,20元,50元,100元為例,要求所找的張數最少
背包問題:假設物體重量W1,W2...Wn其對應的價值為P1,P2...Pn,物體可分割,求裝入重量限制為m的背包中的物體價值最大.可用P/W來解答.
#include<iostream>
#include<algorithm>
using namespace std;
struct good//表示物品的結構體
{
double p;//價值
double w;//重量
double r;//價值與重量的比
}a[2000];
double s,value,m;
int i,n;
bool bigger(good a,good b)
{
return a.r>b.r;
}
int main()
{
scanf("%d",&n);//物品個數
for (i=0;i<n;i++)
{
scanf("%lf%lf",&a[i].w,&a[i].p);
a[i].r=a[i].p/a[i].w;
}
sort(a,a+n,bigger);//調用sort排序函數,你大概不介意吧,按照價值與重量比排序貪心
scanf("%lf",&m);//讀入包的容量m
s=0;//包內現存貨品的重量
value=0;//包內現存貨品總價值
for (i=0;i<n&&s+a[i].w<=m;i++)
{
value+=a[i].p;
s+=a[i].w;
}
printf("The total value in the bag is %.2lf.\n",value);//輸出結果
return 0;
}

『拾』 哪些常見演算法屬於貪婪演算法

顯然KMP和FLOYD演算法不是貪心演算法,FLOYD演算法是使用了類似於動態規劃的思想,而KMP演算法則是對串的前綴進行去處理得到所有可能出現匹配的位置從而減少不必要的位移。貪心演算法可能還有很多,但是一般能用到的可能只有這些。在確定一個問題是否能用貪心來解決的時候應該線能夠證明在這里使用貪心演算法的正確性(詳見演算法導論)

閱讀全文

與貪婪演算法的應用實例相關的資料

熱點內容
單片機最小系統電路設計流程圖 瀏覽:663
steam源碼 瀏覽:29
關於對數的運演算法則及公式 瀏覽:775
明星談如何緩解壓力 瀏覽:141
androidlistview隱藏列 瀏覽:396
plc跑馬燈編程 瀏覽:816
ios開發之網路編程 瀏覽:421
處理照片視頻哪個app好 瀏覽:386
logback壓縮 瀏覽:888
冰箱壓縮機可以用氣割嗎 瀏覽:531
菜鳥如何加密商品信息 瀏覽:315
程序員那麼可愛小說結局 瀏覽:866
zenity命令 瀏覽:570
監禁風暴哪個app有 瀏覽:871
程序員的愛心是什麼 瀏覽:595
java中對字元串排序 瀏覽:296
單片機用數模轉換生成三角波 瀏覽:640
外網怎麼登陸伺服器地址 瀏覽:140
什麼人要懂編譯原理 瀏覽:154
源碼改單 瀏覽:719