書名
This presentation is the property of its rightful owner.
Sponsored Links
1 / 17

台北總公司/台北縣汐止市新台五路一段 112 號 10 樓 A 棟 PowerPoint PPT Presentation


  • 82 Views
  • Uploaded on
  • Presentation posted in: General

書名 Java 於資料結構與演算法之實習應用 書號  PG20098 原著  河西朝雄 著 譯者 周明憲 / 徐堯譯. 台北總公司/台北縣汐止市新台五路一段 112 號 10 樓 A 棟 Building A, 10F, 112, Shin-Tai-Wu Road Sec. 1, Shijr, Taipei, Taiwan. 電話/ 02-26962869  傳真/ 02-26962867 台中辦事處/台中市文心路一段 540 號 4 樓 -1 4-1F, 540, Wen Shing Road, Sec. 1, Taichung, Taiwan.

Download Presentation

台北總公司/台北縣汐止市新台五路一段 112 號 10 樓 A 棟

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


112 10 a

書名Java於資料結構與演算法之實習應用

書號 PG20098

原著 河西朝雄著

譯者 周明憲/徐堯譯

台北總公司/台北縣汐止市新台五路一段112號10樓A棟

Building A, 10F, 112, Shin-Tai-Wu Road Sec. 1, Shijr, Taipei, Taiwan.

電話/02-26962869 傳真/02-26962867

台中辦事處/台中市文心路一段540號4樓-1

4-1F, 540, Wen Shing Road, Sec. 1, Taichung, Taiwan.

電話/04-23287870 傳真/04-23108168

博碩網址:http://www.drmaster.com.tw


112 10 a

第九章 學習重點

  • 電腦中最有發展的應用技術之一為遊戲。可以用雙手自由的操縱畫面中的虛構世界,這種快感正是電玩的魅力。這種遊戲若要創造出更精確的虛構世界,就必須具有在高度繪圖技術及即時(real-time)情況下能夠適時反應的速度,因此這是一種沒有電腦就無法玩的遊戲。

  • 一般而言,遊戲(game)一詞令人有較為世俗的感覺,而益智(puzzle)則具有強烈的智慧思考遊戲的意義。古今中外,人們總會想出各種益智遊戲。這證明了不管是在哪個時代,人類對智慧的好奇心一樣都很旺盛。

  • 若將電腦應用在益智遊戲上,便會有如第4章所示的河內塔問題一般,明快的獲得解決。但一般而言,益智遊戲無法適用明快的演算法,而益智遊戲所適用且演算法也常常須一五一十的檢查各項狀況。這種演算法有逆向追蹤與動態程式,本章會探討說明這兩個演算法。


112 10 a

9-1 魔術方塊

  • 例題64 奇數魔術方塊將1~n2的數字排列在n×n(n為奇數)的正方形格子中,且各行、各列及各對角線的數字合計皆須相同

  • 數字少的時候,試著數次將格子填滿,就能求出解答,但數字多的時候,這方法就不適用了。求出n×n(n=3、5、7、9、...)的魔術方塊的演算法之大致內容如下:

    (1)將1放入第1行的中央

    (2)以方塊大小n除以放入數目的餘數若為1,則立即前進至下1個格子,否則前進至斜上方。

    (3)若超出上方,則移至同1列的最下1格

    (4)若超出右方,則移至同1行的最左1格


112 10 a

public void paint(Graphics g) {

final int N=7; // n魔術方塊(n=3,5,7,9,...)

int i,j,k;

int[][] hojin=new int[N+1][N+1];

j=(N+1)/2;i=0;

for (k=1;k<=N*N;k++) {

if ((k%N)==1)

i++;

else {

i--;j++;

}

if (i==0)

i=N;

if (j>N)

j=1;

hojin[i][j]=k;

}

g.drawString("奇數魔術方塊(N="+N+")",140,20);

for (i=1;i<=N;i++) {

for (j=1;j<=N;j++)

g.drawString(""+hojin[i][j],40*j,20*i+20);

}

}


64 4n

練習問題64 4N魔術方塊

  • 解4的倍數(4,8,12,16,...)的4N魔術方塊。

    4×4方塊的解法如圖9.3所示。

    (a) 由左上角開始從左到右的將1,2,3,4依序填入小格子內,再將5,6,7,8依序填入下一列的格子內,但不須將數字填入對角線內的格子。

    (b) 由左上角開始從左到右的將16,15,14,13依序填入小格子內,再將12,11,10,9依序填入下一列的格子內,但只須將數字填入對角線的格子內。

    (c) 將(a)與(b)組合起來即為解答。


112 10 a

public void paint(Graphics g) {

final int N=8; // 4N魔術方塊(n=4,8,12,16,...)

int i,j;

int[][] hojin=new int[N+1][N+1];

for (j=1;j<=N;j++) {

for (i=1;i<=N;i++) {

if (j%4==i%4 || (j%4+i%4)%4==1)

hojin[i][j]=(N+1-i)*N-j+1;

else

hojin[i][j]=(i-1)*N+j;

}

}

g.drawString("4N魔術方塊 (N="+N+")",160,20);

for (i=1;i<=N;i++) {

for (j=1;j<=N;j++)

g.drawString(""+hojin[i][j],40*j,20*i+20);

}

}


112 10 a

9-2 戰略性猜拳

  • 例題65 製作可讀出猜拳對手的習慣並使自己猜拳能力大增的程式

    分別以0、1、2代表石頭、剪刀、布,然後製作如表9.1所示的電腦與人的猜拳對戰表。

    當computer與man內分別存有0~2的資料時,則能以

    (computer-man+3)%3

    的值來進行下列的判定:

    0 ... 平手

    1 ...電腦輸

    2 ...電腦贏

    假設有人喜歡在出布以後再出石頭,也就是說這類人會受到自己先前出的拳的影響而決定出下一拳。電腦若遇到這種對手,則其戰略為:

    設對手之前出的拳為M,目前出的拳為man時,則表9.2的戰略表的table[m][man]的內容便要+1。猜拳時若使用這個方法,則可至做出如圖9.2所示的戰略資料。

