www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > > 程序員小灰
[導(dǎo)讀]前一段時(shí)間,小灰發(fā)布了上下兩篇關(guān)于股票買賣的算法題講解,激發(fā)了很多小伙伴的興趣。 這一次,小灰把這兩篇漫畫(huà)整合在一起,并且修改了其中的一些細(xì)節(jié)錯(cuò)誤。

前一段時(shí)間,小灰發(fā)布了上下兩篇關(guān)于股票買賣的算法題講解,激發(fā)了很多小伙伴的興趣。


這一次,小灰把這兩篇漫畫(huà)整合在一起,并且修改了其中的一些細(xì)節(jié)錯(cuò)誤,感謝小伙伴們的指正。



—————? 第二天? —————



什么意思呢?讓我們來(lái)舉個(gè)例子,給定如下數(shù)組:



該數(shù)組對(duì)應(yīng)的股票漲跌曲線如下:


顯然,從第2天價(jià)格為1的時(shí)候買入,從第5天價(jià)格為8的時(shí)候賣出,可以獲得最大收益:



此時(shí)的最大收益是 8-1=7。






在上面這個(gè)例子中,最大值9在最小值1的前面,我們又該怎么交易?總不能讓時(shí)間倒流吧?



————————————



以下圖為例,假如我們已經(jīng)確定價(jià)格4的時(shí)候?yàn)橘u出時(shí)間點(diǎn),那么此時(shí)最佳的買入時(shí)間點(diǎn)是哪一個(gè)呢?


我們要選擇價(jià)格4之前的區(qū)間,且必須是區(qū)間內(nèi)最小值,顯然,這個(gè)最佳的選擇是價(jià)格2的時(shí)間點(diǎn)。




第1步,初始化操作,把數(shù)組的第1個(gè)元素當(dāng)做臨時(shí)的最小價(jià)格;最大收益的初始值是0:



第2步,遍歷到第2個(gè)元素,由于2<9,所以當(dāng)前的最小價(jià)格變成了2;此時(shí)沒(méi)有必要計(jì)算差值的必要(因?yàn)榍懊娴脑乇人螅?,?dāng)前的最大收益仍然是0:



第3步,遍歷到第3個(gè)元素,由于7>2,所以當(dāng)前的最小價(jià)格仍然是2;如我們剛才所講,假設(shè)價(jià)格7為賣出點(diǎn),對(duì)應(yīng)的最佳買入點(diǎn)是價(jià)格2,兩者差值7-2=5,5>0,所以當(dāng)前的最大收益變成了5:




第4步,遍歷到第4個(gè)元素,由于4>2,所以當(dāng)前的最小價(jià)格仍然是2;4-2=2,2<5,所以當(dāng)前的最大收益仍然是5:



第5步,遍歷到第5個(gè)元素,由于3>2,所以當(dāng)前的最小價(jià)格仍然是2;3-2=1,1<5,所以當(dāng)前的最大收益仍然是5:



以此類推,我們一直遍歷到數(shù)組末尾,此時(shí)的最小價(jià)格是1;最大收益是8-1=7:



public?class?StockProfit?{

????public?static?int?maxProfitFor1Time(int?prices[])?{
????????if(prices==null?||?prices.length==0)?{
????????????return?0;
????????}
????????int?minPrice?=?prices[0];
????????int?maxProfit?=?0;
????????for?(int?i?=?1;?i?????????????if?(prices[i]?????????????????minPrice?=?prices[i];
????????????}?else?if(prices[i]?-?minPrice?>?maxProfit){
????????????????maxProfit?=?prices[i]?-?minPrice;
????????????}
????????}
????????return?maxProfit;
????}

????public?static?void?main(String[]?args)?{
????????int[]?prices?=?{9,2,7,4,3,1,8,4};
????????System.out.println(maxProfitFor1Time(prices));
????}

}


我們以下圖這個(gè)數(shù)組為例,直觀地看一下買入賣出的時(shí)機(jī):



在圖中,綠色的線段代表價(jià)格上漲的階段。既然買賣次數(shù)不限,那么我們完全可以在每一次低點(diǎn)都進(jìn)行買入,在每一次高點(diǎn)都進(jìn)行賣出。


這樣一來(lái),所有綠色的部分都是我們的收益,最大總收益就是這些局部收益的加總:


(6-1)+(8-3)+(4-2)+(7-4) =?15


至于如何判斷出這些綠色上漲階段呢?很簡(jiǎn)單,我們遍歷整個(gè)數(shù)組,但凡后一個(gè)元素大于前一個(gè)元素,就代表股價(jià)處于上漲階段。


