Doddling around an exercise about energy.

This commit is contained in:
Julien Palard 2021-07-16 07:54:46 +02:00
parent 0fff3e6130
commit ede1227c0b
Signed by: mdk
GPG Key ID: 0EFC1AC1006886F8
1 changed files with 460 additions and 0 deletions

460
doddling/energie.py Normal file
View File

@ -0,0 +1,460 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import itertools
from math import *
from pprint import pprint
class stock:
""" Object permettant de manipuler un etat """
def __init__(self, etat, maximum=20):
self.etat = etat
self.maximum = maximum
def charge(self, charge):
""" incremente l'etat """
self.etat += charge
self.etat = min(self.etat, self.maximum)
def decharge(self, decharge):
""" decrement l'etat """
self.etat -= decharge
self.etat = max(self.etat, 0)
def force_etat(self, etat):
""" definit l'etat a une valeur forcée """
self.etat = etat
return self.etat
class hydrogen(stock):
""" Objet heritant des proprietées de stock """
""" avec notion de rendement """
def __init__(self, etat, rendement):
stock.__init__(self, etat, 140)
self.rendement = rendement
def calcul_charge(self, charge):
""" Retourne decharge en vue du rendement """
return floor(charge / self.rendement)
def calcul_decharge(self, decharge):
""" Retourne decharge en vue du rendement """
return decharge * self.rendement
class energie:
""" Objet pour connaitre la production des sources """
def __init__(self, sources):
self.sources = sources
def production(self, source, heure):
""" Retourne la production d'une """
""" source pour une heure donnée """
return self.sources[source].get(heure, 0)
class implications:
""" Generateur d'implicaitons """
def __init__(self, sources, destinations):
self.sources = sources
self.destinations = destinations
def combinations(self, L):
""" Retourne la combinaison de deux listes """
for i in range(0, len(L) + 1):
for combination in itertools.combinations(L, i):
yield combination
def connections(self):
""" Retourne les connections simultanées """
""" possiblibles vers les destinations """
choosed = []
generated = []
possibles = self.possibles()
while possibles:
choosed, generated, possibles = self.gen_connection(
possibles, choosed, generated
)
return generated
def gen_connection(self, possibles, choosed=[], generated=[]):
choice = possibles.pop(0)
choosed += choice
for possible in possibles:
if not choice[0] in possible[0]:
if len(choice[1]) == 0:
generated += [(choice, possible)]
else:
if not self.is_used(choice[1], possible[1]):
generated += [(choice, possible)]
return choosed, generated, possibles
def connections_list(self):
""" genere une liste de dictionaires de connections possibles """
connections = []
for connection in self.connections():
implications = {}
for destination_tuple in connection:
destination, elements = destination_tuple
if len(elements) != 0:
implications.update({destination: list(elements)})
connections += [implications]
return connections
def possibles(self):
""" Retourne les combinaisons possibles entre sources """
""" et destinations (une source ne peut pas etre sa """
""" propre destination) """
combinations = list(self.combinations(self.sources))
possibles = []
for destination in self.destinations:
for elements in combinations:
if not destination in elements:
possibles += [(destination, elements)]
return possibles
def is_used(self, choice, possible):
used = False
for element in choice:
if element in possible:
used = True
return used
class partie:
def __init__(self, temps, connections_list, batterie, hydrogen, sources):
self.gagne = False
self.temps = temps
self.connections_list = connections_list
self.batterie = batterie
self.hydrogen = hydrogen
self.productions = energie(sources)
self.solutions = {}
def demarre(self):
print("Etat batterie initial: {}".format(self.batterie.etat))
print("Etat hydrogen initial: {}".format(self.hydrogen.etat))
i = 0
for heure in range(1, self.temps + 1):
nouvelles_solutions = {}
for connections in self.connections_list:
if not self.solutions:
etat_suivant = self.etats_suivant(heure, connections)
nouvelles_solutions.update({i: etat_suivant})
i += 1
else:
for sid, solution in self.solutions.items():
for heure_solution, infos_solution in solution.items():
if heure_solution == heure - 1:
etat_suivant = self.etats_suivant(heure, connections)
etat_suivant.update(solution)
nouvelles_solutions.update({i: etat_suivant})
i += 1
choix = self.choix_solution(heure, nouvelles_solutions)
self.solutions.update(choix)
# print('choix:', choix)
print()
def etats_suivant(self, heure, connections):
self.change_etats(heure, connections)
self.pause()
etat = {
heure: {
"etat": {
"batterie": self.batterie.etat,
"hydrogen": self.hydrogen.etat,
"partie_gagnante": self.gagne,
},
"connections": connections,
}
}
self.gagne = False
return etat
def choix_solution(self, heure, new_solutions):
solutions = {}
#  On recupere la valeur max de l'etat de batterie
etats_batterie = []
for sid, s in new_solutions.items():
for h, infos in s.items():
if h == heure:
etats_batterie.append(infos["etat"]["batterie"])
max_batterie = max(etats_batterie)
solutions_max_batterie = {}
for sid, s in new_solutions.items():
for h, infos in s.items():
if infos["etat"]["batterie"] == max_batterie:
solutions_max_batterie.update({sid: s})
print(len(solutions_max_batterie))
#  On recupere la valeur max de l'etat de lh'hydrogen
etats_hydrogen = []
for sid, s in new_solutions.items():
for h, infos in s.items():
if h == heure:
etats_hydrogen.append(infos["etat"]["hydrogen"])
max_hydrogen = max(etats_hydrogen)
solutions_max_hydrogen = {}
for sid, s in new_solutions.items():
for h, infos in s.items():
if infos["etat"]["hydrogen"] == max_hydrogen:
solutions_max_hydrogen.update({sid: s})
print(len(solutions_max_hydrogen))
print("Max batterie:", max_batterie)
print("Max hygrogen:", max_hydrogen)
# on ne garde, que la premiere solution trouvée avec l'etat de bantterie max
choix = {}
for sid, s in new_solutions.items():
for h, infos in s.items():
etat_batterie = infos["etat"]["batterie"]
etat_hydrogen = infos["etat"]["hydrogen"]
if not choix:
if h == heure and etat_batterie == max_batterie:
choix.update({sid: s})
solutions.update(choix)
return solutions
def changements(self, heure, connexions):
charge_batterie = 0
charge_hydrogen = 0
decharge_hydrogen = 0
decharge_batterie = 5
for destination, sources in connexions.items():
for source in sources:
production = self.productions.production(source, heure)
if production:
if destination == "batterie":
charge_batterie += production
if source == "hydrogen":
decharge_hydrogen = self.hydrogen.calcul_decharge(
production
)
elif destination == "hydrogen":
charge_hydrogen += self.hydrogen.calcul_charge(production)
return {
"charge": {"batterie": charge_batterie, "hydrogen": charge_hydrogen},
"decharge": {"batterie": decharge_batterie, "hydrogen": decharge_hydrogen},
}
def change_etats(self, heure, connexions):
changements = self.changements(heure, connexions)
if changements["charge"]["batterie"] != 0:
self.batterie.charge(changements["charge"]["batterie"])
if changements["charge"]["hydrogen"] != 0:
self.hydrogen.charge(changements["charge"]["hydrogen"])
if changements["decharge"]["hydrogen"] != 0:
self.hydrogen.decharge(changements["decharge"]["hydrogen"])
if changements["decharge"]["batterie"] != 0:
self.batterie.decharge(changements["decharge"]["batterie"])
def pause(self):
if self.batterie.etat > 0:
self.gagne = True
if __name__ == "__main__":
sources = {
"eolienne": {
1: 5,
2: 2,
3: 1,
4: 0,
5: 3,
6: 4,
7: 3,
8: 0,
9: 2,
10: 1,
11: 6,
12: 5,
13: 4,
14: 4,
15: 6,
16: 2,
17: 0,
18: 0,
19: 2,
20: 3,
21: 2,
22: 0,
23: 1,
24: 3,
25: 4,
26: 6,
27: 1,
28: 2,
29: 3,
30: 4,
31: 6,
32: 4,
33: 0,
34: 1,
35: 0,
36: 0,
37: 3,
38: 2,
39: 0,
40: 0,
41: 3,
42: 1,
43: 0,
44: 3,
45: 4,
46: 3,
47: 1,
48: 0,
49: 0,
},
"solaire": {
7: 2,
8: 5,
9: 10,
10: 7,
11: 8,
12: 11,
13: 6,
14: 6,
15: 13,
16: 10,
17: 7,
18: 9,
19: 8,
20: 3,
31: 3,
32: 6,
33: 8,
34: 10,
35: 14,
36: 9,
37: 8,
38: 6,
39: 11,
40: 9,
41: 5,
42: 8,
43: 7,
44: 3,
},
"hydrogen": {
1: 4,
2: 4,
2: 4,
4: 4,
5: 4,
6: 4,
7: 4,
8: 4,
9: 4,
10: 4,
11: 4,
12: 4,
13: 4,
14: 4,
15: 4,
16: 4,
17: 4,
18: 4,
19: 4,
20: 4,
21: 4,
22: 4,
23: 4,
24: 4,
25: 4,
26: 4,
27: 4,
28: 4,
29: 4,
30: 4,
31: 4,
32: 4,
33: 4,
34: 4,
35: 4,
36: 4,
37: 4,
38: 4,
39: 4,
40: 4,
41: 4,
42: 4,
43: 4,
44: 4,
45: 4,
46: 4,
47: 4,
48: 4,
},
}
destinations = ["hydrogen", "batterie"]
g = implications(sources=sources, destinations=destinations)
temps = 48
stock_batterie = stock(20)
stock_hydrogen = hydrogen(40, 2)
p = partie(temps, g.connections_list(), stock_batterie, stock_hydrogen, sources)
p.demarre()
for sid, solution in p.solutions.items():
if len(solution) == temps:
pprint(solution)