table[m][man]


112 10 a

宣告

class Rei65Frame extends Frame {

private Checkbox cb1,cb2,cb3;

private TextArea ta;

private int[][] table={{0,0,0}, // 戰略表

{0,0,0},

{0,0,0}};

private int[] hist={0,0,0}; // 勝敗次數

private String[] hand={"石頭","剪刀","布"};

private String[] msg={"平手","你贏","電腦贏"};

private int m=0;

………………………………


112 10 a

public void actionPerformed(ActionEvent e) {

int computer,man,jg;

if (cb1.getState())

man=0;

else if (cb2.getState())

man=1;

else

man=2;

if (table[m][0]>table[m][1] && table[m][0]>table[m][2])

computer=2;

else if (table[m][1]>table[m][2])

computer=0;

else

computer=1;

jg=(computer-man+3) % 3;

hist[jg]++;

table[m][man]++; // 學習

m=man;

ta.setText("電腦出:"+hand[computer]+"\n"+

"判定:"+msg[jg]+"\n"+

"你的勝敗結果:"+hist[1]+"勝"+hist[2]+"敗"+hist[0]+"平手\n");

}


112 10 a

9-3 逆向追蹤

  • 逆向追蹤(back tracking)並不是要徹徹底底的搜尋全部的局面,而是有效率的判定不須搜尋的局面、並降低搜尋時間的演算法。

  • 練習問題66 8個皇后在8×8的棋盤上放置8個西洋棋的皇后棋子,然後求出所有皇后都互不對立的局面。西洋棋的皇后棋子可縱向、橫向與斜向前進。所謂的互不對立是指,某一皇后棋子可以前進的位置其他的皇后棋子不會進入。


112 10 a

private int[] column=new int[N+1], // 表示同一欄內是否有皇后棋子

rup=new int[2*N+1], // 表示是否在由右上角至左下角的對角線上

lup=new int[2*N+1], // 表示是否在由右下角至左下角的對角線上

queen=new int[N+1]; // 皇后棋子的位置

private int num; // 解答的編號

private String result; // 顯示結果


112 10 a

void backtrack(int i) {

int j,x,y;

if (i>N) {

result=result+"\n解答"+(++num)+"\n";

for (y=1;y<=N;y++) {

for (x=1;x<=N;x++)

if (queen[y]==x)

result=result+" Q";

else

result=result+" .";

result=result+"\n";

}

}

else {

for (j=1;j<=N;j++) {

if (column[j]==1 && rup[i+j]==1 && lup[i-j+N]==1) {

queen[i]=j; // (i,j)為皇后棋子的位置

column[j]=rup[i+j]=lup[i-j+N]=0; // 局面的變更

backtrack(i+1);

column[j]=rup[i+j]=lup[i-j+N]=1; // 回復至原貌

}

}

}

}


112 10 a

9-4 動態規劃

  • 動態規劃(dynamic programming)是最化畫問題的有效解法。

  • 求n個元素的最佳解時,可將由i個元素組成的部分集合最佳解製成表格後,求出結果。當增加1個元素時,便以此表為基礎計算出最佳解的變化,然後根據計算結果修改表格的內容。如此反覆操作直至全部集合(n個元素全部)均執行完畢,最後最佳解就可由表中求得。也就是說,動態規劃為從空集合的最佳解(初始值)開始,每當增加1個元素就將最佳解更新,而求得全部集合的最佳解之方法


112 10 a

背包問題與最佳解判定

將物品i放入時,大小s的背包的最佳解是否變更可由下列的式子來判定。

(1)將物品i放入至大小s的背包內後的剩餘空間設為p。

(2)將與 p同樣大小的背包之現在最佳解加上物品i的金額,並將此金額設為newvalue。

(3)若newvalue>「大小s的背包之現在最佳解(value[s])」,則

‧以newvalue修改大小s的最佳解

‧將物品i視為最後放入背包的物品,並記錄至item[s]。


112 10 a

public void paint(Graphics g) {

final int Limit=8, // 背包的重量限制

N=5, // 物品的種類

Min=1; // 重量的最小值

int i,s,p;

int[] item=new int[Limit+1];

long[] value=new long[Limit+1];

long newvalue;

class body {

String name; // 品名

int size; // 重量

long price; // 價格

public body(String n,int s,long p){

name=n; size=s; price=p;

}

}

body[] a={new body("plum",4,4500),new body("apple",5,5700),

new body("orange",2,2250),new body("strawberry",1,1100),

new body("melon",6,6700)};

………………


112 10 a

for (s=0;s<=Limit;s++) {

value[s]=0; // 初始值

}

for (i=0;i<N;i++) { // 物品的編號

for (s=a[i].size;s<=Limit;s++) { // 背包的大小

p=s-a[i].size; // 空背包的大小

newvalue=value[p]+a[i].price;

if (newvalue>value[s]) {

value[s]=newvalue;item[s]=i; // 最佳解的修改

}

}

}

int y=1;

g.drawString("品名",10,20);

g.drawString("價格",80,20);

for (s=Limit;s>=Min;s=s-a[item[s]].size) {

g.drawString(""+a[item[s]].name,10,y*20+20);

g.drawString(""+a[item[s]].price,80,y*20+20);

y++;

}

g.drawString("合計",10,y*20+20);

g.drawString(""+value[Limit],80,y*20+20);

}


  • Login