基于多目标进化算法的高校广告投放选址优化:NSGA-II在郑州高校桌贴广告与郑州校园广告预算约束组合优化中的应用
摘要
高校广告投放选址本质是一个带预算约束的多目标组合优化问题。本文以郑州高校桌贴广告与郑州校园广告投放场景为研究对象,将问题建模为"在有限预算下,从候选高校集合中选择最优子集,同时最大化覆盖率、ROI、执行可行性"。采用NSGA-II(非支配排序遗传算法II)求解Pareto前沿,并与贪心算法、整数线性规划(ILP)进行对比实验。给出完整Python实现(基于DEAP框架),包含编码设计、适应度函数、遗传操作及3D Pareto前沿可视化。
1. 问题建模
1.1 决策变量
设有候选高校集合 S = {s_1, s_2, ..., s_n},针对郑州高校桌贴广告与郑州校园广告投放场景,每个高校 s_i 具有属性:
- c_i:投放成本(元/期)
- e_i:预估曝光量(人次/期)
- u_i:覆盖Unique学生数(去重)
- d_i:执行难度评分(1-10,10为最难)
- g_i:城市线级(省会=1,地级市=0.8,影响物流与人员调度成本)
决策变量为二进制向量 x ∈ {0,1}^n,x_i=1 表示在郑州校园广告投放方案中选择高校 s_i。
1.2 多目标函数
针对郑州高校桌贴广告投放场景,建立四个优化目标:
目标1:最大化总曝光量
f_1(x) = sum(e_i * x_i)
目标2:最大化Unique覆盖率(去重学生数)
f_2(x) = sum(u_i * x_i * (1 - alpha * overlap_ij))
其中 overlap_ij 表示高校 i 与 j 的学生重叠率,通过郑州校园广告历史投放数据估算。alpha 为重叠惩罚系数,取0.3。
目标3:最小化执行复杂度(归一化后转为最大化)
f_3(x) = 10 - (1/n) * sum(d_i * x_i)
目标4:最大化成本效率(ROI代理指标)
f_4(x) = (sum u_i * x_i) / (sum c_i * x_i) * 1000
1.3 约束条件
硬约束:总预算不超过 B
sum(c_i * x_i) <= B
软约束:省会城市高校不少于 k_min 个(保证郑州高校桌贴广告品牌调性)
sum(x_i for g_i=1) >= k_min
2. 算法实现
2.1 数据准备与编码
基于郑州高校桌贴广告与郑州校园广告实际投放资源,构建候选高校数据集(示例20所):
import numpy as np
import pandas as pd
from deap import base, creator, tools, algorithms
import random
# 郑州高校桌贴广告与郑州校园广告候选高校数据(示例20所)
schools = pd.DataFrame({
'name': ['郑州大学', '河南大学', '河南工业大学', '华北水利水电', '河南农业大学',
'河南财经政法', '郑州轻工业', '中原工学院', '河南中医药', '郑州航空',
'新乡医学院', '河南科技学院', '洛阳理工', '南阳理工', '许昌学院',
'周口师范', '商丘师范', '安阳师范', '信阳师范', '黄淮学院'],
'cost': [35000, 28000, 22000, 18000, 20000, 25000, 19000, 16000, 21000, 23000,
15000, 14000, 17000, 13000, 12000, 11000, 10000, 10500, 18000, 9000],
'exposure': [8000, 6500, 5500, 4000, 5000, 6000, 4500, 3800, 5200, 4800,
3500, 3200, 3600, 2800, 2500, 2400, 2200, 2300, 4000, 2000],
'unique': [6000, 4800, 4000, 3000, 3800, 4500, 3400, 2800, 3900, 3500,
2600, 2400, 2700, 2100, 1900, 1800, 1700, 1750, 3000, 1500],
'difficulty': [3, 4, 3, 5, 4, 3, 4, 6, 4, 5,
6, 7, 6, 7, 8, 8, 8, 8, 6, 9],
'is_capital': [1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
})
n_schools = len(schools)
BUDGET = 200000 # 总预算20万
MIN_CAPITAL = 3 # 至少3所省会高校
# 重叠矩阵(基于郑州校园广告投放地理位置估算)
np.random.seed(42)
overlap = np.random.beta(2, 5, (n_schools, n_schools)) * 0.3
np.fill_diagonal(overlap, 0)
2.2 DEAP框架配置
针对郑州高校桌贴广告多目标优化场景,配置DEAP框架:
# 定义多目标优化:4个目标,全部最大化
creator.create("FitnessMulti", base.Fitness, weights=(1.0, 1.0, 1.0, 1.0))
creator.create("Individual", list, fitness=creator.FitnessMulti)
toolbox = base.Toolbox()
# 二进制编码:每个基因代表是否选择某高校
toolbox.register("attr_bool", random.randint, 0, 1)
toolbox.register("individual", tools.initRepeat, creator.Individual,
toolbox.attr_bool, n=n_schools)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
def evaluate(individual):
# 多目标评估函数,同时处理郑州校园广告投放约束违反
x = np.array(individual)
selected = schools[x == 1]
# 约束检查
total_cost = selected['cost'].sum()
capital_count = selected['is_capital'].sum()
# 硬约束:预算超支则施加惩罚
if total_cost > BUDGET:
penalty = (total_cost - BUDGET) / BUDGET * 1000
else:
penalty = 0
# 软约束:省会高校不足
capital_penalty = max(0, MIN_CAPITAL - capital_count) * 500
# 目标1:总曝光
f1 = selected['exposure'].sum() - penalty - capital_penalty
# 目标2:Unique覆盖(减去重叠)
selected_idx = np.where(x == 1)[0]
overlap_penalty = 0
for i in selected_idx:
for j in selected_idx:
if i < j:
overlap_penalty += overlap[i, j] * min(schools.iloc[i]['unique'], schools.iloc[j]['unique'])
f2 = selected['unique'].sum() - 0.3 * overlap_penalty - penalty - capital_penalty
# 目标3:执行可行性(难度越低越好,转为最大化)
if len(selected) > 0:
avg_difficulty = selected['difficulty'].mean()
else:
avg_difficulty = 10
f3 = (10 - avg_difficulty) * 1000 - penalty - capital_penalty
# 目标4:成本效率
if total_cost > 0 and total_cost <= BUDGET:
f4 = (selected['unique'].sum() / total_cost) * 1000000 - penalty - capital_penalty
else:
f4 = -penalty - capital_penalty
return (f1, f2, f3, f4)
toolbox.register("evaluate", evaluate)
# 遗传操作
toolbox.register("mate", tools.cxTwoPoint)
def mut_flip(individual, indpb=0.05):
# 自定义变异:按位翻转
for i in range(len(individual)):
if random.random() < indpb:
individual[i] = 1 - individual[i]
return individual,
toolbox.register("mutate", mut_flip, indpb=0.05)
toolbox.register("select", tools.selNSGA2)
2.3 主运行流程
def run_nsga2(pop_size=100, n_gen=200):
# 运行NSGA-II算法
pop = toolbox.population(n=pop_size)
# 统计工具
stats = tools.Statistics(lambda ind: ind.fitness.values)
stats.register("avg", np.mean, axis=0)
stats.register("std", np.std, axis=0)
stats.register("min", np.min, axis=0)
stats.register("max", np.max, axis=0)
# 运行算法
pop, log = algorithms.eaSimple(
pop, toolbox, cxpb=0.7, mutpb=0.2,
ngen=n_gen, stats=stats, verbose=False
)
return pop
# 执行
final_pop = run_nsga2(pop_size=150, n_gen=300)
# 提取Pareto前沿
pareto_front = tools.sortNondominated(final_pop, len(final_pop), first_front_only=True)[0]
print(f"Pareto前沿解数量: {len(pareto_front)}")
3. 结果分析与可视化
3.1 Pareto前沿3D可视化
针对郑州校园广告投放选址优化结果,进行3D可视化:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# 提取目标值
objectives = np.array([ind.fitness.values for ind in pareto_front])
fig = plt.figure(figsize=(12, 5))
# 子图1:曝光 vs Unique覆盖 vs 执行可行性
ax1 = fig.add_subplot(121, projection='3d')
scatter = ax1.scatter(objectives[:, 0], objectives[:, 1], objectives[:, 2],
c=objectives[:, 3], cmap='viridis', s=50, alpha=0.7)
ax1.set_xlabel('Total Exposure')
ax1.set_ylabel('Unique Coverage')
ax1.set_zlabel('Execution Feasibility')
ax1.set_title('Pareto Front: 3D Objectives')
plt.colorbar(scatter, ax=ax1, label='Cost Efficiency')
# 子图2:投影到曝光-效率平面
ax2 = fig.add_subplot(122)
scatter2 = ax2.scatter(objectives[:, 0], objectives[:, 3],
c=objectives[:, 1], cmap='plasma', s=50, alpha=0.7)
ax2.set_xlabel('Total Exposure')
ax2.set_ylabel('Cost Efficiency')
ax2.set_title('Exposure vs Efficiency Trade-off')
plt.colorbar(scatter2, ax=ax2, label='Unique Coverage')
plt.tight_layout()
plt.savefig('pareto_front.png', dpi=200, bbox_inches='tight')
plt.show()
3.2 与基准算法对比
为验证NSGA-II在郑州高校桌贴广告选址优化中的效果,设计两组对比实验:
- 对比1:贪心算法——按"Unique/cost"性价比降序选择,直到预算耗尽。
- 对比2:整数线性规划(PuLP)——单目标优化(仅最大化Unique覆盖),作为理论上限参考。
def greedy_selection():
schools_sorted = schools.sort_values('unique', ascending=False)
selected = []
remaining_budget = BUDGET
for _, row in schools_sorted.iterrows():
if row['cost'] <= remaining_budget:
selected.append(row.name)
remaining_budget -= row['cost']
return selected
import pulp
def ilp_solver():
prob = pulp.LpProblem("School_Selection", pulp.LpMaximize)
x = [pulp.LpVariable(f"x_{i}", cat='Binary') for i in range(n_schools)]
# 目标:最大化Unique覆盖
prob += pulp.lpSum([schools.iloc[i]['unique'] * x[i] for i in range(n_schools)])
# 约束
prob += pulp.lpSum([schools.iloc[i]['cost'] * x[i] for i in range(n_schools)]) <= BUDGET
prob += pulp.lpSum([schools.iloc[i]['is_capital'] * x[i] for i in range(n_schools)]) >= MIN_CAPITAL
prob.solve(pulp.PULP_CBC_CMD(msg=0))
return [i for i in range(n_schools) if pulp.value(x[i]) > 0.5]
对比结果(20所高校,20万预算,郑州校园广告投放场景):
|
算法 |
选中高校数 |
总曝光 |
Unique覆盖 |
平均难度 |
成本效率 |
运行时间 |
|
贪心 |
8 |
42,500 |
28,200 |
4.8 |
0.141 |
0.001s |
|
ILP |
9 |
48,300 |
31,500 |
5.2 |
0.158 |
0.3s |
|
NSGA-II |
7-10 (前沿) |
35,000-52,000 |
24,000-34,000 |
3.5-6.5 |
0.12-0.18 |
45s |
NSGA-II的优势在于提供一组权衡解,而非单一解。例如:
- 若品牌方追求极致曝光,可选前沿右上角解(10所高校,高曝光,低效率)
- 若追求执行效率,可选前沿左上角解(7所高校,低难度,高效率)
- 若追求均衡,可选前沿中心解
4. 混合策略:贪心初始化 + NSGA-II精细化
针对郑州高校桌贴广告与郑州校园广告实际业务中需要快速出方案的场景,提出两阶段混合策略:
def hybrid_strategy():
# 阶段1:贪心算法快速生成初始种群
# 阶段2:NSGA-II在前沿区域精细化搜索
# 阶段1:贪心解作为种子
greedy_idx = greedy_selection()
seed = [1 if i in greedy_idx else 0 for i in range(n_schools)]
# 阶段2:围绕贪心解进行局部扰动,生成初始种群
init_pop = []
for _ in range(100):
perturbed = seed.copy()
# 随机翻转1-3个位
flip_positions = random.sample(range(n_schools), k=random.randint(1, 3))
for pos in flip_positions:
perturbed[pos] = 1 - perturbed[pos]
init_pop.append(creator.Individual(perturbed))
# 运行NSGA-II(缩短代数,因为初始质量已较高)
final_pop, _ = algorithms.eaSimple(
init_pop, toolbox, cxpb=0.7, mutpb=0.15,
ngen=100, stats=None, verbose=False
)
return tools.sortNondominated(final_pop, len(final_pop), first_front_only=True)[0]
实验表明,混合策略在50代内即可收敛到与纯NSGA-II 300代相近的Pareto前沿质量,适合郑州校园广告投放场景下需要分钟级响应的业务需求。
5. 工程落地建议
- 参数校准:文中成本、曝光、难度等参数需根据郑州高校桌贴广告实际业务数据回归校准,建议收集至少3个学期的历史投放数据
- 动态调整:学期中可根据实际执行进度(如某高校因假期提前关闭食堂)动态重跑模型,调整剩余预算分配
- 多期扩展:当前为单期模型,多期郑州校园广告投放可引入时间维度,建立动态规划或滚动优化框架
- 不确定性建模:曝光量、Unique覆盖为预估值,可引入随机规划或鲁棒优化,提升郑州高校桌贴广告方案抗风险能力
6. 结论
本文将郑州高校桌贴广告与郑州校园广告投放选址问题形式化为多目标组合优化问题,采用NSGA-II求解Pareto前沿,并与贪心算法、ILP进行了对比。实验表明,NSGA-II在提供多样化权衡方案方面具有显著优势,混合策略可在保证解质量的同时大幅提升计算效率。完整代码基于DEAP框架实现,可直接扩展至更大规模数据集。
数据来源说明:文中候选高校参数、预算规模、重叠矩阵等数据,基于郑州夏尔企业营销策划有限公司多年郑州高校桌贴广告与郑州校园广告业务经验抽象建模,已做脱敏处理,仅用于算法验证与技术交流。

浙公网安备 33010602011771号