最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

算法詳解之分支限界法的具體實(shí)現(xiàn)

 更新時(shí)間:2014年02月17日 14:51:09   作者:  
這篇文章主要介紹了算法詳解之分支限界法的具體實(shí)現(xiàn),需要的朋友可以參考下

首先我們來(lái)關(guān)注一個(gè)問(wèn)題:

問(wèn)題描述:

布線問(wèn)題:印刷電路板將布線區(qū)域劃分成n×m個(gè)方格陣列,要求確定連接方格陣列中的方格a的中點(diǎn)到方格b的中點(diǎn)的最短布線方案。在布線時(shí),電路只能沿直線或直角布線,為了避免線路相交,已布了線的方格做了封鎖標(biāo)記,其他線路不允許穿過(guò)被封鎖的方格。如下圖所示:

 

算法思路:

布線問(wèn)題的解空間是一個(gè)圖,則從起始位置a開(kāi)始將它作為第一個(gè)擴(kuò)展結(jié)點(diǎn)。與該擴(kuò)展結(jié)點(diǎn)相鄰并可達(dá)的方格成為可行結(jié)點(diǎn)被加入到活結(jié)點(diǎn)隊(duì)列中,并且將這些方格標(biāo)記為1,即從起始方格a到這些方格的距離為1。接著,從活結(jié)點(diǎn)隊(duì)列中取出隊(duì)首結(jié)點(diǎn)作為下一個(gè)擴(kuò)展結(jié)點(diǎn),并將與當(dāng)前擴(kuò)展結(jié)點(diǎn)相鄰且未標(biāo)記過(guò)的方格標(biāo)記為2,并存入活結(jié)點(diǎn)隊(duì)列。這個(gè)過(guò)程一直繼續(xù)到算法搜索到目標(biāo)方格b或活結(jié)點(diǎn)隊(duì)列為空時(shí)為止。

在實(shí)現(xiàn)上述算法時(shí),

(1) 定義一個(gè)表示電路板上方格位置的類(lèi)Position。

它的2個(gè)成員row和col分別表示方格所在的行和列。在方格處,布線可沿右、下、左、上4個(gè)方向進(jìn)行。沿這4個(gè)方向的移動(dòng)分別記為0,1,2,3。下表中,offset[i].row和offset[i].col(i= 0,1,2,3)分別給出沿這4個(gè)方向前進(jìn)1步相對(duì)于當(dāng)前方格的相對(duì)位移。

(2) 用二維數(shù)組grid表示所給的方格陣列。

初始時(shí),grid[i][j] = 0, 表示該方格允許布線,而grid[i][j] = 1表示該方格被封鎖,不允許布線。

算法圖解:

代碼貼出來(lái):

復(fù)制代碼 代碼如下:

#include <stdio.h>
typedef struct {
  int row;
  int col;
}Position;
int FindPath (Position start, Position finish, int &PathLen, Position *&path)
{ //計(jì)算從起始位置start到目標(biāo)位置finish的最短布線路徑,找到返回1,否則,返回0
  int  i;
  if ((start.row = = finish.row) && (start.col = = finish.col)) {
PathLen = 0;   return 0; } //start = finish
  //設(shè)置方格陣列”圍墻”
  for (i = 0; i <= m+1; i++)
grid[0][i] = grid[n+1][i] = 1; //頂部和底部
  for (i = 0; i <= n+1; i++)
grid[i][0] = grid[i][m+1] = 1; //左翼和右翼
  //初始化相對(duì)位移
int  NumOfNbrs = 4; //相鄰方格數(shù)
  Position offset[4], here, nbr;
  offset[0].row = 0;   offset[0].col = 1;   //右
  offset[0].row = 1;   offset[0].col = 0;   //下
  offset[0].row = 0;   offset[0].col = -1;  //左
  offset[0].row = -1;  offset[0].row = 0;  //上
  here.row = start.row;
  here.col = start.col;
  LinkedQueue <Position> Q; //標(biāo)記可達(dá)方格位置
  do {
for (i = 0; i< NumOfNbrs; i++) { //標(biāo)記可達(dá)相鄰方格
nbr.row = here.row + offset[i].row ;
nbr.col = here.col + offset[i].col;
if (grid[nbr.row][nbr.col] = = 0) { //該方格未標(biāo)記
  grid[nbr.row][nbr.col] = grid[here.row][here.col] + 1;
if ((nbr.row = = finish.row) && (nbr.col = = finish.col))  break;//完成布線
Q.Add(nbr); 
       }
}
if ((nbr.row = = finishi.row) && (nbr.col = = finish.col))  break;//完成布線
if (Q.IsEmpty()) //活隊(duì)列是否為空
return 0; //無(wú)解
      Q.delete(here); //取下一個(gè)擴(kuò)展結(jié)點(diǎn)
}while (1);
//構(gòu)造最短布線路徑
PathLen = grid[finish.row][finish.col] - 2;
path = new Position[PathLen];
here = finish;
for (int j = PathLen – 1; j >= 0; j--) { //找前驅(qū)位置
  path[j] = here;
  for (i = 0; i< NumOfNbrs; i++) {
nbr.row = here.row + offset[i].row ;
nbr.col = here.col + offset[i].col;
if (grid[nbr.row][nbr.col] = = j+2)  break;
}
  here = nbr; //向前移動(dòng)
  }
return 1;
}
void main ()
{
  int grid[8][8];
  int PathLen, *path;
  Position start, finish;
  start.row = 3;  start.col = 2;
  finish.row = 4; finish.col = 6;


  FindPath (start, finish, PathLen, path);
 }

