çµè·¯æ¢çŽ¢ã¢ã«ãŽãªãºã ã¯ãã²ãŒã éçºã«äžå¯æ¬ ãªéšåã§ãã ããŸããŸãªããã²ãŒã·ã§ã³ã·ã¹ãã ããªãªãšã³ããŒã·ã§ã³ãªã©ããããŸãã ãã ããã²ãŒã æ¥çãšããã«äœ¿çšãããã¢ã«ãŽãªãºã ã«çŠç¹ãåœãŠãŸãã
åã²ãŒã éçºè
ã¯ããã¹ãŠã®å£ãåéããã«ããã£ã©ã¯ã¿ãŒïŒãŸãã¯ãããïŒããããã€ã³ãããå¥ã®ãã€ã³ãã«ç§»åãããå¿
èŠãããã¿ã¹ã¯ã«çŽé¢ããŠããŸãã ãŸããæŠç¥éçºè
ã¯ãã»ã«ïŒéè·¯ã沌å°ã森æãªã©ïŒã®ééæ§ãèæ
®ããå¿
èŠããããŸãã ããã¯ããã¹æ€çŽ¢ã¢ã«ãŽãªãºã ãå©ãã«ãªãå Žæã§ãã
ãªãã§ïŒ
äžèšãããé
ããæ©ãããã²ãŒã éçºè
ã¯å¯ŸåŠããæ¹æ³ãèŠã€ããåŸã§ãããèªåã®ãããžã§ã¯ãã«åãããŠä¿®æ£ããã³æé©åããå¿
èŠããããšçµè«ä»ããããšãã§ããŸãã ãŸããéåžžã«å€ãã®æ°äººãGameDevã«çŽæ¥ã¢ã¯ã»ã¹ãããããè€æ°ã®èšäºãèªãã§1ã€ãŸãã¯å¥ã®ã¢ã«ãŽãªãºã ãç解ããããšã¯å¿
ããã容æã§ã¯ãããŸããã ãã®æçš¿ã§ã¯ãæ€çŽ¢ã¢ã«ãŽãªãºã ã®ä»çµã¿ãç解ããããã»ã¹ãä¿é²ããã®ã«åœ¹ç«ã€ãœãããŠã§ã¢ãäœæããè©Šã¿ã«ã€ããŠèª¬æããŸãã
åºæ¬çãªã¢ã«ãŽãªãºã ã«ã€ããŠäžèš
3ã€ã®äž»èŠãªã¢ã«ãŽãªãºã ãæ€èšããŸãã ã¡ã€ã³ã¢ã«ãŽãªãºã ã®ããããã«ã€ããŠç°¡åã«èª¬æããããã°ã©ã ã§ã®äœæ¥ã®èŠèŠåã®ã¹ã¯ãªãŒã³ã·ã§ãããïŒã€ãã³ãã®å°ãåã«ïŒçŽ¹ä»ããŸãã
ãã€ã¯ã¹ãã©ã®ã¢ã«ãŽãªãºã
1959幎ã«ãªã©ã³ãã®ç§åŠè
Edsger Dijkstroyã«ãã£ãŠèšèšãããŸããã ã¢ã«ãŽãªãºã ã¯ãå
ã®é ç¹ãžã®æçãã¹ãèŠã€ãããŸã§ãã°ã©ãã®åé ç¹ããã§ãã¯ããŸãã 詳现ã«ã€ããŠã¯ãããšãã°
ãã¡ããã芧ãã ãã ã
A *ïŒæå°ïŒ
ãã®ã¢ã«ãŽãªãºã ã¯ã1968幎ã«Peter HartãNiels Nielsonãããã³Bertram Raphaelã«ãã£ãŠåããŠèª¬æãããŸããã åã
ã®é ç¹ãèæ
®ãããšããã®é£æ¥ããé ç¹ãžã®é·ç§»ãè¡ãããç®çã®é ç¹ãŸã§ã®æšå®ãã¹ãæçã«ãªããŸãã
ããããç 究ãå§ããããšãã§ã
ãŸã ã
ãžã£ã³ããã€ã³ãæ€çŽ¢
ãã®ã¢ã«ãŽãªãºã ã¯ã2011幎ã«D. HarborãšA. Grastienã«ãã£ãŠå°å
¥ãããŸããã JPSã¯ãã¹ã®æ€çŽ¢ãé«éåãã衚瀺ãã¹ãå€ãã®å Žæãããžã£ã³ããããŸãã ããžã£ã³ããã€ã³ããã䜿çšãããšããå¿
èŠãªãããŒãã®ã¿ãèæ
®ããŠããã¹æ€çŽ¢ã¢ã«ãŽãªãºã ãé«éåã§ããŸãã
ããã§ã®åäœåç
ã¯éåžžã«ãã説æãããŠããŸãã
å°ããªäºçŽ
ããã°ã©ã ã«è¡šç€ºãããŠãã
Growing Treeãžã§ãã¬ãŒã¿ãŒã¯ãäžã®å³ã®ããã«ãå€å
žçãªè¿·è·¯ããäœæããŸãïŒæ¡å€§ã®ã¿ïŒãèšå®ã®é«ããšå¹
ã¯ãããã«åãããŠããã«èšå®ãããŸãã ãã®ãžã§ãã¬ãŒã¿ãŒã¯ãåå¿è
åãã®ããããå¹æããäœæããæãåºæ¬çãªã¢ã«ãŽãªãºã ïŒå³ãŸãã¯å·Šæã®ã«ãŒã«ãDFSïŒã«ãã£ãŠæ§ç¯ããããã¹ãå®èšŒããããã«è¿œå ãããŸããã
æ€çŽ¢åºæº-åžæŸæš¡æ§ã®ãã£ãŒã«ã
æ€çŽ¢ã¯ã°ã©ãã§æ©èœããŸããå°å³ããã°ã©ããäœæããæãç°¡åãªæ¹æ³ã¯ãå°å³ãåžæŸæš¡æ§ã®ãã£ãŒã«ã
ã«å€æãã
ãŠã§ã€ãã€ã³ããèšå®ããããšã§ãã ç®æšã¯åºæ¬ã®ç解ã容æã«ããããšãªã®ã§ãæ£æ¹åœ¢ã®ã»ã«ã䜿çšããŸãã
ãŸããã»ã«ã®ã¯ã©ã¹ã決å®ããå¿
èŠããããŸãã ãŠãŒã¶ãŒã¯ãå
¥ãå£ãåºå£ãèšå®ããééã§ããªãé害ç©ããã£ãŒã«ãã«é
眮ã§ããå¿
èŠããããŸãããŸããã¢ã«ãŽãªãºã ã®å®è¡äžã«ã»ã«ããã®èŠªãããã³ã¹ããŒã¿ã¹ã®ç¹æ§ã調ã¹ãããšã圹ç«ã¡ãŸãã ãã®çµæãæ瀺ãããã¯ã©ã¹ãååŸããŸãïŒã¹ããŒã¹ãç¯çŽããããã«set-ãget-functionsãåé€ããŸããïŒïŒ
enum Status{ Click, Unclick, Enter, Exit, NoStatus }; enum ListStatus {NoList, InClosed, InOpen}; class GraphicsCell : public QGraphicsRectItem { public: GraphicsCell(int, int, int, bool *, bool *, bool *, QGraphicsItem *parent = 0); void pressButton(int buttonID); void showInfo(QPoint pos); void updateStatus(int upd); void deleteInfo(); private: int x; int y; int f; int g; int h; int weight = INT_MAX; Status status; ListStatus listStatus; bool *isEnter; bool *isExit; bool visited; GraphicsCell *par; QGraphicsRectItem *infoBox; };
pressButtonããã³updateStatusé¢æ°ã¯ãã»ã«ã®ã¹ããŒã¿ã¹ãšè²ã®å€æŽãåŠçããŸãã ã€ã³ãã©ããã¯ã¹ã®showInfoããã³deleteInfoãããã«ã€ããŠã¯åŸè¿°ããŸãã å€æ°xãšyã¯åº§æšãæ
åœããŸãã fãgãhãæ€çŽ¢ã¢ã«ãŽãªãºã ã®åäœã«å¿
èŠãªç¹æ§ã®éã¿ãã¹ããŒã¿ã¹ããã³ã¹ããŒã¿ã¹
ã»ã«ã¹ããŒã¿ã¹ããããäžã«å
¥åãšåºåããããã©ããã®isEnterããã³isExitã芪ã»ã«ã®ããŒïŒæ§ç¯ããããã¹ã埩å
ããããã«å¿
èŠïŒã
ãã£ãŒã«ãã¯ãŒã¯
åžæŸæš¡æ§ã®ãã£ãŒã«ããäœæããŸãããä»åºŠã¯ããŠãŒã¶ãŒã«åºãå
¥ããè¡ããå£ãèšå®ããåè¿°ã®æ
å ±ããã¯ã¹ãåŒã³åºãæ©äŒãäžãããšããã§ãããã
幞ããªããšã«ãã€ã³ã¿ãŒãã§ã€ã¹ãäœæããQtãã¬ãŒã ã¯ãŒã¯ã®QGraphicsViewã¯ã©ã¹ã¯ãã¯ãªãã¯ãããã«ã¯ãªãã¯ãã«ãŒãœã«ç§»åã®ä»®æ³æ©èœïŒãããããmousePressEventãdoubleClickEventãmouseMoveEventïŒãæäŸããŸãã ç§ãã¡ã¯çŽ°èãå«ãæ宀ã®ã·ãŒã³ã§ãããããªãŒããŒããŒãããŸãã
checkPosé¢æ°ã¯ãã«ãŒãœã«ãã»ã«ãªããžã§ã¯ãäžã«ããããšã確èªããŸãã
void MazeWindow::mousePressEvent(QMouseEvent *event) { checkPos(event); GraphicsCell *currCell = static_cast<GraphicsCell *>(scene()->itemAt(mapFromGlobal(cursor().pos()), QTransform())); if (currCell == NULL) return; if (startStatus == Status::NoStatus) { if (currCell->status == Status::Click) startStatus = Status::Click; else startStatus = Status::Unclick; } if (event->button() == Qt::RightButton) { currCell->showInfo(mapFromGlobal(cursor().pos())); cellWithInfo = currCell; } else currCell->pressButton(event->button()); }
ã¯ãªãã¯æ©èœã®å®è£
ã ã¯ãªãã¯ããã»ã«ãç¹å®ããã¹ããŒã¿ã¹ã®æŽæ°ãäŸé ŒããŸãã Infoboxã¯RMBã«ã€ã³ã¹ããŒã«ããå¿
èŠããããŸãããQtã§ã¯ããã«ã¯ãªãã¯ã䜿çšãããšãã«éåžžã®ã¯ãªãã¯ã®æ©èœãæåã«åŒã³åºãããããã«ããã»ã«ãã¡ãã€ããŸãïŒã·ã³ã°ã«ã¯ãªãã¯ã§ã»ã«ã®ç¶æ
ãæŽæ°ããããã«ã¯ãªãã¯ãèªèãããšãã«ãããè¿ããŸããïŒã
å
¥åã¯ãCtrl + LMBãã«é
眮ãããåºåã¯ããŠã¹ãã€ãŒã«ãŸãã¯ã¿ãããããã®ãAlt + LMBãã«é
眮ãããŸãã ååã«å¿«é©ã å£ã«ã¯éåžžã®å¡è£
ãæœãããŠããŸãã
void MazeWindow::mouseMoveEvent(QMouseEvent *event) { checkPos(event); GraphicsCell *currCell = static_cast<GraphicsCell *>(scene()->itemAt(mapFromGlobal(cursor().pos()), QTransform())); if (currCell == NULL) return; if (cellWithInfo != NULL && currCell != cellWithInfo) { cellWithInfo->deleteInfo(); cellWithInfo = NULL; } if (currCell->status == Status::Enter || currCell->status == Status::Exit) return; if (event->buttons() & Qt::LeftButton) { if (startStatus == Status::Click && currCell->status == Status::Click) currCell->updateStatus(1); else if (startStatus == Status::Unclick && currCell->status == Status::Unclick) currCell->updateStatus(0); } }
ãŸããéåžžã®ã°ã©ãã£ãã¯ãšãã£ã¿ãŒã§è¡ãããŠããããã«ããŠãŒã¶ãŒãLMBãäžäžã«åãããŠå£ãæãããšãã§ããããã«ãããã£ãã®ã§ãã
ãããè¡ãã«ã¯ãmouseMoveEventïŒïŒé¢æ°ããªãŒããŒããŒãããŸãã ã»ã«ã®äžã«ããããšã確èªããã«ãŒãœã«ã®äžã®ã»ã«ã®ç¶æ
ãæŽæ°ããããã«èŠæ±ããŸãã 空ã®ã»ã«ããæç»ãéå§ããå Žåã¯å£ãæç»ãç¶ããå£ãæ¶å»ããå Žåã¯ãæ¶ããŽã ãã¢ãŒããç¶è¡ããŸãã é¢æ°ã¯ãåŒã³åºãããã»ã«ããã«ãŒãœã«ãåé€ããå Žåãæ
å ±ããã¯ã¹ãåé€ãã圹å²ãæãããŸãã
ã€ã³ãã©ããã¯ã¹ãéåžžã®é·æ¹åœ¢ãšããŠäœæããŸãããã®é·æ¹åœ¢ã¯ãééãFãGãHã®ç¹æ§ïŒäžèšã®ã¢ã«ãŽãªãºã ã«ç²ŸéããŠããå Žåã¯ãããã®è¡šèšæ³ãç¥ã£ãŠããŸãïŒãã»ã«ãšãã®èŠªã®çŸåšã®ç¶æ
ã瀺ããŸãã
ããã ãã§ããç§ãã¡ã¯èŠèŠåã®ããã«çŸå Žã®ä»äºãæäŸããŸãããé£ããä»äºã®ååã¯å®äºã§ãã也æ¯ïŒ
ãã¹ãèŠã€ããäœæ¥ã®é²è¡ç¶æ³ã®èŠèŠå
ããã°ã©ã ã®æãèå³æ·±ãéšåã¯ãéå±ãªïŒãŸãã¯ããã§ãªãïŒèšäºã次ã®ãããªãã®ã«å€ããã¹ããã®ã§ãã
ã¹ããããã€ã¹ãããã¢ãŒãããããŸããããã¯ãã€ã³ãã©ããã¯ã¹ãšçµã¿åãããŠãåã¢ã«ãŽãªãºã ã®åäœã100ïŒ
ç解ããã®ã«åœ¹ç«ã¡ãŸãã
ããã§ããããã©ã®ããã«å®è£
ããããã«ã€ããŠå°ã説æããŸãã äŸãšããŠãAStarã¢ã«ãŽãªãºã ã®æ©èœãèããŠã¿ãŸããããæ®ãã®ã¢ã«ãŽãªãºã ãåæ§ã«å®è£
ãããŸãã ãŸãããã¿ã³ããé¢æ°èªäœãžã®ä¿¡å·éä¿¡ã¯ãã®ãŸãŸã«ããŸãã
bool MazeWindow::ASolve(int mode) { currMode = 0; if (a == NULL) {
1ã€ã®é¢æ°ã«ã¹ããããã€ã¹ãããã¢ãŒããšå®å
šãªãœãªã¥ãŒã·ã§ã³ãå®è£
ãããããã¢ãŒãIDã転éããå¿
èŠããããŸãïŒ0-å®å
šãªãœãªã¥ãŒã·ã§ã³ãš1-次ã®ã¹ãããçšïŒã ããã«ããããå®å
šãªãœãªã¥ãŒã·ã§ã³ãŸãã¯æ®µéçãªæ¹æ³ã®æåã®ã¹ãããã§ããå Žåãåã®ãœãªã¥ãŒã·ã§ã³ã®æ®ããããã£ãŒã«ããã¯ãªã¢ããã»ã«ã®ã¹ããŒã¿ã¹ãæ¶å»ããclearLabyré¢æ°ã䜿çšããŠç¹æ§ãæŽæ°ããŸãã ã¢ã«ãŽãªãºã èªäœã®æ©èœã¯ãæ€çŽ¢ãšã³ããã€ã³ãã«å°éããå Žåãæ€çŽ¢ãç¶è¡ã§ããªãå Žåã¯trueãè¿ããäœæ¥ãç¶è¡ã§ããå Žåã¯falseãè¿ãããã«å®è£
ãããŸãã ãããã£ãŠãwhileæŒç®åã«ããå®å
šãªãœãªã¥ãŒã·ã§ã³ã§ã¯ãtrueãè¿ããããŸã§é¢æ°ãåŒã³åºããupdatePictureSolveé¢æ°ãåŒã³åºããŠã·ãŒã³ã«ãã¹ã©ã€ã³ãæç»ããŸãã ã¹ããããã€ã¹ãããã¢ãŒãã§ã¯ãã¯ãªãã¯ãããã³ã«é¢æ°ãåŒã³åºããŸãããã¹ãèŠã€ãã£ãå Žåã¯ããŠãŒã¶ãŒã誀ã£ãŠæ±ºå®ã®ç¬éãã¯ãªãã¯ããªãããã«ãã¡ãã»ãŒãžãæç»ããŠè¡šç€ºããããã«éä¿¡ããŸãã
æ€çŽ¢ã¢ã«ãŽãªãºã èªäœã¯ãã»ã«ãéãããªã¹ããŸãã¯éãããªã¹ãã«ãªã¹ããããŠãããšãã«ã»ã«ã®ã¹ããŒã¿ã¹ãæŽæ°ããŸãã
å¶åŸ¡ç€
ããã°ã©ã ã«å«ãŸãããã®ïŒ
- 2çš®é¡ã®ãžã§ãã¬ãŒã¿ãŒïŒ æé·ããªãŒãšæåã¢ãŒãïŒäžèšã®åžæŸæš¡æ§ã®ãã£ãŒã«ãïŒ
- 5çš®é¡ã®ã¢ã«ãŽãªãºã ïŒDFââSããã³Growing Treeãžã§ãã¬ãŒã¿ãŒã®æåã«ãŒã«æ€çŽ¢ ãããã³æåã¢ãŒãã®DijkstraãAStarãJPSã
ãŠãŒã¶ãŒãååä»ããªãã·ã§ã³ãç°¡åã«åãæ¿ããããããã«ããå¿
èŠããããŸããã
åªãããã¶ã€ã³ã®çµæãã¯ãŒã¯ã¹ããŒã¹ã«å°ããªã¡ãã¥ãŒããŒã衚瀺ãããããŒã«ããŒããé衚瀺ã«ãããåŒã³åºãããã§ããŸãã ã«ã©ãŒãã£ãŒã«ããã¯ãªãã¯ããŠããã¹ã©ã€ã³ã®è²ãå€æŽããããšãã§ããŸãã
ïŒç§ã®å¥œã¿ãæ°ã«å
¥ããªãå ŽåïŒçµ±èšãæäœãã
ãã®ããã°ã©ã ã䜿çšããŠãç¹å®ã®ç¶æ³ã«æãå¹æçãªã¢ã«ãŽãªãºã ãéžæããããšãã§ããŸãã
- å¿
èŠãªãããã倧ãŸãã«æããšãåçã®ããã«ãªããŸã
- 3ã€ã®ã¢ã«ãŽãªãºã ãã¹ãŠãéå§ããäœæ¥ãç®ã§è©äŸ¡ããŸãã
æããã«ãå€ããå°ãªããæ·±å»ãªãããžã§ã¯ãã§ã¯ãç®ã§èŠããã ãã§ã¯ååã§ã¯ãªããããçµ±èšã衚瀺ããå¿
èŠããããŸãã
ããã¯ãã¯ãŒã¯ã¹ããŒã¹å
ã®çŸåšã®ã¢ã«ãŽãªãºã ã®ç°¡åãªçµ±èšãšã»ãã·ã§ã³ããšã®ãã¹ãŠã®ã¢ã«ãŽãªãºã ã®æäœã衚瀺ããExcelãªã©ã§ã³ããŒã§ããã¬ããŒããäœæããããã§ã°ã©ããäœæã§ããå¥ã®ãŠã£ã³ããŠã䜿çšããŠããŠã£ãžã§ããã®åœ¢åŒã§ãããè¡ããŸãã
ç°¡åãªçµ±èšã䜿çšãããŠã£ãžã§ããã®å®è£
ã¯ãèšå®ã䜿çšãããŠã£ãžã§ããã®å®è£
ãšéåžžã«äŒŒãŠãããã»ãšãã©åãããã«èŠããŸãã
ã¢ã«ãŽãªãºã èªäœãæäœã®æ°ãèšç®ããŸãã ãã¹ã®é·ãã¯åºå£ã»ã«ã®ç¹æ§ããç¥ãããšãã§ããæéãã¿ã€ããŒãšèŠãªããæç»ã«è²»ãããæéãå·®ãåŒããŸãïŒãã ããããã¯ããŸãæ£ç¢ºã§ã¯ãããŸããïŒã ã¢ã«ãŽãªãºã ã®åäœãå®äºãããšããŠã£ãžã§ããã«çµ±èšãæž¡ããé¢æ°ãåŒã³åºããŠããŒãã«ã«ãšã³ããªãäœæããŸãã ãã®çµæã次ã®è¡šããããŸãã
A *ãšDextraã®çµæãåãã§ããçç±ãåå¥ã«èšåãã䟡å€ããããŸãããJPSã¯åªããŠããŸãã ããã¯ã2ã€ã®ç°ãªãæ¹æ³ã䜿çšããŠã»ã«éã®è·é¢ãèšç®ããããã§ããA*ãšãã€ã¯ã¹ãã©ã¯ãåçŽããã³æ°Žå¹³é·ç§»10ãšå¯Ÿè§ç·14ã®ã³ã¹ãã䜿çšããåèšçµæã10ã§é€ç®ããŸãã JPSã¯ãããã1ãšsqrtïŒ2ïŒã䜿çšããäœãåå²ããŸããããåãæšãŠãŸãã JPSã¯ãã¹ã®é·ããããæ£ç¢ºã«è¡šç€ºãããããæ°å€ãç°ãªããŸãã
ããŒã¿ãåŠçããåŸã次ã®ãããªãã®ãååŸã§ããŸãããã®ç¶æ³ã®å ŽåïŒãã®ãããªã¹ã±ãžã¥ãŒã«ïŒ ãããã«
ããã°ã©ããŒã ãã§ãªããåå¿è
ããã¹æ€çŽ¢ã¢ã«ãŽãªãºã ãæ±ãã®ã«åœ¹ç«ã€ããã°ã©ã ãå
¥æããŸããã å°ãªããšãç§ã¯ãŸã æ°äººã®å人ãå©ããŸããïŒ
èè
ã¯ãè©Šéšãæžãããããã«ããªãã®åžæã«è³ãåŸããããããæºè¶³ãããŸãã
ãããããäžé£ã®æ¹åã«ãããã¢ã«ãŽãªãºã ãåãã匷åãªã©ã€ãã©ãªãåŸããããšããäºå®ã«ã€ãªãããããã°ã©ã ã¯ãã®ããã®çŽ æŽããããã¢ã«ãªããŸãïŒ
PathFinding.jsã®ããã« ãããè¯ãã ãã§ãïŒã
ãŠã§ã€ã®æ€çŽ¢ã«é¢ããèšäºãæžãããå Žåã¯ããã®ããã°ã©ã ãæ·»ä»ã§ããŸãã
âå®éšç 究è³æïŒ
PathFinding.jsâãã®ããã°ã©ã ã¯ã
poisonãŸãã¯
DropBoxããã¢ãŒã«ã€ããããŠã³ããŒãã§ã
ãŸã ã
UPDïŒæåã¯èª€ã£ãŠäžå®å
šã«ãããã°ãããããŒãžã§ã³ãå
¬éãããŠããŸããããçŸåšã¯ãã¹ãŠåé¡ãããŸããã è¬ããŸã 2017幎3æ14æ¥ïŒã¯ããçŽ4æ¥éãã¿ã°ä»ãããŒãžã§ã³ããã³ã°ããŸããïŒCïŒ
âãªãªãžãã«ãããžã§ã¯ãVS2013ïŒPoison and
Dropbox