获取未被覆盖的equals方法使用hashCode

问题描述:

我目前正在研究一个多维数据集求解器,它使用宽度优先搜索来寻找2x2x2 rubiks多维数据集求解器的最短解决方案。事情是,在搜索中有重复的位置被击中,我的目标是知道我有多少人,并在稍后“修剪”出来(我知道如何避免重复,但与本文无关) 。这是它应该看起来像 Old version working获取未被覆盖的equals方法使用hashCode

这是从旧版本的代码与hashCode和等效,但我试图让新版本使用它。我认为这是因为在旧版本中,我会重写equals和hashCode,但在新版本中我似乎无法这样做,因为我不再比较对象,而是数组(这是猜测)。由于这个原因,当前版本不会重复复制。它说没有重复,但这是不正确的。

current non working version.

这里是什么的hashCode和equals是像老版本检测重复。

private Cube() { 
    cube = new int[][] { 
     { 0, 0, 0, 0 }, 
     { 1, 1, 1, 1 }, 
     { 2, 2, 2, 2 }, 
     { 3, 3, 3, 3 }, 
     { 4, 4, 4, 4 }, 
     { 5, 5, 5, 5 } 
    }; 

    cube = scanCube(cube); 
    cube = print_cube(cube); 
} 

private Cube(Cube other) { 
    cube = new int[other.cube.length][]; 
    for (int i = 0; i < other.cube.length; i++) { 
     cube[i] = Arrays.copyOf(other.cube[i], other.cube[i].length); 
    } 
} 

public boolean isSolved() { 
    for (int i = 0; i < cube.length; i++) { 
     for (int k = 1; k < cube[i].length; k++) { 
      if (cube[i][0] != cube[i][k]) { 
       return false; 
      } 
     } 
    } 
    return true; 
} 

@Override 
public boolean equals(Object other) { 
    return other instanceof Cube && Arrays.deepEquals(((Cube) other).cube, cube); 
} 


