private void generateFifteenPuzzleDB(final byte dummyTile, final long boardConfig) {
		final boolean[] tilesInSubset = computeSubset(dummyTile, boardConfig);
		final int[] tilePositions = new int[tilesInSubset.length];
		int numTilesInSubset = 0;
		for (int i = 0; i < tilePositions.length; ++i) {
			if (tilesInSubset[i]) {
				tilePositions[i] = numTilesInSubset++;
			}
		}
		breadthFirstSearch(boardConfig, tilesInSubset);
		final int tableLength = (int) Math.pow(2, numTilesInSubset * 4);
		this.costTable_15_puzzle = new byte[tableLength];
		this.configTable_15_puzzle = new long[tableLength];
		for (int i = tableLength - 1; i >= 0; --i) {
			this.costTable_15_puzzle[i] = KEY_NOT_FOUND;
		}
		System.err.println("Total states visited: " + this.tempMap.size());
		System.err.print("Removing duplicates...");
		final Set<Entry> entries = this.tempMap.entrySet();
		final Iterator<Entry> it = entries.iterator();
		while (it.hasNext()) {
			final Entry entry = it.next();
			final long config = entry.getKey();
			final byte movesRequired = entry.getValue();
			final int index = indexFor(config, true, tilesInSubset, tilePositions);
			final byte moves = this.costTable_15_puzzle[index];
			if (moves == KEY_NOT_FOUND || movesRequired < moves) {
				this.configTable_15_puzzle[index] = config;
				this.costTable_15_puzzle[index] = movesRequired;
			}
		}
		int numElements = 0;
		for (int i = tableLength - 1; i >= 0; --i) {
			if (this.costTable_15_puzzle[i] != KEY_NOT_FOUND) {
				++numElements;
			}
		}
		System.err.println("done");
		System.err.println("States in subset: " + numElements);
	}