python Pyomo,如何在Pyomo中编写一个约束来确保设备的最大运行时间?

m4pnthwp  于 2022-12-21  发布在  Python
关注(0)|答案(1)|浏览(252)

我正在处理一个优化问题,其中有一个设备是可移位的,可以安排在其他时间而不是它的初始时间表。问题是,这个设备有一个特定的占空比,我的意思是,如果它是开着的,它必须开着至少T_ON小时,不能超过T_ON小时。
有一个二进制变量,I(t)显示设备的ON(1)或OFF(0)状态。在Pyomo中,据我所知,我们不能定义变量的if语句,所以我很难在Pyomo中公式化这个问题。我还试图在下图中制作一个图形版本,我正在寻找。
我真的很感激,如果有人能帮助我的想法,如何公式化这个问题。
干杯!:)
See the graphic here! :)
如果"if"语句在Pyomo中起作用,我将把它写成如下形式:

model.Gen  = Set(initialize=RangeSet(0,End_uses -1), doc='set of enduses') #index of end uses

model.T  = Set(initialize=RangeSet(0,50-1), doc='Time') #index of data samples

model.taw = SetOf(model.T) # references whatever is in T
#Yes/No of each item (binary variable) --> include or exclude an item

model.I_test=Var(model.Gen,model.T,within=Binary)
#Min Up time
def MinUp(model,g,t):
    if t > 0:
        if model.I_test[g,t]-model.I_test[g,t-1]>0:
                return sum(model.I_test[g,t2] for t2 in model.taw if t2>=t and t2<=t+T_on[g]) >= T_on[g]*(model.I_test[g,t]-model.I_test[g,t-1])
    else:
        return Constraint.Skip

model.cons5 = Constraint(model.Gen,model.T,rule=MinUp)

我正在寻找一个公式化的问题,甚至是类似的代码,可以帮助我解决这个问题的帮助。

izkcnapc

izkcnapc1#

您缺少的部分是一个额外的变量,用于跟踪 * 机器在哪个时段启动 *。这将允许使用某些整数运算绘制其他几种类型的约束。下面是几个示例。
从你的问题中并不清楚哪一个对你最有用,你似乎暗示min_runtime == max_runtime,然后你提到占空比,但没有定义它。
如果您的规范简化为精确的n小时开启,然后最少n小时关闭,则可以重写下面这些类型的约束之一,使启动后的n时段为"开启",然后n+12n时段为关闭,并删除其他约束。

代码:
# cycling machine example

import pyomo.environ as pyo

# machine characteristics
min_runtime = 2        # minimum number of periods to run after startup
min_reset_time = 3     # off periods after being turned off
duty_cycle = (4, 8)    # 50% duty cycle evaluated over 8 periods "4 of 8"

time_periods = 12
demand = 7 # periods of 'runtime' from the machine

m = pyo.ConcreteModel()

# SETS
m.T = pyo.Set(initialize=range(time_periods))

# VARS
m.start   = pyo.Var(m.T, domain=pyo.Binary, doc='start machine')
m.running = pyo.Var(m.T, domain=pyo.Binary, doc='machine running')

# OBJ
m.obj = pyo.Objective(expr=sum(m.running[t] for t in m.T))   # minimze the runtime

# CONSTRAINTS

# satisfy the demand
m.satisfy_demand = pyo.Constraint(expr=sum(m.running[t] for t in m.T) >= demand)

@m.Constraint(m.T)
def link_running(m, t):
    """machine can only be running if it was running in prior period or started in this one"""
    if t == m.T.first():
        return pyo.Constraint.Skip
    return m.running[t] <= m.running[t-1] + m.start[t]

@m.Constraint(m.T)
def min_runtime(m, t):
    """force the minimum runtime after a start event"""
    # make a subset of the time periods of interest...
    next_time_periods = {t + offset for offset in range(min_runtime) if t + offset < time_periods}
    return sum(m.running[tt] for tt in next_time_periods) >= len(next_time_periods) * m.start[t]

@m.Constraint(m.T)
def honor_reset_time(m, t):
    if t == m.T.first():
        return pyo.Constraint.Skip
    previous_time_periods = {t - offset for offset in range(1, min_reset_time + 1) if t - offset >=0}
    return len(previous_time_periods) * m.start[t] <= sum(1-m.running[tt] for tt in previous_time_periods)

@m.Constraint(m.T)
def duty_cycle_limit(m, t):
    """ evaluate all possible duty cycles and impose limit """
    if t + duty_cycle[1] > time_periods:
        return pyo.Constraint.Skip
    duty_cycle_periods = list(range(t, t + duty_cycle[1]))
    return sum(m.running[tt] for tt in duty_cycle_periods) <= duty_cycle[0]

m.pprint()

solver = pyo.SolverFactory('glpk')
soln = solver.solve(m)
print(soln)
m.running.display()
输出(部分):
Solver: 
- Status: ok
  Termination condition: optimal
  Statistics: 
    Branch and bound: 
      Number of bounded subproblems: 1
      Number of created subproblems: 1
  Error rc: 0
  Time: 0.0057790279388427734
Solution: 
- number of solutions: 0
  number of solutions displayed: 0

running : machine running
    Size=12, Index=T
    Key : Lower : Value : Upper : Fixed : Stale : Domain
      0 :     0 :   1.0 :     1 : False : False : Binary
      1 :     0 :   1.0 :     1 : False : False : Binary
      2 :     0 :   1.0 :     1 : False : False : Binary
      3 :     0 :   1.0 :     1 : False : False : Binary
      4 :     0 :   0.0 :     1 : False : False : Binary
      5 :     0 :   0.0 :     1 : False : False : Binary
      6 :     0 :   0.0 :     1 : False : False : Binary
      7 :     0 :   0.0 :     1 : False : False : Binary
      8 :     0 :   1.0 :     1 : False : False : Binary
      9 :     0 :   1.0 :     1 : False : False : Binary
     10 :     0 :   1.0 :     1 : False : False : Binary
     11 :     0 :   0.0 :     1 : False : False : Binary

相关问题