????public?int?maxProfitForAnyTime(int[]?prices)?{
????????int?maxProfit?=?0;
????????for?(int?i?=?1;?i?????????????if?(prices[i]?>?prices[i-1])
????????????????maxProfit?+=?prices[i]?-?prices[i-1];
????????}
????????return?maxProfit;
????}




我們?nèi)匀灰灾暗臄?shù)組為例:



首先,尋找到1次買賣限制下的最佳買入賣出點(diǎn):


兩次買賣的位置是不可能交叉的,所以我們找到第1次買賣位置后,把這一對(duì)買入賣出點(diǎn)以及它們中間的元素全部剔除掉:



接下來(lái),我們按照同樣的思路,再?gòu)氖O碌脑刂袑ふ业?次買賣的最佳買入賣出點(diǎn):


這樣一來(lái),我們就找到了最多2次買賣情況下的最佳選擇:





對(duì)于上圖的這個(gè)數(shù)組,如果獨(dú)立兩次求解,得到的最佳買入賣出點(diǎn)分別是【1,9】和【6,7】,最大收益是?(9-1)+(7-6)=9:


但實(shí)際上,如果選擇【1,8】和【3,9】,最大收益是(8-1)+(9-3)=13>9:




當(dāng)?shù)?次最佳買入賣出點(diǎn)確定下來(lái),第2次買入賣出點(diǎn)的位置會(huì)有哪幾種情況呢?


情況1:第2次最佳買入賣出點(diǎn),在第1次買入賣出點(diǎn)左側(cè)


情況2:第2次最佳買入賣出點(diǎn),在第1次買入賣出點(diǎn)右側(cè)


情況3:第1次買入賣出區(qū)間從中間截?cái)?,重新拆分成兩次買賣



那么,如何判斷給定的股價(jià)數(shù)組屬于那種情況呢?很簡(jiǎn)單,在第1次最大買入賣出點(diǎn)確定后,我們可以比較一下哪種情況帶來(lái)的收益增量最大:



尋找左側(cè)和右側(cè)的最大漲幅比較好理解,尋找中間的最大跌幅有什么用呢?


細(xì)想一下就能知道,當(dāng)?shù)?次買賣需要被拆分開(kāi)來(lái)的時(shí)候,買賣區(qū)間內(nèi)的最大跌幅,就等同于拆分后的收益增量(類似于炒股的抄底操作):



這樣一來(lái),我們可以總結(jié)出下面的公式:


最大總收益 = 第1次最大收益 + Max(左側(cè)最大漲幅,中間最大跌幅,右側(cè)最大漲幅)


所謂動(dòng)態(tài)規(guī)劃,就是把復(fù)雜的問(wèn)題簡(jiǎn)化成規(guī)模較小的子問(wèn)題,再?gòu)暮?jiǎn)單的子問(wèn)題自底向上一步一步遞推,最終得到復(fù)雜問(wèn)題的最優(yōu)解。


首先,讓我們分析一下當(dāng)前這個(gè)股票買賣問(wèn)題,這個(gè)問(wèn)題要求解的是一定天數(shù)范圍內(nèi)、一定交易次數(shù)限制下的最大收益。


既然限制了股票最多買賣2次,那么股票的交易可以劃分為5個(gè)階段:


沒(méi)有買賣

第1次買入

第1次賣出

第2次買入

第2次賣出


我們把股票的交易階段設(shè)為變量m(用從0到4的數(shù)值表示),把天數(shù)范圍設(shè)為變量n。而我們求解的最大收益,受這兩個(gè)變量影響,用函數(shù)表示如下:


最大收益 = F(n,m)(n>=1,0<=m<=4


既然函數(shù)和變量已經(jīng)確定,接下來(lái)我們就要確定動(dòng)態(tài)規(guī)劃的兩大要素:


1.問(wèn)題的初始狀態(tài)
2.問(wèn)題的狀態(tài)轉(zhuǎn)移方程式


問(wèn)題的初始狀態(tài)是什么呢?我們假定交易天數(shù)的范圍只限于第1天,也就是n=1的情況:



1.如果沒(méi)有買賣,也就是m=0時(shí),最大收益顯然是0,也就是?F(1,0)= 0


2.如果有1次買入,也就是m=1時(shí),相當(dāng)于憑空減去了第1天的股價(jià),最大收益是負(fù)的當(dāng)天股價(jià),也就是?F(1,1)=?-price[0]


3.如果有1次買出,也就是m=2時(shí),買賣抵消(當(dāng)然,這沒(méi)有實(shí)際意義),最大收益是0,也就是?F(1,2)= 0


4.如果有2次買入,也就是m=3時(shí),同m=1的情況,F(1,3)= -price[0]


5.如果有2次賣出,也就是m=4時(shí),同m=2的情況,F(1,4)=?0



確定了初始狀態(tài),我們?cè)賮?lái)看一看狀態(tài)轉(zhuǎn)移。假如天數(shù)范圍限制從n-1天增加到n天,那么最大收益會(huì)有怎樣的變化呢?