代碼貼出來(lái):

復(fù)制代碼 代碼如下:

#include <stdio.h>
typedef struct {
  int row;
  int col;
}Position;
int FindPath (Position start, Position finish, int &PathLen, Position *&path)
{ //計(jì)算從起始位置start到目標(biāo)位置finish的最短布線路徑,找到返回1,否則,返回0
  int  i;
  if ((start.row = = finish.row) && (start.col = = finish.col)) {
PathLen = 0;   return 0; } //start = finish
  //設(shè)置方格陣列”圍墻”
  for (i = 0; i <= m+1; i++)
grid[0][i] = grid[n+1][i] = 1; //頂部和底部
  for (i = 0; i <= n+1; i++)
grid[i][0] = grid[i][m+1] = 1; //左翼和右翼
  //初始化相對(duì)位移
int  NumOfNbrs = 4; //相鄰方格數(shù)
  Position offset[4], here, nbr;
  offset[0].row = 0;   offset[0].col = 1;   //右
  offset[0].row = 1;   offset[0].col = 0;   //下
  offset[0].row = 0;   offset[0].col = -1;  //左
  offset[0].row = -1;  offset[0].row = 0;  //上
  here.row = start.row;
  here.col = start.col;
  LinkedQueue <Position> Q; //標(biāo)記可達(dá)方格位置
  do {
for (i = 0; i< NumOfNbrs; i++) { //標(biāo)記可達(dá)相鄰方格
nbr.row = here.row + offset[i].row ;
nbr.col = here.col + offset[i].col;
if (grid[nbr.row][nbr.col] = = 0) { //該方格未標(biāo)記
  grid[nbr.row][nbr.col] = grid[here.row][here.col] + 1;
if ((nbr.row = = finish.row) && (nbr.col = = finish.col))  break;//完成布線
Q.Add(nbr); 
       }
}
if ((nbr.row = = finishi.row) && (nbr.col = = finish.col))  break;//完成布線
if (Q.IsEmpty()) //活隊(duì)列是否為空
return 0; //無(wú)解
      Q.delete(here); //取下一個(gè)擴(kuò)展結(jié)點(diǎn)
}while (1);
//構(gòu)造最短布線路徑
PathLen = grid[finish.row][finish.col] - 2;
path = new Position[PathLen];
here = finish;
for (int j = PathLen – 1; j >= 0; j--) { //找前驅(qū)位置
  path[j] = here;
  for (i = 0; i< NumOfNbrs; i++) {
nbr.row = here.row + offset[i].row ;
nbr.col = here.col + offset[i].col;
if (grid[nbr.row][nbr.col] = = j+2)  break;
}
  here = nbr; //向前移動(dòng)
  }
return 1;
}
void main ()
{
  int grid[8][8];
  int PathLen, *path;
  Position start, finish;
  start.row = 3;  start.col = 2;
  finish.row = 4; finish.col = 6;


  FindPath (start, finish, PathLen, path);
 }


好了,問(wèn)題解出來(lái)了。咦,我們用的是什么方法呢?呵呵,對(duì),這就是分支限界算法。


算法總結(jié):

分支限界法基本思想:

• 分支限界法常以廣度優(yōu)先或以最小耗費(fèi)(最大效益)優(yōu)先的方式搜索問(wèn)題的解空間樹(shù)。

• 在分支限界法中,每一個(gè)活結(jié)點(diǎn)只有一次機(jī)會(huì)成為擴(kuò)展結(jié)點(diǎn)?;罱Y(jié)點(diǎn)一旦成為擴(kuò)展結(jié)點(diǎn),就一次性產(chǎn)生其所有兒子結(jié)點(diǎn)。

• 在這些兒子結(jié)點(diǎn)中,導(dǎo)致不可行解或?qū)е路亲顑?yōu)解的兒子結(jié)點(diǎn)被舍棄,其余兒子結(jié)點(diǎn)被加入活結(jié)點(diǎn)表中。

