2016-11-24 33 views
6

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; 
} 
+2

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

Odpowiedz

3

Możesz zajrzeć do Chronicle. Jest to zoptymalizowany magazyn o kluczowej wartości i powinien pasować do Twojego celu.

Albo możesz sam zapisać miejsce do przechowywania, ale nadal będziesz robił coś podobnego do mapy i pliku mapowanego pod maską.