461 lines
13 KiB
Python
461 lines
13 KiB
Python
#!/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)
|