formations/doddling/energie.py

461 lines
13 KiB
Python
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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)