トップページに戻る
次のJavaアルゴリズムパズルへ
前のJavaアルゴリズムパズルへ
PL/SQL版
2-4 (行儀の良い)ナイト巡回問題
Javaアルゴリズムパズル
バックトラック法
ナイト巡回問題は、与えられたマスを、ナイトが連続して飛び続けることで、
全てのマスを1回ずつ訪れる経路を求める問題である。
行儀の良いナイト巡回問題では、最後に元に戻れるように巡回する。
つまり、最後のマスから、最初のマスへは「ナイト飛び」で移動できるものを指す。
行儀の良いナイト巡回問題を解いてみます。
ソース
//行儀の良いナイト巡回問題
public final class goodKnight {
final static int masu = 5;
class InfoDef {
int X;
int Y;
InfoDef(int X,int Y){
this.X = X;
this.Y = Y;
}
int LV;
String Path; //sys_connect_by_path用
};
//スタック
class StackClass {
int stackP;
InfoDef stackValue[];
StackClass(){
stackP = 0;
stackValue = new InfoDef[99999];
}
private void push(InfoDef pInfoDef){
stackValue[stackP++] = pInfoDef;
}
private InfoDef pop(){
return stackValue[--stackP];
}
boolean isEmpty(){
return stackP == 0;
}
}
public static void main(String[] args) {
goodKnight mi = new goodKnight();
mi.main();
}
void main() {
StackClass st = new StackClass();
InfoDef StaInfo = new InfoDef(1,1);
StaInfo.LV = 1;
StaInfo.Path = "(1,1)";
st.push(StaInfo);
int LoopChk = 0;
while (st.isEmpty() == false){
InfoDef priInfo = st.pop();
for (int X=1;X<=masu;X++)
for (int Y=1;Y<=masu;Y++){
String Work = "(" + Integer.toString(X) + "," + Integer.toString(Y) + ")";
if ((((priInfo.X+2 == X) && (priInfo.Y+1 == Y))
|| ((priInfo.X+2 == X) && (priInfo.Y-1 == Y))
|| ((priInfo.X+1 == X) && (priInfo.Y+2 == Y))
|| ((priInfo.X+1 == X) && (priInfo.Y-2 == Y))
|| ((priInfo.X-2 == X) && (priInfo.Y+1 == Y))
|| ((priInfo.X-2 == X) && (priInfo.Y-1 == Y))
|| ((priInfo.X-1 == X) && (priInfo.Y+2 == Y))
|| ((priInfo.X-1 == X) && (priInfo.Y-2 == Y)))
&& priInfo.LV < masu*masu){
//未到着ノードならpush
if (priInfo.Path.indexOf(Work) == -1){
InfoDef willPush = new InfoDef(X,Y);
willPush.Path = priInfo.Path + "-" + Work;
willPush.LV = priInfo.LV+1;
st.push(willPush);
}
}
}
//合格経路なら表示
if (priInfo.LV == masu*masu){
boolean isOK = true;
for (int LX=1;LX<=masu;LX++)
for (int LY=1;LY<=masu;LY++){
String wk = "(" + Integer.toString(LX) + "," + Integer.toString(LY) + ")";
if (priInfo.Path.indexOf(wk) == -1) isOK = false;
}
if ((priInfo.X == 3 && priInfo.Y == 2)
|| (priInfo.X == 2 && priInfo.Y == 3));
else isOK = false;
if (isOK) System.out.println(priInfo.Path);
}
if (++LoopChk == 99999999){
System.out.println("There is a Loop."); break;
}
}
}
}
実行結果
条件を満たす経路は存在しませんでした。