這取決于現(xiàn)在處于什么階段(是第幾次買入賣出),以及對(duì)第n天股價(jià)的操作(買入、賣出或觀望)。讓我們對(duì)各個(gè)階段情況進(jìn)行分析:


1.假如之前沒(méi)有任何買賣,而第n天仍然觀望,那么最大收益仍然是0,即?F(n,0) = 0


2.假如之前沒(méi)有任何買賣,而第n天進(jìn)行了買入,那么最大收益是負(fù)的當(dāng)天股價(jià),即 F(n,1)=?-price[n-1]


3.假如之前有1次買入,而第n天選擇觀望,那么最大收益和之前一樣,即?F(n,1)=?F(n-1,1)


4.假如之前有1次買入,而第n天進(jìn)行了賣出,那么最大收益是第1次買入的負(fù)收益加上當(dāng)天股價(jià),即那么?F(n,2)=?F(n-1,1)+ price[n-1]


5.假如之前有1次賣出,而第n天選擇觀望,那么最大收益和之前一樣,即?F(n,2)=?F(n-1,2)


6.假如之前有1次賣出,而第n天進(jìn)行2次買入,那么最大收益是第1次賣出收益減去當(dāng)天股價(jià),即F(n,3)= F(n-1,2) - price[n-1]


7.假如之前有2次買入,而第n天選擇觀望,那么最大收益和之前一樣,即?F(n,3)=?F(n-1,3)


8.假如之前有2次買入,而第n天進(jìn)行了賣出,那么最大收益是第2次買入收益減去當(dāng)天股價(jià),即F(n,4)=?F(n-1,3) +?price[n-1]


9.假如之前有2次賣出,而第n天選擇觀望(也只能觀望了),那么最大收益和之前一樣,即?F(n,4)=?F(n-1,4)


最后,我們把情況【2,3】,【4,5】,【6、7】,【8,9】合并,可以總結(jié)成下面的5個(gè)方程式:


F(n,0) = 0

