amélioration du système de sauvegarde de l'ia

This commit is contained in:
2024-08-20 17:28:41 +02:00
parent a8f0e7cdca
commit 4064bde716
9 changed files with 241 additions and 133 deletions

View File

@@ -1,8 +1,16 @@
package personnage.IAQLearning;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import personnage.types.Mouvement;
@@ -20,6 +28,9 @@ public class QTable {
* necessaire pour que le bot puisse faire des actions.
*/
private HashMap<Actions, Double> qValues;
public static int folderStorage = 1000;
private ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
/**
* Constructeur de la classe QTabl cree le HashMap qValues.
@@ -32,9 +43,13 @@ public class QTable {
* Constructeur de la classe QTable cree le HashMap qValues et mets dans la liste
* les informations du fichier dans le path.
*/
public QTable(String pathFile) {
public QTable(String pathFile, String pathname) {
qValues = new HashMap<>();
getValues(pathFile);
try {
get(pathFile, pathname);
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
}
/**
@@ -62,7 +77,15 @@ public class QTable {
* Cette méthode sauvegarde les valeurs Q dans un fichier spécifié.
* @param path le chemin du fichier où sauvegarder les données
*/
public void save(String path) {
public void saveChunk(HashMap<Actions, Double> hashmapSlide, String path) {
try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path))) {
oos.writeObject(hashmapSlide);
} catch (IOException e) {
e.printStackTrace();
}
}
public void saveChunk(String path) {
try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path))) {
oos.writeObject(qValues);
} catch (IOException e) {
@@ -73,22 +96,97 @@ public class QTable {
/**
* Cette méthode charge les valeurs Q depuis un fichier spécifié.
* @param path le chemin du fichier à partir duquel charger les données
* @throws ClassNotFoundException
*/
@SuppressWarnings("unchecked")
public void getValues(String path) {
try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path))) {
public void getChunk(String path) throws IOException, ClassNotFoundException {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path))) {
qValues = (HashMap<Actions, Double>) ois.readObject();
}
}
} catch (IOException | ClassNotFoundException e) {
save(path);
}
@SuppressWarnings("unchecked")
private HashMap<Actions, Double> getChunkSave(String path) throws IOException, ClassNotFoundException {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path))) {
return (HashMap<Actions, Double>)ois.readObject();
}
}
public void save(String pathFolderName, String name) {
File file = new File(pathFolderName);
if (name == null) name = "null";
if (file.isFile()) {
saveChunk(pathFolderName);
} else {
List<Map.Entry<Actions, Double>> entryList = new ArrayList<>(qValues.entrySet());
int indexFile = 0;
for (int i = 0; i < entryList.size(); i += folderStorage) {
int end = Math.min(i + folderStorage, entryList.size());
List<Map.Entry<Actions, Double>> subList = entryList.subList(i, end);
HashMap<Actions, Double> subHashMap = new HashMap<>();
for(Map.Entry<Actions, Double> subValue : subList) {
subHashMap.put(subValue.getKey(), subValue.getValue());
}
String fileName = pathFolderName + File.separator + name + "_part" + (++indexFile) + ".ser";
executor.submit(() -> saveChunk(subHashMap, fileName));
}
executor.shutdown();
try {
executor.awaitTermination(1, TimeUnit.HOURS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void get(String pathFolderName, String name) throws ClassNotFoundException, IOException {
File file = new File(pathFolderName);
if (file.isFile()) {
getChunk(pathFolderName);
} else if (!(file.exists() && file.isDirectory())) {
System.err.println("Erreur : le fichier " + pathFolderName + " n'existe pas.");
System.exit(-1);
} else {
// les hashmaps basique ne supporte pas bien le multithread en java >> https://www.geeksforgeeks.org/concurrenthashmap-in-java/
ConcurrentHashMap<Actions, Double> multithreadHashMap = new ConcurrentHashMap<>();
File[] listFiles = file.listFiles((dir, filename) -> filename.startsWith(name) && filename.endsWith(".ser"));
if (listFiles != null) {
for (File partFile : listFiles) {
executor.submit(() -> {
try {
// Charger chaque fichier dans un HashMap temporaire
HashMap<Actions, Double> tempMap = getChunkSave(partFile.getPath());
// Ajouter chaque entrée au ConcurrentHashMap
multithreadHashMap.putAll(tempMap);
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
});
}
executor.shutdown();
try {
executor.awaitTermination(1, TimeUnit.HOURS);
} catch (InterruptedException e) {
e.printStackTrace();
}
qValues = new HashMap<>(multithreadHashMap);
}
}
}
/**
* cette méthode renvoie dans le terminal tout les elements du
* hashmap.
*/
public void printValues() {
public void printHashMap() {
for (Map.Entry<Actions, Double> value : qValues.entrySet()) {
System.out.println(value.getKey().toString() + " -> " + value.getValue());
}