基于Python/Gekko的乐队演出日程优化结果展示改进问询
乐队日程优化:提取Gekko求解结果生成日程表
我所在的音乐学校要举办学生乐队联合音乐节,由于不同乐队间存在亲属关系,我用Python和Gekko实现了乐队日程优化,目标是最小化有亲属关系乐队的演出间隔时间。目前已得到可行解决方案,但输出的x矩阵过于庞大,不知道如何提取其中值为1的元素,生成按时间顺序排列的日程表,特寻求方向指引。
相关背景:
- 英语非母语
- 并非程序员,以下代码是我花两天学习Python后编写的
实现代码
from gekko import GEKKO import numpy as np m = GEKKO() #variables and constrains n = 20 #n of bands s = 37 #n of slots to play t = 25 #time in minutes one band spend on the stage x = m.Array(m.Var,(n,s),value=0,lb=0,ub=1,integer=True) #matrix of all bands(rows) x slots (columns) for j in range(s): m.Equation(m.sum([x[i,j] for i in range(n)])<=1) #since this is the decision i made it binary and sum=1 to 1 band only ocuppie one slot for i in range(n): m.Equation(m.sum([x[i,j] for j in range(s)])==1) #since this is the decision i made it binary and sum=1 to 1 band only ocuppie one slot z = [k for k in range(1,s+1)] #array with slot index to use to calc time w = z*x*t #time the band will perform ;; used in objetive function #objective #in this exemple the band (1,4) and the band (1,5) have a relationship, and so do (3,2) and (1,15), so the objetive function bellow will try to minimize the sum of the time between bands that have relationship y = m.abs2(w.item(1, 4)-w.item(1, 5))+ m.abs2(w.item(3, 2)-w.item(1, 15)) m.Minimize(y) #solver m.options.SOLVER = 1 m.solve() #print(w.item((1, 4))) print('y') print(y) print('x') print(x)
提取结果生成日程表的方法
Gekko生成的变量矩阵x,需要通过.value属性获取实际数值。直接遍历矩阵,筛选出值为1的位置,就能整理出按时间排序的日程表。
具体实现代码
在现有代码的最后(print(x)语句之后)添加以下代码:
# 提取所有安排了演出的乐队和对应时段 schedule = [] for band_idx in range(n): for slot_idx in range(s): # 用>0.9判断而非==1,避免浮点精度导致的判断误差 if x[band_idx, slot_idx].value[0] > 0.9: # 计算演出开始时间:时段序号(从1开始)乘以单场时长 start_time = (slot_idx + 1) * t # 乐队编号从1开始计数(如果需要和你的索引对应可调整) schedule.append( (start_time, f"乐队{band_idx + 1}") ) # 按演出开始时间排序 schedule.sort() # 打印整理后的日程表 print("\n=== 演出日程表(按时间排序) ===") for time, band in schedule: print(f"开始时间:{time}分钟 -> {band}")
代码说明
- 遍历每个乐队和时段,通过
.value[0]获取Gekko变量的数值,用>0.9判断是否为1(整数变量求解后可能有微小浮点误差) - 演出开始时间计算对应你代码里的逻辑:第
slot_idx个时段(从0开始)对应序号slot_idx+1,乘以单场时长t得到开始时间 - 将结果存入列表后按时间排序,输出清晰的日程表
内容的提问来源于stack exchange,提问作者Lucas Catharino
相关产品推荐
相关产品推荐

