import numpy as np NODE_TYPES = {"A": dict(cap=6.0, mem=4.0, p_idle=4.0, p_peak=15.0), "B": dict(cap=24.0, mem=16.0, p_idle=12.0, p_peak=65.0)} DT = 0.1 def make_nodes(n_nodes, rng): nodes = [] for i in range(n_nodes): t = "A" if rng.random() < 0.5 else "B" base = NODE_TYPES[t]; jit = rng.uniform(0.85, 1.15) nodes.append(dict(id=i, type=t, cap=base["cap"]*jit, mem=base["mem"], p_idle=base["p_idle"], p_peak=base["p_peak"])) return nodes def node_arrays(nodes): return (np.array([n["cap"] for n in nodes], dtype=float), np.array([n["mem"] for n in nodes], dtype=float), np.array([n["p_idle"] for n in nodes], dtype=float), np.array([n["p_peak"] for n in nodes], dtype=float)) def make_tasks(n_tasks, rng): if n_tasks == 0: return (np.zeros(0), np.zeros(0), np.zeros(0), np.zeros(0, dtype=int)) cls = (rng.random(n_tasks) < 0.40).astype(int) demand = np.where(cls == 1, rng.uniform(0.05, 0.30, n_tasks), rng.uniform(0.40, 1.50, n_tasks)) mem = np.where(cls == 1, rng.uniform(0.05, 0.4, n_tasks), rng.uniform(0.2, 1.2, n_tasks)) deadline = np.where(cls == 1, 0.050, 0.500) return demand, mem, deadline, cls def make_link_latency(n_nodes, rng): return rng.uniform(0.002, 0.020, n_nodes) def evaluate(assign, demand, mem, deadline, cls, backlog, cap, link_lat, p_idle, p_peak, alpha=0.5, beta=0.3, gamma=0.2, dt=DT, return_metrics=False, node_mem=None): n_nodes = cap.shape[0]; m = assign.shape[0] work = np.zeros(n_nodes); memload = np.zeros(n_nodes); lat = np.zeros(m) order = np.lexsort((demand, -cls)); ahead = backlog.copy() for idx in order: n = assign[idx] proc = demand[idx] / cap[n]; wait = ahead[n] / cap[n] lat[idx] = link_lat[n] + wait + proc ahead[n] += demand[idx]; work[n] += demand[idx]; memload[n] += mem[idx] served = np.minimum(ahead, cap * dt) util = np.clip(served / (cap * dt), 0.0, 1.0) avg_lat = float(lat.mean()) if m > 0 else 0.0 energy = float(np.sum((p_idle + (p_peak - p_idle) * util) * dt)) sigma_u = float(np.std(util)) cap_over = np.maximum(work - cap * dt, 0.0).sum() mem_over = np.maximum(memload - node_mem, 0.0).sum() if node_mem is not None else 0.0 penalty = 50.0 * cap_over + 50.0 * mem_over lat_n = avg_lat / 0.1; en_n = energy / (n_nodes * 0.065 + 1e-9) fit = alpha * lat_n + beta * en_n + gamma * sigma_u + penalty if not return_metrics: return fit classA = cls == 1 a_met = float(np.mean(lat[classA] <= deadline[classA])) if classA.any() else 1.0 met_all = float(np.mean(lat <= deadline)) if m > 0 else 1.0 jain = float((util.sum() ** 2) / (n_nodes * np.sum(util ** 2) + 1e-12)) if util.sum() > 0 else 1.0 return dict(fitness=fit, avg_latency=avg_lat, energy=energy, sigma_u=sigma_u, utilization=float(util.mean()), jain=jain, classA_deadline_met=a_met, all_deadline_met=met_all, served=served, work=work)