@Override 
public int hashCode() { 
    return Arrays.deepHashCode(cube); 
}` 

这是当前版本。

public static void main(String[] args) { 

    int[][] cube = new int[][] { 
     { 0, 0, 0, 0 }, 
     { 1, 1, 1, 1 }, 
     { 2, 2, 2, 2 }, 
     { 3, 3, 3, 3 }, 
     { 4, 4, 4, 4 }, 
     { 5, 5, 5, 5 } 
    }; 
    cube = scanCube(cube); 
    cube = print_cube(cube); 
    solve(cube); 
}  
private static boolean isSolved(int [][] cube) { 
    for (int i = 0; i < cube.length; i++) { 
     for (int k = 1; k < cube[i].length; k++) { 
      if (cube[i][0] != cube[i][k]) { 
       return false; 
      } 
     } 
    } 
    return true; 
} 

public static int[][] copyCube(int [][] cube){ 
    int [][] copy = new int [6][4]; 

    for(int i = 0; i < 6; i++){ 
     copy[i] = cube[i].clone(); 
    } 
    return copy; 
} 

public static boolean equals(int[][] other, int[][] cube) { 
    return Arrays.deepEquals(other, cube); 
} 

public int hashCode(int [][] cube) { 
    return Arrays.deepHashCode(cube); 
} 

在搜索方法是确定重复的地方。这是旧的代码。

static public void solve(Cube c) { 
    Set<Cube> cubesFound = new HashSet<Cube>(); 
    cubesFound.add(c); 

    Stack<Cube> s = new Stack<Cube>(); 
    s.push(c); 

    Set<Stack<Cube>> initialPaths = new HashSet<Stack<Cube>>(); 
    initialPaths.add(s); 

    solve(initialPaths, cubesFound); 
} 

static public void solve(Set<Stack<Cube>> livePaths, Set<Cube> cubesFoundSoFar) { 
    System.out.println("livePaths size:" + livePaths.size()); 
    int numDupes = 0; 

    Set<Stack<Cube>> newLivePaths = new HashSet<Stack<Cube>>(); 

    for (Stack<Cube> currentPath : livePaths) { 

     Set<Cube> nextStates = currentPath.peek().getNextStates(); 

     for (Cube next : nextStates) { 
      if (currentPath.size() > 1 && next.isSolved()) { 
       currentPath.push(next); 
       System.out.println("Path length:" + currentPath.size()); 
       System.out.println("Path:" + currentPath); 
       System.exit(0); 

      } else if (!cubesFoundSoFar.contains(next)) { 
       Stack<Cube> newCurrentPath = new Stack<Cube>(); 
       newCurrentPath.addAll(currentPath); 
       newCurrentPath.push(next); 
       newLivePaths.add(newCurrentPath); 
       cubesFoundSoFar.add(next); 
      } else { 
       numDupes += 1; 
      } 
     } 
    } 

    System.out.println("Duplicates found " + numDupes + "."); 
    solve(newLivePaths, cubesFoundSoFar); 
} 

而新的。

static private void solve(int[][] cube) { 

    int[][][] s = new int[12][6][4]; 
    s[0] = cube; 

    Set<int[][][]> initialPaths = new HashSet<int[][][]>(); 
    initialPaths.add(s); 
    Set<int[][]> cubesFound = new HashSet<int[][]>(); 
    cubesFound.add(cube); 

    solve(initialPaths, cubesFound, 1); 
} 

static private void solve(Set<int[][][]> livePaths,Set<int[][]> cubesFoundSoFar, int iterationCount) { 
    System.out.println("livePaths size:" + livePaths.size()); 

    Set<int[][][]> newLivePaths = new HashSet<int[][][]>(); 
    int counter = 0; 
    int recordDepth = 0; 
    int duplicates = 0; 

    for(int[][][] currentPath : livePaths) { 

     Set<int [][]> nextStates = getNextStates(currentPath[iterationCount-1]); 

     for (int[][] next : nextStates) { 
      if (isSolved(next)) { 
       currentPath[iterationCount] = next; 
       int maxSteps = -1; 
       System.out.println("Path:"); 
       for(int i = 0; i < currentPath.length; i++) { 
        if(currentPath[i] != null) { 
         maxSteps = i; 
         System.out.println(toString(currentPath[i])); 
        }else { 
         break; 
        } 
       } 
       System.out.println("Path length:" + maxSteps); 
       System.exit(0); 

      } else if(!cubesFoundSoFar.contains(next)){ 
       int[][][] newCurrentPath = new int[12][6][4]; 
       newCurrentPath = currentPath.clone(); 
       newCurrentPath[iterationCount] = next; 
       newLivePaths.add(newCurrentPath); 
       counter ++; 
       cubesFoundSoFar.add(next); 
      } else { 
       duplicates += 1; 
      } 
     } 
    } 
    //System.out.println(" Set.size(): "+newLivePaths.size()); 

    String storeStates = "positions.txt"; 
    try { 
     PrintWriter outputStream = new PrintWriter(storeStates); 
     outputStream.println(storeStates); 
     for(int[][][] s:newLivePaths) { 
      outputStream.println(toString(s[iterationCount])); 
     } 
     outputStream.close(); 

    } catch (FileNotFoundException e) { 
     System.err.println("Fatal: could not open cache file for cube positions. exiting."); 
     e.printStackTrace(); 
     System.exit(1); 
    } 
    System.out.println("Duplicates found "+ duplicates + "."); 
    solve(newLivePaths, cubesFoundSoFar, iterationCount+1); 
} 
+0

所以,如果我知道,你问为什么你重复检测方法是行不通的,对吗?那个方法在哪里?如果您不发布,我们可以提供什么帮助? –

+0

是的,它不是在新版本中工作,我会将代码发布到旧版和新版的代码中。 @JBNizet – cuber

+0

@JBNizet更新了它 – cuber

您还没有覆盖在你的第二个代码equals(Object)方法,但 Set.contains(Object)使用equals比较的元素。由于立方体中没有,因此使用Object之一。这不会比较内容,它只是测试对象是否是相同的实例(相同的内存位置)。

这里contains相关部分:

...更正式地说,返回true当且仅当该组包含的元素e(O == NULLé== NULL:Ø .equals(e))。 ...

你可能喜欢的东西添加到第二代码:

@Override 
public boolean equals(Object other) { 
    if (other instanceof Cube) 
     return equals(cube, ((Cube) other).cube); 
    else 
     return false; 
} 


@Override 
public int hashCode() { 
    return hashCode(cube); 
} 
+0

我明白你的意思,所以我将不得不恢复到在第二个代码中使用包装类,然后编辑部分我的搜索方法来处理对象而不是int [] [] [ ],就像我之前做的一样。对? – cuber

+0

也许你可以将状态表示为一个整数或长整数......但这会很棘手,很难理解/维护。 –

+0

另外我不认为我能够返回'hashCode(cube)',因为它要么必须在方法中有一个参数,因此不可能覆盖或删除'cube'参数,这会给我因递归而出现溢出错误。我认为这会发生在equals方法中,因为我将不得不删除'return equals'额外的参数。 – cuber