代码模板¶
每天学完对应专题,就把这里的骨架跑一遍、换成自己的数据。比赛当天不要现学语法,只改数字和变量名。
熵权法 + TOPSIS · 评价类¶
import numpy as np
def entropy_weight(X):
# X: n个方案 x m个指标,已做正向化+标准化到[0,1]
X = X + 1e-12
P = X / X.sum(axis=0)
k = 1 / np.log(len(X))
e = -k * (P * np.log(P)).sum(axis=0)
d = 1 - e
return d / d.sum() # 各指标权重
def topsis(X, w):
Z = X / np.sqrt((X**2).sum(axis=0)) # 标准化
Zw = Z * w
best, worst = Zw.max(axis=0), Zw.min(axis=0)
d_best = np.sqrt(((Zw - best )**2).sum(axis=1))
d_worst = np.sqrt(((Zw - worst)**2).sum(axis=1))
return d_worst / (d_best + d_worst) # 得分,越大越优
AHP 层次分析法(一致性检验)· 评价类¶
import numpy as np
def ahp_weight(A):
# A: 判断矩阵 (n x n)
n = A.shape[0]
eigvals, eigvecs = np.linalg.eig(A)
idx = np.argmax(eigvals.real)
w = eigvecs[:, idx].real
w = w / w.sum()
lam_max = eigvals[idx].real
CI = (lam_max - n) / (n - 1)
RI = {1:0,2:0,3:0.58,4:0.9,5:1.12,6:1.24,7:1.32,8:1.41,9:1.45}[n]
CR = CI / RI if RI else 0
return w, CR # CR < 0.1 才算通过一致性检验
灰色预测 GM(1,1) · 预测类¶
import numpy as np
def gm11(x0, forecast=5):
x1 = np.cumsum(x0)
z1 = (x1[:-1] + x1[1:]) / 2
B = np.column_stack((-z1, np.ones(len(z1))))
Y = x0[1:].reshape(-1, 1)
a, b = np.linalg.lstsq(B, Y, rcond=None)[0].flatten()
def x1_hat(k): return (x0[0] - b/a) * np.exp(-a*k) + b/a
pred = [x1_hat(0)] + [x1_hat(k) - x1_hat(k-1) for k in range(1, len(x0)+forecast)]
return np.array(pred)
整数规划 · 优化类¶
import pulp
prob = pulp.LpProblem("demo", pulp.LpMaximize)
x = [pulp.LpVariable(f"x{i}", lowBound=0, cat="Integer") for i in range(3)]
prob += 5*x[0] + 4*x[1] + 3*x[2] # 目标函数
prob += 2*x[0] + 3*x[1] + x[2] <= 5 # 约束
prob += 4*x[0] + x[1] + 2*x[2] <= 11
prob.solve()
print([v.varValue for v in x], pulp.value(prob.objective))
遗传算法骨架 · 优化类¶
import numpy as np
def genetic_algorithm(fitness_fn, dim, bounds, pop=50, gens=200, pc=0.8, pm=0.05):
lo, hi = bounds
population = lo + (hi - lo) * np.random.rand(pop, dim)
for _ in range(gens):
fit = np.array([fitness_fn(ind) for ind in population])
parents = population[np.argsort(-fit)[:pop//2]] # 选择:保留前50%
kids = []
while len(kids) < pop - len(parents):
p1, p2 = parents[np.random.randint(len(parents), size=2)]
mask = np.random.rand(dim) < 0.5
child = np.where(mask, p1, p2) if np.random.rand() < pc else p1.copy()
if np.random.rand() < pm:
child += np.random.normal(0, 0.1, dim)
kids.append(np.clip(child, lo, hi))
population = np.vstack([parents, kids])
fit = np.array([fitness_fn(ind) for ind in population])
return population[np.argmax(fit)], fit.max() # 换掉 fitness_fn 即可复用