From 01dd080a44d9ab580edcd7917245ecb4332490a7 Mon Sep 17 00:00:00 2001 From: yann Date: Tue, 1 Apr 2025 09:59:32 +0200 Subject: [PATCH] bf works, dp worse than sienna s --- bruteforce.py | 82 ++++++++++++++++++++++++++++++++++++++++++++++++ greedy.py | 52 ++++++++++++++++++++++++++++++ importactions.py | 39 +++++++++++++++++++++++ permute.py | 28 +++++++++++++++++ powersetsme.py | 70 +++++++++++++++++++++++++++++++++++++++++ sacadeux.py | 66 ++++++++++++++++++++++++++++++++++++++ sacados.py | 48 ++++++++++++++++++++++++++++ test.py | 11 +++++++ testsacdos.py | 61 +++++++++++++++++++++++++++++++++++ 9 files changed, 457 insertions(+) create mode 100644 bruteforce.py create mode 100644 greedy.py create mode 100644 importactions.py create mode 100644 permute.py create mode 100644 powersetsme.py create mode 100644 sacadeux.py create mode 100644 sacados.py create mode 100644 test.py create mode 100644 testsacdos.py diff --git a/bruteforce.py b/bruteforce.py new file mode 100644 index 0000000..90ea31b --- /dev/null +++ b/bruteforce.py @@ -0,0 +1,82 @@ +import csv + + +def powerset(itemList): + result = [[]] + for item in itemList: + newsubsets = [subset + [item] for subset in result] + result.extend(newsubsets) + return result + +def listFromFile(csv_file): + """ + get data from a csv file and : + converts numbers, remove first title line + returns a list including name, cost: int, roi: float + """ + liste = [] + with open(csv_file) as file: + data = csv.reader(file) + for i in data: + liste.append(i) + liste.pop(0) + for item in liste: + item[1] = int(item[1]) + item[2] = float(item[2].strip("%")) + return liste + +def splitActions(actionList): + """ + split list in two parts, just in case we need to divide the operation for + more efficiency + returns a tuple with two lists + """ + liste1 = [] + liste2 = [] + for i in range(len(actionList)): + if (i < 10): + liste1.append(actionList[i]) + if (i >= 10): + liste2.append(actionList[i]) + return (liste1, liste2) + +def selectActions(actionList, max): + """ + :param actionList: takes a list of combinations and a max + :return: a list of selected combinations where cost is under max + """ + best = [] + best2 = [] + for i in actionList: + cout = 0 + rendement = 0 + for action in i: + cout += action[1] + rendement += action[2] + if cout < int(max): + best.append((rendement, cout, i)) + best2.append(i) + return best, best2 + + + +actions = listFromFile("/home/b/Documents/OCR/projet7/actions.csv") +powerActions = powerset(actions) +selectedActions, selected = selectActions(powerActions, 500) + +print("Longueur de la liste d'actions:", len(actions)) +print("Nb de combinaisons:", len(powerActions)) +print("Nb de combinaisons au cout inferieur à 500:", len(selectedActions)) + +#tri des actions sur le rendement +best_sorted = sorted(selectedActions, key=lambda k: k[0], reverse=True) +best2 = sort(selected, key=lambda k:[]) +#print("\nfive last sorted :") +#for i in range(len(best_sorted)-1, len(best_sorted)-10, -1): +# print("set", i, ":", best_sorted[i]) +#print(f"Rendement: {sum(x[2][1] * x[2][2]/100 for x in best_sorted[0])}") +print(selected[1]) +print("Meilleur rendement:", best_sorted[0][0], "%") +print("Actions sélectionnées:") +for action in best_sorted[0][2]: + print(f"Nom: {action[0]}, Cout: {action[1]}, Rendement: {action[2]}%") \ No newline at end of file diff --git a/greedy.py b/greedy.py new file mode 100644 index 0000000..981aedf --- /dev/null +++ b/greedy.py @@ -0,0 +1,52 @@ +import csv + +class Item: + def __init__(self, weight, value): + self.weight = weight + self.value = value + self.ratio = value / weight + + def fractional_knapsack(capacity, items): + # sort items by value-to-weight ration in descending order + items.sort(key=lambda x: x.ratio, reverse=True) + total_value = 0 + remaining_capacity = capacity + for item in items: + if remaining_capacity >= item.weight: + total_value += item.value + remaining_capacity -= item.weight + else: + total_value += item.ratio * remaining_capacity + break + return total_value + + + +def listFromFile(csv_file): + liste = [] + with open(csv_file) as file: + data = csv.reader(file) + for i in data: + liste.append(i) + liste.pop(0) + for item in liste: + item[1] = float(item[1]) + item[2] = float(item[2]) + return liste + + +def greedy(capacity:int, items:[]): + # sort items by value-to-weight ration in descending order + items.sort(key=lambda x: x.ratio, reverse=True) + selected_items = [] + total_value = 0 + remaining_capacity = capacity + for item in items: + if remaining_capacity >= item.weight: + total_value += item.value + remaining_capacity -= item.weight + selected_items.append(item) + else: + total_value += item.ratio * remaining_capacity + break + return selected_items, total_value \ No newline at end of file diff --git a/importactions.py b/importactions.py new file mode 100644 index 0000000..fa55914 --- /dev/null +++ b/importactions.py @@ -0,0 +1,39 @@ +import csv + +def listFromFile(csv_file): + liste = [] + with open(csv_file) as file: + data = csv.reader(file) + for i in data: + liste.append(i) + liste.pop(0) + for item in liste: + item[1] = int(item[1]) + item[2] = float(item[2].strip("%")) + + return liste + +def listFromFile2(csv_file): + liste = [] + with open(csv_file) as file: + data = csv.reader(file) + for i in data: + liste.append(i) + liste.pop(0) + for item in liste: + item[1] = float(item[1]) + item[2] = float(item[2]) + return liste + +def splitListe(liste): + liste1 = [] + liste2 = [] + + for i in range(len(liste)): + if (i < 10): + print(liste[i]) + liste1.append(liste[i]) + if (i >= 10): + liste2.append(liste[i]) + + diff --git a/permute.py b/permute.py new file mode 100644 index 0000000..2c8bf12 --- /dev/null +++ b/permute.py @@ -0,0 +1,28 @@ +def permute(liste): + if len(liste) == 0: + return [] + + if len(liste) == 1: + return [liste] + + permutations = [] + + for i in range(len(liste)): + current = liste[i] + remaining = liste[:i] + liste[i+1:] + + for p in permute(remaining): + permutations.append([current] + p) + + return permutations + + + +liste = [] + +for i in range(1, 6): + liste.append(i) + + +test = permute(liste) +print(test) diff --git a/powersetsme.py b/powersetsme.py new file mode 100644 index 0000000..2551375 --- /dev/null +++ b/powersetsme.py @@ -0,0 +1,70 @@ +from math import log + +def powerset(xs): + result = [[]] + for x in xs: + newsubsets = [subset + [x] for subset in result] + result.extend(newsubsets) + return result + +def powerset2(orig, newset): + if orig == []: + return [newset] + else: + res = [] + for s in powerset2(orig[1:], newset+[orig[0]]): + res.append(s) + for s in powerset2(orig[1:], newset): + res.append(s) + return res + +def powerset3(orig, newset): + if orig == []: + yield newset + else: + for s in powerset3(orig[1:], newset+[orig[0]]): + yield s + for s in powerset3(orig[1:], newset): + yield s + +def powerset4(lst): + if len(lst) <= 1: + yield lst + yield [] + else: + for x in powerset4(lst[1:]): + yield [lst[0]] + x + yield x + +def powerset5(lst): + if lst == []: + yield [] + else: + for s in powerset5(lst[1:]): + yield s + [lst[0]] + yield s + +def powerset6(lst): + pairs = [(2**i, x) for i, x in enumerate(lst)] + for i in xrange(2**len(pairs)): + yield [x for (mask, x) in pairs if i & mask] + +if __name__ == '__main__': + l = [1,2,3] + +# print(powerset(l)) +# print(powerset2(l, [])) +# print list(powerset3(l, [])) +# print list(powerset4(l)) +# print list(powerset5(l)) +# print list(powerset6(l)) + +# n = 8 +# for i in range(n): +# b = str(bin(i))[2:] +# if n % 2 != 0: +# l = int(1.0+len(n, 2)) +# else: +# l = int(log(n, 2)) +# b = '0'*(l - len(b)) + b +# print b \ No newline at end of file diff --git a/sacadeux.py b/sacadeux.py new file mode 100644 index 0000000..57c9358 --- /dev/null +++ b/sacadeux.py @@ -0,0 +1,66 @@ +import csv + +def listFromFile(csv_file): + liste = [] + with open(csv_file) as file: + data = csv.reader(file) + for i in data: + liste.append(i) + liste.pop(0) + for item in liste: + item[1] = float(item[1]) + item[2] = float(item[2]) + return liste + +def sac_a_dos(actions, cout_maximal): + n = len(actions) + # Créer une table pour stocker les résultats des sous-problèmes + table = [[0 for x in range(cout_maximal + 1)] for x in range(n + 1)] + + # Construire la table de programmation dynamique + for i in range(n + 1): + for w in range(int(cout_maximal) + 1): + print(w - actions[i-1]['cout']) + #print(w-actions[i-1]) + if i == 0 or w == 0: + table[i][w] = 0.0 + elif actions[i-1]['cout'] <= w: + table[i][w] = max(actions[i-1]['rendement'] + table[i-1][int(w-actions[i-1]['cout'])], table[i-1][w]) + else: + table[i][w] = table[i-1][w] + + + for i in range(n + 1): + print(f"\ntable[{i}][60]", table[i][60], i-1) + print(f"actions[{i}-1]['rendement']", actions[i-1]['rendement']) + print(f"table[{i}-1][(60-actions[{i}-1]['cout'])]", table[i-1][(60-actions[i-1]['cout'])]) + print(f"table[{i}-1][60]", table[i-1][60]) + print(f"actions[{i}-1]['rendement'] + table[{i}-1][(60-actions[{i}-1]['cout'])], table[{i}-1][60]", actions[i-1]['rendement'] + table[i-1][(w-actions[i-1]['cout'])], table[i-1][w]) + # Trouver les actions sélectionnées + w = cout_maximal + actions_selectionnees = [] + for i in range(n, 0, -1): + if table[i][int(w)] != table[i-1][int(w)]: + actions_selectionnees.append(actions[i-1]) + w -= actions[i-1]['cout'] + + return table[n][cout_maximal], actions_selectionnees + + +def display_result(): + print(f"Rendement maximal: {rendement_maximal}%") + print("Actions sélectionnees:") + for action in actions_selectionnees: + print( + f"Nom: {action['nom']}, Cout: {action['cout']}, Rendement: {action['rendement']}%") + +#actions = listFromFile("/home/b/Documents/OCR/projet7/actions.csv") +actions = listFromFile("/home/b/Documents/OCR/projet7/ph3/dataset1_Python+P7.csv") +# Conversion de la liste en dictionnaires pour faciliter l'accès +actions = [{'nom': action[0], 'cout': action[1], 'rendement': action[2]} for action in actions] + +#print(actions[22]['cout'], type(actions[22]['cout'])) +cout_maximal = 500 +rendement_maximal, actions_selectionnees = sac_a_dos(actions, cout_maximal) + +# display_result() diff --git a/sacados.py b/sacados.py new file mode 100644 index 0000000..2f32331 --- /dev/null +++ b/sacados.py @@ -0,0 +1,48 @@ +from importactions import listFromFile, listFromFile2 + +def sac_a_dos(actions, cout_maximal): + n = len(actions) + # Créer une table pour stocker les résultats des sous-problèmes + table = [[0 for x in range(cout_maximal + 1)] for x in range(n + 1)] + + # Construire la table de programmation dynamique + for i in range(n + 1): + for w in range(cout_maximal + 1): + #print('\ni', i, 'w', w) + #print(actions[i-1]['cout'], ) + if i == 0 or w == 0: + table[i][w] = 0 + elif actions[i-1]['cout'] <= w: + table[i][w] = max(actions[i-1]['rendement'] + table[i-1][(w-actions[i-1]['cout'])], table[i-1][w]) + else: + table[i][w] = table[i-1][w] + + # Trouver les actions sélectionnées + w = cout_maximal + actions_selectionnees = [] + for i in range(n, 0, -1): + if table[i][w] != table[i-1][w]: + actions_selectionnees.append(actions[i-1]) + w -= actions[i-1]['cout'] + + return table[n][cout_maximal], actions_selectionnees + + +def display_result(): + print(f"Rendement : {sum(x['cout'] * x['rendement']/100 for x in actions_selectionnees)}€") + print(f"Cout: {sum(x['cout'] for x in actions_selectionnees)}€") + print("Actions sélectionnees:") + for action in actions_selectionnees: + print( + f"Nom: {action['nom']}, Cout: {action['cout']}, Rendement: {action['rendement']}%") + +actions = listFromFile("/home/b/Documents/OCR/projet7/actions.csv") +#actions = listFromFile2("/home/b/Documents/OCR/projet7/ph3/dataset1_Python+P7.csv") +# Conversion de la liste en dictionnaires pour faciliter l'accès +actions = [{'nom': action[0], 'cout': action[1], 'rendement': action[2]} for action in actions] + +#print(actions[22]['cout'], type(actions[22]['cout'])) +cout_maximal = 500 +rendement_maximal, actions_selectionnees = sac_a_dos(actions, cout_maximal) + +display_result() diff --git a/test.py b/test.py new file mode 100644 index 0000000..378d568 --- /dev/null +++ b/test.py @@ -0,0 +1,11 @@ +def dig_root(n: int) -> int | None: + s = 0 + if len(str(n)) == 1: + s = n + return s + for i in str(n): + s += int(i) + dig_root(s) + + +print(dig_root(942)) \ No newline at end of file diff --git a/testsacdos.py b/testsacdos.py new file mode 100644 index 0000000..ec0bc46 --- /dev/null +++ b/testsacdos.py @@ -0,0 +1,61 @@ +import csv + +def listFromFile(csv_file): + liste = [] + with open(csv_file) as file: + data = csv.reader(file) + for i in data: + liste.append(i) + liste.pop(0) + for item in liste: + item[1] = float(item[1]) + item[2] = float(item[2]) + return liste + +def sac_a_dos_float(actions, cout_maximal): + n = len(actions) + table = [[0.0 for x in range(int(cout_maximal) + 1)] for x in range(n + 1)] + + # Dynamic programing table + for i in range(n + 1): + for w in range(int(cout_maximal) + 1): + if i == 0 or w == 0: + table[i][w] = 0.0 + elif actions[i-1]['cout'] <= w: + table[i][w] = max(actions[i-1]['rendement'] + table[i-1][int(w-actions[i-1]['cout'])], table[i-1][w]) + else: + table[i][w] = table[i-1][w] + + # Select + w = cout_maximal + actions_selectionnees = [] + for i in range(n, 0, -1): + if table[i][int(w)] != table[i-1][int(w)]: + actions_selectionnees.append(actions[i-1]) + w -= actions[i-1]['cout'] + + return table[n][int(cout_maximal)], actions_selectionnees + +actions = listFromFile("/home/b/Documents/OCR/projet7/ph3/dataset1_Python+P7.csv") +actionstmp = [{'nom': action[0], 'cout': action[1], 'rendement': action[2]} for action in actions if action[1] > 0.0] +actions = sorted(actionstmp, key=lambda x: x['cout']) + +actions2 = listFromFile("/home/b/Documents/OCR/projet7/ph3/dataset2_Python+P7.csv") +actions2tmp = [{'nom': action[0], 'cout': action[1], 'rendement': action[2]} for action in actions2 if action[1] > 0.0] +actions2 = sorted(actions2tmp, key=lambda x: x['cout']) + + +cout_maximal = 500 + +valeur_maximale, actions_selectionnees = sac_a_dos_float(actions, cout_maximal) +valeur_maximale2, actions_selectionnees2 = sac_a_dos_float(actions2, cout_maximal) + +print("\nDATASET 1\n") +print(f"Cout: {sum(x['cout'] for x in actions_selectionnees):.2f}") +print(f"Rendement: {sum((x['cout']*x['rendement']/100)for x in actions_selectionnees):.2f}") +print(f"Actions sélectionnées: {[x['nom'] for x in actions_selectionnees]}") + +print("\nDATASET 2\n") +print(f"Cout: {sum(x['cout'] for x in actions_selectionnees2):.2f}") +print(f"Rendement: {sum((x['cout']*x['rendement']/100)for x in actions_selectionnees2):.2f}") +print(f"Actions sélectionnées: {[x['nom'] for x in actions_selectionnees2]}")