F(n,1)=? max(-price[n-1],F(n-1,1)

F(n,2)=? max(F(n-1,1)+ price[n-1],F(n-1,2)

F(n,3)=? max(F(n-1,2)-?price[n-1],F(n-1,3)

F(n,4)=? max(F(n-1,3)+?price[n-1],F(n-1,4)


從后面4個(gè)方程式中,可以總結(jié)出每一個(gè)階段最大收益和上一個(gè)階段的關(guān)系:


F(n,m)?= max(F(n-1,m-1)+?price[n-1],F(xiàn)(n-1,m))


由此我們可以得出,完整的狀態(tài)轉(zhuǎn)移方程式如下:






在表格中,不同的行代表不同天數(shù)限制下的最大收益,不同的列代表不同買賣階段的最大收益。


我們?nèi)匀焕弥袄赢?dāng)中的數(shù)組,以此為基礎(chǔ)來(lái)填充表格:



首先,我們?yōu)楸砀裉畛涑跏紶顟B(tài):



接下來(lái),我們開(kāi)始填充第2行數(shù)據(jù)。


沒(méi)有買賣時(shí),最大收益一定為0,因此F(2,0)的結(jié)果是0:



根據(jù)之前的狀態(tài)轉(zhuǎn)移方程式,F(xiàn)(2,1)= max(F(1,0)-2,F(xiàn)(1,1))= max(-2,-1)= -1,所以第2行第2列的結(jié)果是-1:



F(2,2)= max(F(1,1)+2,F(xiàn)(1,2))= max(1,0)= 1,所以第2行第3列的結(jié)果是1:



F(2,3)= max(F(1,2)-2,F(xiàn)(1,3))= max(-2,-1)= -1,所以第2行第4列的結(jié)果是-1:



F(2,4)= max(F(1,3)+2,F(xiàn)(1,4))= max(1,0)= 1,所以第2行第5列的結(jié)果是1:



接下來(lái)我們繼續(xù)根據(jù)狀態(tài)轉(zhuǎn)移方程式,填充第3行的數(shù)據(jù):



接下來(lái)填充第4行:



以此類推,我們一直填充完整個(gè)表格:



如圖所示,表格中最后一個(gè)數(shù)據(jù)13,就是全局的最大收益。


????//最大買賣次數(shù)
????private?static?int?MAX_DEAL_TIMES?=?2;

????public?static?int?maxProfitFor2Time(int[]?prices)?{
????????if(prices==null?||?prices.length==0)?{
????????????return?0;
????????}
????????//表格的最大行數(shù)
????????int?n?=?prices.length;
????????//表格的最大列數(shù)
????????int?m?=?MAX_DEAL_TIMES*2+1;
????????//使用二維數(shù)組記錄數(shù)據(jù)
????????int[][]?resultTable?=?new?int[n][m];
????????//填充初始狀態(tài)
????????resultTable[0][1]?=?-prices[0];
????????resultTable[0][3]?=?-prices[0];
????????//自底向上,填充數(shù)據(jù)
????????for(int?i=1;i????????????for(int?j=1;j????????????????if((j&1)?==?1){
????????????????????resultTable[i][j]?=?Math.max(resultTable[i-1][j],?resultTable[i-1][j-1]-prices[i]);
????????????????}else?{
????????????????????resultTable[i][j]?=?Math.max(resultTable[i-1][j],?resultTable[i-1][j-1]+prices[i]);
????????????????}
????????????}
????????}
????????//返回最終結(jié)果
????????return?resultTable[n-1][m-1];
????}




????//最大買賣次數(shù)
????private?static?int?MAX_DEAL_TIMES?=?2;

????public?static?int?maxProfitFor2TimeV2(int[]?prices)?{
????????if(prices==null?||?prices.length==0)?{
????????????return?0;
????????}
????????//表格的最大行數(shù)
????????int?n?=?prices.length;
????????//表格的最大列數(shù)
????????int?m?=?MAX_DEAL_TIMES*2+1;
????????//使用一維數(shù)組記錄數(shù)據(jù)
????????int[]?resultTable?=?new?int[m];
????????//填充初始狀態(tài)
????????resultTable[1]?=?-prices[0];
????????resultTable[3]?=?-prices[0];
????????//自底向上,填充數(shù)據(jù)
????????for(int?i=1;i????????????for(int?j=1;j????????????????if((j&1)?==?1){
????????????????????resultTable[j]?=?Math.max(resultTable[j],?resultTable[j-1]-prices[i]);
????????????????}else?{
????????????????????resultTable[j]?=?Math.max(resultTable[j],?resultTable[j-1]+prices[i]);
????????????????}
????????????}
????????}
????????//返回最終結(jié)果
????????return?resultTable[m-1];
????}


在這段代碼中,resultTable從二維數(shù)組簡(jiǎn)化成了一維數(shù)組。由于最大買賣次數(shù)是常量,所以算法的空間復(fù)雜度也從O(n)降低到了O(1)。




????public?static?int?maxProfitForKTime(int[]?prices,?int?k)?{
????????if(prices==null?||?prices.length==0?||?k<=0)?{
????????????return?0;
????????}
????????//表格的最大行數(shù)
????????int?n?=?prices.length;
????????//表格的最大列數(shù)
????????int?m?=?k*2+1;
????????//使用一維數(shù)組記錄數(shù)據(jù)
????????int[]?resultTable?=?new?int[m];
????????//填充初始狀態(tài)
????????for(int?i=1;i2)?{
????????????resultTable[i]?=?-prices[0];
????????}
????????//自底向上,填充數(shù)據(jù)
????????for(int?i=1;i????????????for(int?j=1;j????????????????if((j&1)?==?1){
????????????????????resultTable[j]?=?Math.max(resultTable[j],?resultTable[j-1]-prices[i]);
????????????????}else?{
????????????????????resultTable[j]?=?Math.max(resultTable[j],?resultTable[j-1]+prices[i]);
????????????????}
????????????}
????????}
????????//返回最終結(jié)果
????????return?resultTable[m-1];
????}




—————END—————



喜歡本文的朋友,歡迎關(guān)注公眾號(hào)?程序員小灰,收看更多精彩內(nèi)容

      
點(diǎn)個(gè)[在看],是對(duì)小灰最大的支持!


免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過(guò)流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問(wèn)題卻十分常見(jiàn),不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問(wèn)題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問(wèn)題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來(lái)解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開(kāi)關(guān)電源具有效率高的特性,而且開(kāi)關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開(kāi)關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