1. 程式人生 > >java課作業一則:動態規劃(不優化)

java課作業一則:動態規劃(不優化)

tex value 交叉點 util 並且 class 分享圖片 and 簡單的

/*

*1、實驗內容:1)第1題:

*設平面上有一個m×n 的網格,將左下角的網格點標記為(0,0)而右上角的網格點標記為(m,n).某人想從(0,0)出發沿網格線行進到達(m,n).

*但是在網格點(i,j)處他只能向上行進或者向右行進,向上行進的代價為aij(aij=+∞),向右行進的代價是bij(bij=+∞)

*試設計一個動態規劃算,在這個網格中為該旅行者尋找一條代價最小的旅行路線。編寫一個簡單的應用程序進行編譯、運行;

*根據網上類似DP問題的思路,為了一致和方便,把左上角標記為起點(0,0),右下角為終點(m,n),每條路徑的value(代價)設成了[1,10].

*/

import

java.util.Scanner;

import java.util.Random;

public class ShortestPath

{

public static void main(String[] args)

{

//輸入行數、列數,用m橫n豎表示

Scanner matrix = new Scanner(System.in);

System.out.println("請輸入行數m:");

int m = matrix.nextInt() + 1;

System.out.println("請輸入列數n:");

int n = matrix.nextInt() + 1;

System.out.println("這是一個" + m + "橫" + n + "豎的網格.\n");

//①產生一個↓ 的aij矩陣:m行n-1列,value[1,10]隨機產生,並且打印.

System.out.println("①↓豎著走每一條線的值(aij)如下:");

int[][] aij = new int[m - 1][n];//矩陣aij,存放↓路徑的value

for(int i = 0; i < m - 1; i++)

{

for(int j = 0; j < n; j++)

{

Random rand2 = new Random();

aij[i][j] =(rand2.nextInt(10) + 1);

System.out.printf("%3d",aij[i][j]);

}

System.out.println("\n");

}

//②同理產生一個 → 的bij矩陣:m-1行n列,value[1,10]隨機產生,並且打印.

System.out.println("②→橫著走每一條線的值(bij)如下:");

int[][] bij = new int[m][n - 1];//矩陣bij,存放→路徑的value

for(int i = 0; i < m; i++)

{

for(int j = 0; j < n - 1; j++)

{

Random rand1 = new Random();

bij[i][j] =(rand1.nextInt(10) + 1);

System.out.printf("%3d",bij[i][j]);

}

System.out.println("\n");

}

/*③

* 根據動態規劃的設計,畫出dp矩陣:

* 先打印第一橫線的每個node的value;

* 再打印第一豎線的每個node的value;

* 然後,比較(根據上方入口node和對應的向下的abj,左側入口node和向右的bij,補全dp矩陣.

* 最後,打印

*/

int[][] Dp = new int[m][n];//矩陣dp,存放每一node的最短路徑值.

Dp[0][0] = 0;

for(int i = 1; i < m; i++)

{

Dp[i][0] = Dp[i - 1][0] + aij[i - 1][0];

}

for(int j = 1; j < n; j++)

{

Dp[0][j] = Dp[0][j - 1] + bij[0][j - 1];

}

for(int i = 0; i < m - 1; i++)

{

for(int j = 0; j < n - 1; j++)

{

Dp[i+1][j+1] = Math.min(Dp[i + 1][j] + bij[i + 1][j] ,Dp[i][j+1] + aij[i][j + 1]);

}

}

System.out.printf("③到達每個節點的最小值:\n");

for(int i = 0; i < m; i++)

{

for(int j = 0; j < n; j++)

{

System.out.printf("%5d",Dp[i][j]);

}

System.out.println(" \n");

}


/*

* 下面是輸出到達節點的最優路徑(從"終點"往"左上角起點"倒著再走一遍即可)

* 要找個數組s[k]記錄每一次的倒著走的過程;要註意到達網格邊緣的特殊情況

*/

Scanner node = new Scanner(System.in);

System.out.println("請輸入交叉點位於第幾橫:");

int a = node.nextInt();

System.out.println("請輸入交叉點位於第幾豎:");

int b = node.nextInt();

if((a <= n) && (a >= 0) && (b <= m) && (b >= 0))//排除用戶輸入有誤的情況

{

int [] s = new int [a + b - 1];//新建Step數組存放每一步是向下↓還是向右→,長度應該和下面的k一樣,但是讓k=0很麻煩,故比k長1.

int k = a + b - 2;//從起點到終點的步驟數目

int i = a - 1;

int j = b - 1;

while(i != 0 && j != 0)

{

if(Dp[i][j] == Dp[i][j - 1] + bij[i][j - 1])//判斷(每一個)終點值來自何方,並用1/0記錄.

{

s[k] = 0;//0標記為Right

j--;

k--;

}

else

{

s[k]= 1 ;//1標記為Down

i --;

k --;

}

if(i == 0)//走到第1橫了,只能往左方向走(從右側來).

{

while(j != 0)

{

s[k] = 0;

j --;

k --;

}

}

if(j == 0)//走到第1豎了,只能往上方向走(從下側來).

{

while(i != 0)

{

s[k] = 1;

i --;

k --;

}

}

}

System.out.println("具體過程:");//按照上邊用s[k]數組存的0/1,打印過程

for (i = 1; i <= a + b - 2 ; i ++ )

{

if ( s[i] == 0 )

System.out.println("Right→");

else

System.out.println("Down↓");

}

}

else

System.out.println("輸入有誤");

}

}


技術分享圖片

java課作業一則:動態規劃(不優化)