import random
import math
# functiile de baza
def valid_state(x, y, z):
return x >= 10 and y >= 5 and z >= 7 and (5*x + 3*y + z <= 150)
def calculate_impact(x, y, z):
# funcția obiectiv (impactul total).
return 10*x + 15*y + 5*z
def get_random_valid_state():
# adaugam solutii la intamplare
x, y, z = 10, 5, 7 # pornim de la minime
pages_left = 150 - (5*x + 3*y + z)
# adaugam aleator cantități valide
while pages_left > 0:
choice = random.choice(['x', 'y', 'z'])
if choice == 'x' and pages_left >= 5:
x += 1; pages_left -= 5
elif choice == 'y' and pages_left >= 3:
y += 1; pages_left -= 3
elif choice == 'z' and pages_left >= 1:
z += 1; pages_left -= 1
else:
break
return x, y, z
def get_neighbors(x, y, z):
# generare vecini
neighbors = []
moves = [(1,0,0), (-1,0,0), (0,1,0), (0,-1,0), (0,0,1), (0,0,-1)]
for dx, dy, dz in moves:
nx, ny, nz = x + dx, y + dy, z + dz
if valid_state(nx, ny, nz):
neighbors.append((nx, ny, nz))
return neighbors
# Greedy (introduce valoriile maxime pana nu mai incap)
def greedy_optimization():
print("\n Algoritmul Greedy")
x, y, z = 10, 5, 7
pages_used = 5*x + 3*y + z
while pages_used + 3 <= 150: # Cât timp mai încape un y
y += 1
pages_used += 3
while pages_used + 1 <= 150: # Cât timp mai încape un z
z += 1
pages_used += 1
impact = calculate_impact(x, y, z)
print(f"Soluție Greedy: x={x}, y={y}, z={z} | Impact: {impact}")
return impact
# Hill climbing (verifica constant vecinii sa vada care e mai bun)
def hill_climbing():
current_x, current_y, current_z = get_random_valid_state()
current_impact = calculate_impact(current_x, current_y, current_z)
while True:
neighbors = get_neighbors(current_x, current_y, current_z)
best_neighbor = None
best_impact = current_impact
for nx, ny, nz in neighbors:
impact = calculate_impact(nx, ny, nz)
if impact > best_impact:
best_impact = impact
best_neighbor = (nx, ny, nz)
if best_neighbor is None:
break
current_x, current_y, current_z = best_neighbor
current_impact = best_impact
return current_x, current_y, current_z, current_impact
# Simulated annealing (asemanator cu hill, doar ca greseste intentionat pentru a isi face o idee despre date)
def simulated_annealing(temp, cooling_rate, iterations):
current_x, current_y, current_z = get_random_valid_state()
current_impact = calculate_impact(current_x, current_y, current_z)
best_x, best_y, best_z, best_impact = current_x, current_y, current_z, current_impact
for _ in range(iterations):
neighbors = get_neighbors(current_x, current_y, current_z)
if not neighbors:
break
nx, ny, nz = random.choice(neighbors)
new_impact = calculate_impact(nx, ny, nz)
# daca e bun se accepta, daca nu, se accepta cu o probabilitate
if new_impact > current_impact or random.random() < math.exp((new_impact - current_impact) / temp):
current_x, current_y, current_z = nx, ny, nz
current_impact = new_impact
# se salveaza cel mai bun rezultat intalnit
if current_impact > best_impact:
best_x, best_y, best_z, best_impact = current_x, current_y, current_z, current_impact
temp *= cooling_rate # Răcim temperatura
return best_x, best_y, best_z, best_impact
# Rularea
# Greedy
greedy_optimization()
# Hill
print("\n Hill Climbing")
for i in range(1, 4):
x, y, z, impact = hill_climbing()
print(f"Execuția {i}: x={x}, y={y}, z={z} | Impact: {impact}")
# SA
print("\n Simulated Annealing")
params = [
(100.0, 0.95, 100), # T_start=100, Rata racire=0.95, Iterații=100
(500.0, 0.99, 500), # Parametri pentru explorare agresivă
(10.0, 0.80, 50) # Răcire foarte rapidă (devine similar cu Hill Climbing)
] # Odata ce racirea devine aproape de 0 algoritmul va refuza sa mai faca greseli intentionat
for p_idx, (t, cr, iters) in enumerate(params, 1):
print(f"\nConfigurația {p_idx} (Temp={t}, Răcire={cr}, Iterații={iters}):")
for i in range(1, 4):
x, y, z, impact = simulated_annealing(t, cr, iters)
print(f" Execuția {i}: x={x}, y={y}, z={z} | Impact: {impact}")
aW1wb3J0IHJhbmRvbQppbXBvcnQgbWF0aAoKIyBmdW5jdGlpbGUgZGUgYmF6YQpkZWYgdmFsaWRfc3RhdGUoeCwgeSwgeik6CgogICAgcmV0dXJuIHggPj0gMTAgYW5kIHkgPj0gNSBhbmQgeiA+PSA3IGFuZCAoNSp4ICsgMyp5ICsgeiA8PSAxNTApCgpkZWYgY2FsY3VsYXRlX2ltcGFjdCh4LCB5LCB6KToKICAjIGZ1bmPIm2lhIG9iaWVjdGl2IChpbXBhY3R1bCB0b3RhbCkuIAogICAgcmV0dXJuIDEwKnggKyAxNSp5ICsgNSp6CgpkZWYgZ2V0X3JhbmRvbV92YWxpZF9zdGF0ZSgpOgogICAjIGFkYXVnYW0gc29sdXRpaSBsYSBpbnRhbXBsYXJlCiAgICB4LCB5LCB6ID0gMTAsIDUsIDcgIyBwb3JuaW0gZGUgbGEgbWluaW1lCiAgICBwYWdlc19sZWZ0ID0gMTUwIC0gKDUqeCArIDMqeSArIHopCiAgICAKICAgICMgYWRhdWdhbSBhbGVhdG9yIGNhbnRpdMSDyJtpIHZhbGlkZQogICAgd2hpbGUgcGFnZXNfbGVmdCA+IDA6CiAgICAgICAgY2hvaWNlID0gcmFuZG9tLmNob2ljZShbJ3gnLCAneScsICd6J10pCiAgICAgICAgaWYgY2hvaWNlID09ICd4JyBhbmQgcGFnZXNfbGVmdCA+PSA1OgogICAgICAgICAgICB4ICs9IDE7IHBhZ2VzX2xlZnQgLT0gNQogICAgICAgIGVsaWYgY2hvaWNlID09ICd5JyBhbmQgcGFnZXNfbGVmdCA+PSAzOgogICAgICAgICAgICB5ICs9IDE7IHBhZ2VzX2xlZnQgLT0gMwogICAgICAgIGVsaWYgY2hvaWNlID09ICd6JyBhbmQgcGFnZXNfbGVmdCA+PSAxOgogICAgICAgICAgICB6ICs9IDE7IHBhZ2VzX2xlZnQgLT0gMQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGJyZWFrICAKICAgIHJldHVybiB4LCB5LCB6CgpkZWYgZ2V0X25laWdoYm9ycyh4LCB5LCB6KToKICAgICAjIGdlbmVyYXJlIHZlY2luaQogICAgbmVpZ2hib3JzID0gW10KICAgIG1vdmVzID0gWygxLDAsMCksICgtMSwwLDApLCAoMCwxLDApLCAoMCwtMSwwKSwgKDAsMCwxKSwgKDAsMCwtMSldCiAgICBmb3IgZHgsIGR5LCBkeiBpbiBtb3ZlczoKICAgICAgICBueCwgbnksIG56ID0geCArIGR4LCB5ICsgZHksIHogKyBkegogICAgICAgIGlmIHZhbGlkX3N0YXRlKG54LCBueSwgbnopOgogICAgICAgICAgICBuZWlnaGJvcnMuYXBwZW5kKChueCwgbnksIG56KSkKICAgIHJldHVybiBuZWlnaGJvcnMKCiMgICBHcmVlZHkgKGludHJvZHVjZSB2YWxvcmlpbGUgbWF4aW1lIHBhbmEgbnUgbWFpIGluY2FwKQpkZWYgZ3JlZWR5X29wdGltaXphdGlvbigpOgogICAgcHJpbnQoIlxuIEFsZ29yaXRtdWwgR3JlZWR5IikKICAgIHgsIHksIHogPSAxMCwgNSwgNwogICAgcGFnZXNfdXNlZCA9IDUqeCArIDMqeSArIHoKICAgIAogICAgd2hpbGUgcGFnZXNfdXNlZCArIDMgPD0gMTUwOiAjIEPDonQgdGltcCBtYWkgw65uY2FwZSB1biB5CiAgICAgICAgeSArPSAxCiAgICAgICAgcGFnZXNfdXNlZCArPSAzCiAgICAgICAgCiAgICB3aGlsZSBwYWdlc191c2VkICsgMSA8PSAxNTA6ICMgQ8OidCB0aW1wIG1haSDDrm5jYXBlIHVuIHoKICAgICAgICB6ICs9IDEKICAgICAgICBwYWdlc191c2VkICs9IDEKICAgICAgICAKICAgIGltcGFjdCA9IGNhbGN1bGF0ZV9pbXBhY3QoeCwgeSwgeikKICAgIHByaW50KGYiU29sdcibaWUgR3JlZWR5OiB4PXt4fSwgeT17eX0sIHo9e3p9IHwgSW1wYWN0OiB7aW1wYWN0fSIpCiAgICByZXR1cm4gaW1wYWN0CgojIEhpbGwgY2xpbWJpbmcgKHZlcmlmaWNhIGNvbnN0YW50IHZlY2luaWkgc2EgdmFkYSBjYXJlIGUgbWFpIGJ1bikKZGVmIGhpbGxfY2xpbWJpbmcoKToKICAgIGN1cnJlbnRfeCwgY3VycmVudF95LCBjdXJyZW50X3ogPSBnZXRfcmFuZG9tX3ZhbGlkX3N0YXRlKCkKICAgIGN1cnJlbnRfaW1wYWN0ID0gY2FsY3VsYXRlX2ltcGFjdChjdXJyZW50X3gsIGN1cnJlbnRfeSwgY3VycmVudF96KQogICAgCiAgICB3aGlsZSBUcnVlOgogICAgICAgIG5laWdoYm9ycyA9IGdldF9uZWlnaGJvcnMoY3VycmVudF94LCBjdXJyZW50X3ksIGN1cnJlbnRfeikKICAgICAgICBiZXN0X25laWdoYm9yID0gTm9uZQogICAgICAgIGJlc3RfaW1wYWN0ID0gY3VycmVudF9pbXBhY3QKICAgICAgICAKICAgICAgICBmb3IgbngsIG55LCBueiBpbiBuZWlnaGJvcnM6CiAgICAgICAgICAgIGltcGFjdCA9IGNhbGN1bGF0ZV9pbXBhY3QobngsIG55LCBueikKICAgICAgICAgICAgaWYgaW1wYWN0ID4gYmVzdF9pbXBhY3Q6CiAgICAgICAgICAgICAgICBiZXN0X2ltcGFjdCA9IGltcGFjdAogICAgICAgICAgICAgICAgYmVzdF9uZWlnaGJvciA9IChueCwgbnksIG56KQogICAgICAgICAgICAgICAgCiAgICAgICAgaWYgYmVzdF9uZWlnaGJvciBpcyBOb25lOiAKICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgCiAgICAgICAgY3VycmVudF94LCBjdXJyZW50X3ksIGN1cnJlbnRfeiA9IGJlc3RfbmVpZ2hib3IKICAgICAgICBjdXJyZW50X2ltcGFjdCA9IGJlc3RfaW1wYWN0CiAgICAgICAgCiAgICByZXR1cm4gY3VycmVudF94LCBjdXJyZW50X3ksIGN1cnJlbnRfeiwgY3VycmVudF9pbXBhY3QKCiMgU2ltdWxhdGVkIGFubmVhbGluZyAoYXNlbWFuYXRvciBjdSBoaWxsLCBkb2FyIGNhIGdyZXNlc3RlIGludGVudGlvbmF0IHBlbnRydSBhIGlzaSBmYWNlIG8gaWRlZSBkZXNwcmUgZGF0ZSkKZGVmIHNpbXVsYXRlZF9hbm5lYWxpbmcodGVtcCwgY29vbGluZ19yYXRlLCBpdGVyYXRpb25zKToKICAgIGN1cnJlbnRfeCwgY3VycmVudF95LCBjdXJyZW50X3ogPSBnZXRfcmFuZG9tX3ZhbGlkX3N0YXRlKCkKICAgIGN1cnJlbnRfaW1wYWN0ID0gY2FsY3VsYXRlX2ltcGFjdChjdXJyZW50X3gsIGN1cnJlbnRfeSwgY3VycmVudF96KQogICAgCiAgICBiZXN0X3gsIGJlc3RfeSwgYmVzdF96LCBiZXN0X2ltcGFjdCA9IGN1cnJlbnRfeCwgY3VycmVudF95LCBjdXJyZW50X3osIGN1cnJlbnRfaW1wYWN0CiAgICAKICAgIGZvciBfIGluIHJhbmdlKGl0ZXJhdGlvbnMpOgogICAgICAgIG5laWdoYm9ycyA9IGdldF9uZWlnaGJvcnMoY3VycmVudF94LCBjdXJyZW50X3ksIGN1cnJlbnRfeikKICAgICAgICBpZiBub3QgbmVpZ2hib3JzOgogICAgICAgICAgICBicmVhawogICAgICAgICAgICAKICAgICAgICBueCwgbnksIG56ID0gcmFuZG9tLmNob2ljZShuZWlnaGJvcnMpCiAgICAgICAgbmV3X2ltcGFjdCA9IGNhbGN1bGF0ZV9pbXBhY3QobngsIG55LCBueikKICAgICAgICAKICAgICAgICAjIGRhY2EgZSBidW4gc2UgYWNjZXB0YSwgZGFjYSBudSwgc2UgYWNjZXB0YSBjdSBvIHByb2JhYmlsaXRhdGUKICAgICAgICBpZiBuZXdfaW1wYWN0ID4gY3VycmVudF9pbXBhY3Qgb3IgcmFuZG9tLnJhbmRvbSgpIDwgbWF0aC5leHAoKG5ld19pbXBhY3QgLSBjdXJyZW50X2ltcGFjdCkgLyB0ZW1wKToKICAgICAgICAgICAgY3VycmVudF94LCBjdXJyZW50X3ksIGN1cnJlbnRfeiA9IG54LCBueSwgbnoKICAgICAgICAgICAgY3VycmVudF9pbXBhY3QgPSBuZXdfaW1wYWN0CiAgICAgICAgICAgIAogICAgICAgICAgICAjIHNlIHNhbHZlYXphIGNlbCBtYWkgYnVuIHJlenVsdGF0IGludGFsbml0CiAgICAgICAgICAgIGlmIGN1cnJlbnRfaW1wYWN0ID4gYmVzdF9pbXBhY3Q6CiAgICAgICAgICAgICAgICBiZXN0X3gsIGJlc3RfeSwgYmVzdF96LCBiZXN0X2ltcGFjdCA9IGN1cnJlbnRfeCwgY3VycmVudF95LCBjdXJyZW50X3osIGN1cnJlbnRfaW1wYWN0CiAgICAgICAgICAgICAgICAKICAgICAgICB0ZW1wICo9IGNvb2xpbmdfcmF0ZSAjIFLEg2NpbSB0ZW1wZXJhdHVyYQogICAgICAgIAogICAgcmV0dXJuIGJlc3RfeCwgYmVzdF95LCBiZXN0X3osIGJlc3RfaW1wYWN0CgojIFJ1bGFyZWEKCiMgR3JlZWR5CmdyZWVkeV9vcHRpbWl6YXRpb24oKQoKIyBIaWxsCnByaW50KCJcbiBIaWxsIENsaW1iaW5nIikKZm9yIGkgaW4gcmFuZ2UoMSwgNCk6CiAgICB4LCB5LCB6LCBpbXBhY3QgPSBoaWxsX2NsaW1iaW5nKCkKICAgIHByaW50KGYiRXhlY3XIm2lhIHtpfTogeD17eH0sIHk9e3l9LCB6PXt6fSB8IEltcGFjdDoge2ltcGFjdH0iKQoKIyBTQQpwcmludCgiXG4gU2ltdWxhdGVkIEFubmVhbGluZyIpCnBhcmFtcyA9IFsKICAgICgxMDAuMCwgMC45NSwgMTAwKSwgICMgVF9zdGFydD0xMDAsIFJhdGEgcmFjaXJlPTAuOTUsIEl0ZXJhyJtpaT0xMDAKICAgICg1MDAuMCwgMC45OSwgNTAwKSwgICMgUGFyYW1ldHJpIHBlbnRydSBleHBsb3JhcmUgYWdyZXNpdsSDCiAgICAoMTAuMCwgIDAuODAsIDUwKSAgICAjIFLEg2NpcmUgZm9hcnRlIHJhcGlkxIMgKGRldmluZSBzaW1pbGFyIGN1IEhpbGwgQ2xpbWJpbmcpCl0gIyBPZGF0YSBjZSByYWNpcmVhIGRldmluZSBhcHJvYXBlIGRlIDAgYWxnb3JpdG11bCB2YSByZWZ1emEgc2EgbWFpIGZhY2EgZ3Jlc2VsaSBpbnRlbnRpb25hdAoKZm9yIHBfaWR4LCAodCwgY3IsIGl0ZXJzKSBpbiBlbnVtZXJhdGUocGFyYW1zLCAxKToKICAgIHByaW50KGYiXG5Db25maWd1cmHIm2lhIHtwX2lkeH0gKFRlbXA9e3R9LCBSxINjaXJlPXtjcn0sIEl0ZXJhyJtpaT17aXRlcnN9KToiKQogICAgZm9yIGkgaW4gcmFuZ2UoMSwgNCk6CiAgICAgICAgeCwgeSwgeiwgaW1wYWN0ID0gc2ltdWxhdGVkX2FubmVhbGluZyh0LCBjciwgaXRlcnMpCiAgICAgICAgcHJpbnQoZiIgIEV4ZWN1yJtpYSB7aX06IHg9e3h9LCB5PXt5fSwgej17en0gfCBJbXBhY3Q6IHtpbXBhY3R9IikK