野人传教士过河 算法

来源:互联网 发布:中国网速和外国网络 编辑:程序博客网 时间:2024/05/17 02:43

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;

//{ 7, 6, 4 }, { 2, 8, 0 }, { 1, 3, 5 }
//{ 5, 4, 1 }, { 2, 0, 3 }, { 7, 8, 6 }

class strack extends LinkedList {// 堆栈

 public boolean isEmpty() {
  return super.isEmpty();
 }

 public Object pop() {
  if (!this.isEmpty())
   return removeFirst();
  return "null";
 }

 public void push(Object e) {
  super.addFirst(e);
 }

}

public class BSM {
 static ArrayList deepall = new ArrayList();

 static strack s = new strack();

 public static void main(String[] args) {
  int[][] start = new int[][] { { 7, 6, 4 }, { 2, 8, 0 }, { 5,3,1 } };

  int[][] end = new int[][] { { 1, 2, 3 }, { 8, 0, 4 }, { 7, 6, 5 } };
  ArrayList list = new ArrayList();
  ArrayList list1 = new ArrayList();
  strack s1 = new strack();
  int deep = 0;

  list.add(start);
  deepall.add(deep);

  new BSM().work(start, end, list, list1, deepall, deep);

  for (int i = 0;; i++) {

   if (s.isEmpty()) {

    break;
   }

   int[][] hh = (int[][]) s.pop();

  
   if (i == 0)
    s1.push(hh);
   if (i != 0) {
    int[][] haha = (int[][]) s1.getFirst();

    if (new BSM().accfn(haha, hh) == 1)

     s1.push(hh);
   }
  }

  while (!s1.isEmpty()) {
   int[][] haha = (int[][]) s1.pop();
   for (int i = 0; i < 3; i++)
    System.out.println(Arrays.toString(haha[i]));
   System.out.println("-----------------");


  }

 }

 public void work(int[][] start, int[][] end, ArrayList list,
   ArrayList list1, ArrayList deepall, int deep) {
  while (accfn(start, end) != 0 && list != null) {
   start = findbast(list, end, deepall);

   if (accfn(start, end) == 0)
    System.out.println("找到解");
   else {
    deep = getdeep(list, deepall, start);
    list = findall(list, start, end, ++deep, deepall, list1);
   }
   // for (int i = 0; i < 3; i++)
   // System.out.println(Arrays.toString(start[i]));
   // System.out.println("--------------------------");
   s.push(start);
   
   list = removes(list, start, deepall);

  }
 }

 public int accfn(int[][] a, int[][] b) {// 计算W(n)
  int aa[] = new int[9];
  int aaa[] = new int[9];
  int bb[] = new int[9];
  int bbb[] = new int[9];
  int count = 0;
  for (int i = 0; i < 3; i++)
   for (int j = 0; j < 3; j++) {
    aa[a[i][j]] = i;
    bb[b[i][j]] = i;
    aaa[a[i][j]] = j;
    bbb[b[i][j]] = j;

   }

  for (int i = 1; i < 9; i++)
   count += Math.abs(bb[i] - aa[i]) + Math.abs(bbb[i] - aaa[i]);

  return count;
 }

 public int[][] findbast(ArrayList list, int[][] end, ArrayList li) {
  int count = 0;

  Iterator it = list.iterator();
  Iterator i = li.iterator();
  int u = 0;
  int min = 99;
  int[][] bast = new int[3][3];
  while (it.hasNext()) {
   int[][] haha = (int[][]) it.next();
   int h = (Integer) i.next();
   count = (accfn(haha, end)) + h;

   if (min > count) {
    min = count;

    for (int m = 0; m < 3; m++)
     for (int n = 0; n < 3; n++)
      bast[m][n] = haha[m][n];

   }

  }

  return bast;
 }

