Jestem brutalnie wymuszając jedną grę i muszę przechowywać dane dla wszystkich pozycji i wyników. Dane prawdopodobnie będą miały setki Gb. Rozważałem SQL, ale obawiam się, że wyszukiwania w ciasnej pętli mogą zabić wydajność. Program będzie sprawdzał możliwe pozycje i zwrócił zwycięski ruch, jeśli jest znany, zwróć najdłuższą przegraną sekwencję, jeśli wszystkie ruchy zostaną utracone i sprawdź wynik dla nieznanych ruchów.Jak skutecznie przechowywać dużą mapę Java?
Jaki jest najlepszy sposób przechowywania dużego Map<Long,Long[]> positionIdToBestMoves
? Rozważam serializację SQL lub serializację danych.
Chcę rozwiązać małe warcaby przez brutalne wymuszanie wszystkich wykonalnych ruchów w Javie. Górny limit pozycji wynosi około 100 miliardów. Większość z nich nie jest prawdopodobna (tj. Więcej sztuk niż na początku gry). Około 10 miliardów to rozsądny szacunek. Każda z map jest zapisywana w następujący sposób: i. Wartość dodatnia wskazuje, że pozycja wygrywa, a ruch, który prowadzi do pozycji zapisanej w wartości, powinien zostać wybrany. Wartość ujemna -n
oznacza, że pozycja traci co najwyżej n
ruchów.
Szukaj samo miałoby rekursji tak:
//this is a stub
private Map<Long, Long[]> boardBook =...
//assuming that all winning positions are known
public Long nextMove(Long currentPos, int whiteOrBlack){
Set<Long> validMoves = calculateValidMoves(currentPos, whiteOrBlack);
boolean hasWinner = checkIfValidMoveIsKnownToWin(validMoves, whiteOrBlack);
if(hasWinner){ //there is a winning move - play it
Long winningMove = getWinningMove(validMoves, whiteOrBlack);
boardBook.get(currentPos)[whiteOrBlack] = winningMove ;
return winningMove ;
}
boolean areAllPositionsKnown = checkIfAllPositionsKnown(validMoves, whiteOrBlack);
if(areAllPositionsKnown){ //all moves are losing.. choose longest struggle
Long longestSequenceToDefeat = findPositionToLongestSequenceToDefeat(validMoves, whiteOrBlack);
int numberOfStepsTodefeat = boardBook.get(longestSequenceToDefeat)[whiteOrBlack];
boardBook.get(currentPos)[whiteOrBlack] = longestSequenceToDefeat ;
return longestSequenceToDefeat;
}
Set<Long> movesToCheck = getUntestedMoves(validMoves, whiteOrBlack);
Long longeststruggle;
int maxNumberOfMovesToDefeat =-1;
for(Long moveTocheck : movesToCheck){
Long result = nextMove(moveToCheck, whiteOrBlack);
if(result>0){ //just discovered a winning move
boardBook.get(currentPos)[whiteOrBlack] = winningMove ;
return winningMove ;
}else {
int numOfMovesToDefeat = -1*boardBook.get(moveTocheck)[whiteOrBlack];
if(numOfMovesToDefeat >maxNumberOfMovesToDefeat){
maxNumberOfMovesToDefeat =numOfMovesToDefeat ;
longeststruggle = moveTocheck;
}
}
}
boardBook.get(currentPos)[whiteOrBlack] = -1*maxNumberOfMovesToDefeat;
return longeststruggle;
}
Intrygujące pytanie. Wykracza to poza moje umiejętności odpowiadania, ale to, co opisujesz, bardziej przypomina terytorium dużego rozwiązania danych/NoSQL niż tradycyjne SQL. – Gimby