You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Python/Gekko的乐队排程优化方案展示优化需求

乐队排程优化方案改进

问题需求

我所在的音乐学校举办学生乐队联合音乐节,需优化乐队演出排程,使有亲属关系的乐队演出时间间隔总和最小。目前已用Python/Gekko实现可行方案,但需做两项改进:

  1. 不再手动定义乐队数量n,改为从用户输入的乐队列表自动统计;
  2. 输出乐队名称而非ID(名称来自用户输入的乐队列表)。

后续还计划让目标函数支持用户输入,但暂不重点处理。以下是当前使用的代码:

from gekko import GEKKO
import numpy as np
m = GEKKO()

#variables and constrains
n = 10 #n of bands
s = 10 #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 slot can only be ocupied by one band
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,9), 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, 9)) 
m.Minimize(y)


#solver
m.options.SOLVER = 1
m.solve()



#prints the schedule
schedule = [(i+1, j+1) for i in range(n) for j in range(s) if x[i,j][0] == 1]
schedule.sort(key=lambda x: x[1])
for band, slot in schedule:
    print(f"Band {band} is scheduled to play in slot {slot}")

修改后的代码

from gekko import GEKKO
import numpy as np

# 用户输入乐队列表,可直接替换为实际乐队名称
band_names = [
    "摇滚少年团",
    "爵士风组合",
    "古典重奏组",
    "嘻哈小分队",
    "民谣唱作社",
    "电音实验团",
    "朋克突击队",
    "蓝调乐团",
    "流行唱跳团",
    "金属核乐队"
]

m = GEKKO()

# 自动从乐队列表获取乐队数量n
n = len(band_names)
s = 10  # 演出时段数量
t = 25  # 每个乐队演出时长(分钟)

# 定义变量矩阵:乐队(行) x 时段(列),二进制变量
x = m.Array(m.Var, (n, s), value=0, lb=0, ub=1, integer=True)

# 约束条件:每个时段最多一个乐队演出
for j in range(s):
    m.Equation(m.sum([x[i, j] for i in range(n)]) <= 1)
# 约束条件:每个乐队必须演出一次
for i in range(n):
    m.Equation(m.sum([x[i, j] for j in range(s)]) == 1)

# 计算每个乐队的演出时间点(时段序号*时长)
z = np.array([k for k in range(1, s+1)])
w = z * x * t

# 目标函数:最小化有亲属关系乐队的时间间隔总和(示例关系)
# 注意:索引对应band_names列表的0下标(Python列表从0开始计数)
y = m.abs2(w.item(0, 3) - w.item(0, 4)) + m.abs2(w.item(2, 1) - w.item(0, 8))
m.Minimize(y)

# 求解器设置
m.options.SOLVER = 1
m.solve()

# 生成并输出排程(按时段排序)
schedule = []
for i in range(n):
    for j in range(s):
        if x[i, j][0] == 1:
            schedule.append((band_names[i], j+1))

schedule.sort(key=lambda item: item[1])
for band_name, slot in schedule:
    print(f"乐队 {band_name} 被安排在第 {slot} 个时段演出")

关键改动说明

  • 自动获取乐队数量:通过len(band_names)自动计算乐队总数n,无需手动硬编码;
  • 输出乐队名称:将原代码中依赖ID的逻辑替换为直接调用band_names列表中的名称,排程输出时直接展示乐队名;
  • 索引适配:原代码目标函数使用1-based索引,修改后对应Python列表的0-based索引(比如原w.item(1,4)对应新代码的w.item(0,3));
  • 扩展性:band_names列表可灵活替换,比如通过循环input()获取用户输入的乐队名称,或从文件读取批量数据。

内容的提问来源于stack exchange,提问作者Lucas Catharino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 00:25:02