 public static ArrayList findall(ArrayList list, int[][] s1, int[][] end,
   int deep, ArrayList li, ArrayList list1) {
  int[] f = new BSM().find(s1);// 找到0的位置
  int[][] xian = new int[3][3];

  int[][] bast = new int[3][3];
  for (int i = -1; i < 2; i++, i++) {
   xian = s1;
   if (f[0] + i >= 0 && f[0] + i <= 2) {
    xian = s1;

    int ll = xian[f[0] + i][f[1]];
    xian[f[0] + i][f[1]] = xian[f[0]][f[1]];
    xian[f[0]][f[1]] = ll;
    int[][] kk = new int[3][3];
    for (int m = 0; m < 3; m++)
     for (int n = 0; n < 3; n++)
      kk[m][n] = xian[m][n];
    if (test(list1, kk) == true) {
     list1.add(kk);
     li.add(deep);
     list.add(kk);
    } else {

    }
    ll = xian[f[0] + i][f[1]];
    xian[f[0] + i][f[1]] = xian[f[0]][f[1]];
    xian[f[0]][f[1]] = ll;

   }
   if (f[1] + i >= 0 && f[1] + i <= 2) {
    xian = s1;

    int ll = xian[f[0]][f[1] + i];
    xian[f[0]][f[1] + i] = xian[f[0]][f[1]];
    xian[f[0]][f[1]] = ll;
    int[][] kk = new int[3][3];
    for (int m = 0; m < 3; m++)
     for (int n = 0; n < 3; n++)
      kk[m][n] = xian[m][n];
    if (test(list1, kk) == true) {
     li.add(deep);
     list.add(kk);
     list1.add(kk);
    } else {
    }

    ll = xian[f[0]][f[1] + i];
    xian[f[0]][f[1] + i] = xian[f[0]][f[1]];
    xian[f[0]][f[1]] = ll;
   }

  }

  return list;

 }

 public static boolean test(ArrayList list1, int[][] kk) {
  Iterator it = list1.iterator();
  boolean flag = true;
  int u = 0;
  int min = 99;
  while (it.hasNext()) {

   int[][] haha = (int[][]) it.next();

   if (haha[0][0] == kk[0][0] && haha[0][1] == kk[0][1]
     && haha[0][2] == kk[0][2] && haha[1][0] == kk[1][0]
     && haha[1][2] == kk[1][2] && haha[1][1] == kk[1][1]
     && haha[2][1] == kk[2][1] && haha[2][2] == kk[2][2]) {
    flag = false;
    break;
   }

  }
  return flag;
 }

 public ArrayList removes(ArrayList list, int[][] s1, ArrayList gg) {

  Iterator it = list.iterator();// list 输出

  int i = 0;
  while (it.hasNext()) {
   i += 1;
   int[][] haha = (int[][]) it.next();
   if (haha[0][0] == s1[0][0] && haha[0][1] == s1[0][1]
     && haha[0][2] == s1[0][2] && haha[1][0] == s1[1][0]
     && haha[1][2] == s1[1][2] && haha[1][1] == s1[1][1]
     && haha[2][1] == s1[2][1] && haha[2][2] == s1[2][2]) {
    break;
   }
  }

  list.remove(i - 1);
  gg.remove(i - 1);

  return list;
 }

 public int[] find(int[][] a) {// 找到o的位置
  int[] aa = new int[2];

  for (int i = 0; i < 3; i++)
   for (int j = 0; j < 3; j++) {

    if (a[i][j] == 0) {
     aa[0] = i;
     aa[1] = j;
     break;
    }

   }
  return aa;
 }

 public static int getdeep(ArrayList list, ArrayList deepall, int[][] kk) {

  Iterator it = list.iterator();

  Iterator it1 = deepall.iterator();
  int flag = 1;
  int min = 99;

  while (it.hasNext()) {

   int[][] haha = (int[][]) it.next();

   int k = (Integer) it1.next();

   if (haha[0][0] == kk[0][0] && haha[0][1] == kk[0][1]
     && haha[0][2] == kk[0][2] && haha[1][0] == kk[1][0]
     && haha[1][2] == kk[1][2] && haha[1][1] == kk[1][1]
     && haha[2][1] == kk[2][1] && haha[2][2] == kk[2][2]) {

    flag = k;
    break;
   }

  }
  return flag;

 }

}

0 0