• 此后,從活結(jié)點(diǎn)表中取下一結(jié)點(diǎn)成為當(dāng)前擴(kuò)展結(jié)點(diǎn),并重復(fù)上述結(jié)點(diǎn)擴(kuò)展過(guò)程。這個(gè)過(guò)程一直持續(xù)到找到所需的解或活結(jié)點(diǎn)表為空時(shí)為止。

分支限界法與回溯法的不同:

(1)求解目標(biāo)不同:回溯法的求解目標(biāo)是找出解空間樹(shù)中滿足約束條件的所有解,而分支限界法的求解目標(biāo)則是找出滿足約束條件的一個(gè)解,或是在滿足約束條件的解中找出在某種意義下的最優(yōu)解。

(2)搜索方式的不同:回溯法以深度優(yōu)先的方式搜索解空間樹(shù),而分支限界法則以廣度優(yōu)先或以最小耗費(fèi)優(yōu)先的方式搜索解空間樹(shù)。

相關(guān)文章

  • C++ 中回文數(shù)判斷簡(jiǎn)單實(shí)例

    C++ 中回文數(shù)判斷簡(jiǎn)單實(shí)例

    這篇文章主要介紹了C++ 中回文數(shù)判斷簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • C++實(shí)現(xiàn)萬(wàn)年歷源代碼

    C++實(shí)現(xiàn)萬(wàn)年歷源代碼

    這篇文章主要介紹了C++實(shí)現(xiàn)萬(wàn)年歷源代碼,可以直接在VC6.0編譯運(yùn)行,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • Qt QChart實(shí)現(xiàn)折線圖的繪制

    Qt QChart實(shí)現(xiàn)折線圖的繪制

    QChart是常用的圖表,這篇文章主要為大家詳細(xì)介紹了Qt如何利用QChart實(shí)現(xiàn)折線圖的繪制,文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2023-04-04
  • C++中四種加密算法之AES源代碼

    C++中四種加密算法之AES源代碼

    本篇文章主要介紹了C++中四種加密算法之AES源代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。
    2016-11-11
  • C語(yǔ)言詳解用char實(shí)現(xiàn)大小寫(xiě)字母的轉(zhuǎn)換

    C語(yǔ)言詳解用char實(shí)現(xiàn)大小寫(xiě)字母的轉(zhuǎn)換

    這篇文章主要給大家介紹了關(guān)于C語(yǔ)言實(shí)現(xiàn)大小寫(xiě)字母轉(zhuǎn)換的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 在C++中高效使用和處理Json格式數(shù)據(jù)的示例代碼

    在C++中高效使用和處理Json格式數(shù)據(jù)的示例代碼

    最近的項(xiàng)目在用c處理后臺(tái)的數(shù)據(jù)時(shí),因?yàn)楹枚嗤獠拷涌诙荚谑褂肑son格式作為返回的數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)描述,如何在c中高效使用和處理Json格式的數(shù)據(jù)就成為了必須要解決的問(wèn)題,需要的朋友可以參考下
    2023-11-11
  • 解析C++多文件編程問(wèn)題

    解析C++多文件編程問(wèn)題

    在某些場(chǎng)景中,考慮到編譯效率和可移植性,#pragma once 和 #ifndef 經(jīng)常被結(jié)合使用來(lái)避免頭文件被 重復(fù)引入,這里介紹用 _Pragma 操作符避免頭文件重復(fù)引入的問(wèn)題,感興趣的朋友跟隨小編一起看看吧
    2021-10-10
  • C語(yǔ)言超詳細(xì)講解函數(shù)指針的運(yùn)用

    C語(yǔ)言超詳細(xì)講解函數(shù)指針的運(yùn)用

    函數(shù)指針是一個(gè)指針變量,它可以存儲(chǔ)函數(shù)的地址,然后使用函數(shù)指針,下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言進(jìn)階教程之函數(shù)指針的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • C++實(shí)現(xiàn)LeetCode(13.羅馬數(shù)字轉(zhuǎn)化成整數(shù))

    C++實(shí)現(xiàn)LeetCode(13.羅馬數(shù)字轉(zhuǎn)化成整數(shù))

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(13.羅馬數(shù)字轉(zhuǎn)化成整數(shù)),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • Qt常用容器類(lèi)的使用

    Qt常用容器類(lèi)的使用

    本文主要介紹了Qt常用容器類(lèi)的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06

最新評(píng)論

靖西县| 临湘市| 虹口区| 大同市| 连山| 鄯善县| 三门县| 新民市| 凤凰县| 浦城县| 溧阳市| 扎鲁特旗| 山西省| 湘乡市| 灌南县| 加查县| 稻城县| 屏南县| 行唐县| 婺源县| 安康市| 怀来县| 南安市| 涪陵区| 鲜城| 高邑县| 昌图县| 霞浦县| 阿鲁科尔沁旗| 中西区| 姜堰市| 浙江省| 南康市| 芜湖县| 池州市| 永仁县| 定南县| 镶黄旗| 寿阳县| 开远市| 泉州市|