alfabeta zrobione

This commit is contained in:
neerka 2024-04-04 14:17:13 +02:00
parent 3f2178a0e5
commit 6ab8c4af87
3 changed files with 85 additions and 19 deletions

11
funkcje.py Normal file
View File

@ -0,0 +1,11 @@
def ograniczenie(lista, left_cap):
wynik = 0
for item in lista:
new_cap = left_cap - item.waga
if new_cap <= 0:
temp = item.waga + new_cap
wynik += item.wartosc*(temp/item.waga)
break
else:
wynik += item.wartosc
return wynik

View File

@ -5,6 +5,7 @@ class Item:
def __init__(self):
self._waga = random.randint(1, 6)
self._wartosc = random.randint(5, 10)
self._ratio = self._wartosc/self._waga
@property
def waga(self):
@ -13,3 +14,7 @@ class Item:
@property
def wartosc(self):
return self._wartosc
@property
def ratio(self):
return self._ratio

88
main.py
View File

@ -1,44 +1,94 @@
from plecak import *
from item import *
from funkcje import ograniczenie
l = 10
dostepne = [Item() for _ in range(l)]
liczba_itemow = 20
dost = []
for i in range(liczba_itemow):
item = Item()
ratio = item.ratio
dost.append((ratio, item))
for x in dostepne:
r = [el[0] for el in dost]
r.sort(reverse=True)
dostepne_items = []
for i in r:
for j in dost:
if i == j[0]:
dostepne_items.append(j[1])
break
for x in dostepne_items:
print(x.waga, x.wartosc)
cap = 25
cap = 4 * liczba_itemow / 2 # te liczby tutaj są raczej przypadkowe i można je zmieniać, algorytm dalej powinien działać
alfa = liczba_itemow * 5
def knapsack(dostepne, cap):
def rekurencja(i, waga, val, items, alfa):
nonlocal max_val, plecak
def knapsack(dostepne, cap, mode):
if i >= len(dostepne) or waga == cap:
def rekurencja(i, waga, val, items):
nonlocal max_val, plecak, actions
actions += 1
if i >= len(dostepne):
if val > max_val:
max_val = val
plecak = items
return
if val >= alfa:
plecak = items
if mode in [1, 2] and waga >= cap: # alfa cięcie
return
rekurencja(i+1, waga, val, items, alfa)
if mode in [2] and max_val >= val + ograniczenie(dostepne[i:], cap-waga): # beta cięcie
return
if waga + dostepne[i].waga <= cap:
temp = items[:]
temp.append(dostepne[i])
rekurencja(i+1, waga + dostepne[i].waga, val + dostepne[i].wartosc, temp, alfa)
rekurencja(i+1, waga + dostepne[i].waga, val + dostepne[i].wartosc, temp)
rekurencja(i+1, waga, val, items[:])
max_val = float("-inf")
plecak = []
rekurencja(0, 0, 0, [], 60)
return max_val, plecak
actions = 0
rekurencja(0, 0, 0, [])
return plecak, actions
best, final = knapsack(dostepne, cap)
final0, actions0 = knapsack(dostepne_items, cap, 0)
final1, actions1 = knapsack(dostepne_items, cap, 1)
final2, actions2 = knapsack(dostepne_items, cap, 2)
total_w0 = 0
best_val0 = 0
total_w1 = 0
best_val1 = 0
total_w2 = 0
best_val2 = 0
for item in final0:
total_w0 += item.waga
best_val0 += item.wartosc
print("----------\n" + f'wartość plecaka: {best}')
for item in final:
print(item.waga, item.wartosc)
for item in final1:
total_w1 += item.waga
best_val1 += item.wartosc
for item in final2:
total_w2 += item.waga
best_val2 += item.wartosc
print("----------\n" + f'wartości plecaka: {best_val0} - {best_val1} - {best_val2}')
print(f"waga plecaka: {total_w0}/{int(cap)} - {total_w1}/{int(cap)} - {total_w2}/{int(cap)}")
binar = ''
for item in dostepne_items:
binar += "1" if item in final0 else "0"
print(binar)
print("---------------")
print(f"Wierzchołki na surowo: {actions0}")
print(f"Wierzchołki z alfa cięciem: {actions1}")
print(f"Wierzchołki z alfabeta cięciem: {actions2}")