如何计算目标函数中的子和? Gurobi优化

问题描述 投票:0回答:3

我需要最小化以下功能:enter image description here

其中d_it - 二进制数组:d_it = [[1,0,0,1,0,0,0],[1,0,1,1,0,0,0],...] x_it - 从d_it到下一个1。 例如:df = [3763398,2029384,2976081,3269537,2698083,2519153,2415021] 如果d_0 = [1,0,0,1,0,0,0] 然后 x_00 = 3763398 + 2029384 + 2976081,x_03 = 3269537 + 2698083 + 2519153 + 2415021

from gurobipy import *
atm_frame = [[3763398, 2029384, 2976081, 3269537, 2698083, 2519153, 2415021],
             [0, 0, 2447076, 2653185, 2705684, 2836803, 2292156]]

N = 2
T = 7
d = {}
Q = 3
def calc_F(atm_frame):
    F = 0.1017/365
    amount = sum(atm_frame)
    result = 0
    for i in atm_frame:
        result += amount * F
        amount -= i
    return int(result)
#This function finds the window length to the next 1
#Input: atm_num - i, start - t
def find_window(atm_num, start):
    try:
        days = [d[atm_num,t].x for t in range(T)]
    except:
        days = [1, 0, 0, 0, 0, 0, 0]
    print(days)
    win_size = 0
    if start == T-1:
        return 0
    else:
        for i in range(start+1,T):
            if not days[i]:
                win_size += 1
            else:
                break
    return win_size

m = Model('ATM Optimize')

for i in range(N):
    for t in range(T):
        d[i,t] = m.addVar(obj=1, vtype=GRB.BINARY, name="d(%s,%s)" % (i,t))

m.addConstr(quicksum(d[i,t] for i in range(N) for t in range(T)) == Q)
m.update()

obj=quicksum(quicksum((calc_F(atm_frame[i][t:t+find_window(i,t)]))*d[i,t] for t in range(T)) for i in range(N))
m.setObjective(obj, GRB.MINIMIZE)
m.optimize() 

在第一次迭代中,变量没有值。我尝试使用try / except手动设置它,但是没有出现变量的值。输出:

[1, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0]
Optimize a model with 1 rows, 14 columns and 14 nonzeros
Variable types: 0 continuous, 14 integer (14 binary)
Coefficient statistics:
  Matrix range     [1e+00, 1e+00]
  Objective range  [7e+02, 2e+04]
  Bounds range     [1e+00, 1e+00]
  RHS range        [3e+00, 3e+00]
Found heuristic solution: objective 35468.000000
Presolve removed 0 rows and 1 columns
Presolve time: 0.00s
Presolved: 1 rows, 13 columns, 13 nonzeros
Variable types: 0 continuous, 13 integer (12 binary)

Root relaxation: objective 7.010000e+02, 1 iterations, 0.00 seconds

    Nodes    |    Current Node    |     Objective Bounds      |     Work
 Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time

*    0     0               0     701.0000000  701.00000  0.00%     -    0s

Explored 0 nodes (1 simplex iterations) in 0.02 seconds
Thread count was 8 (of 8 available processors)

Solution count 2: 701 35468 

Optimal solution found (tolerance 1.00e-04)
Best objective 7.010000000000e+02, best bound 7.010000000000e+02, gap 0.0000%
{(0, 0): <gurobi.Var d(0,0) (value -0.0)>, (0, 1): <gurobi.Var d(0,1) (value -0.0)>, (0, 2): <gurobi.Var d(0,2) (value -0.0)>, (0, 3): <gurobi.Var d(0,3) (value -0.0)>, (0, 4): <gurobi.Var d(0,4) (value -0.0)>, (0, 5): <gurobi.Var d(0,5) (value 1.0)>, (0, 6): <gurobi.Var d(0,6) (value 1.0)>, (1, 0): <gurobi.Var d(1,0) (value -0.0)>, (1, 1): <gurobi.Var d(1,1) (value -0.0)>, (1, 2): <gurobi.Var d(1,2) (value -0.0)>, (1, 3): <gurobi.Var d(1,3) (value -0.0)>, (1, 4): <gurobi.Var d(1,4) (value -0.0)>, (1, 5): <gurobi.Var d(1,5) (value -0.0)>, (1, 6): <gurobi.Var d(1,6) (value 1.0)>}

变量值的每次迭代都不会出现,但是在gurobi的末尾会设置一些随机值。是否有可能以另一种方式计算金额?

python-3.x optimization gurobi
3个回答
0
投票

看来你的d是空的???天= [d [atm_num,t] .x,范围(T)中的t]和x是什么?


0
投票

如果我理解你的问题,你可以像delow一样:

from gurobipy import *
atm_frame = [[3763398, 2029384, 2976081, 3269537, 2698083, 2519153, 2415021],
         [0, 0, 2447076, 2653185, 2705684, 2836803, 2292156]]
N = 2
T = 7
#d = {}
d = [[1, 0, 0, 1, 0, 0, 0], [1, 0, 1, 1, 0, 0, 1], [1, 0, 1, 0, 1, 0, 0],\
 [1, 0, 1, 1, 0, 0, 1], [1, 1, 0, 0, 0, 0, 0], [0, 1, 0, 1, 0, 0, 0], [0, 0, 1, 0, 1, 0, 1]]
Q = 3
def calc_F(atm_frame):
   F = 0.1017/365
   amount = sum(atm_frame)
   result = 0
   for i in atm_frame:
     result += amount * F
     amount -= i
   return int(result)
#This function finds the window length to the next 1
#Input: atm_num - i, start - t
def find_window(atm_num, start):
   try:
      days = [d[atm_num][t] for t in range(T)]
   except:
      days = [1, 0, 0, 0, 0, 0, 0]
   print(days)
   win_size = 0
   if start == T-1:
      return 0
   else:
      for i in range(start+1,T):
        if not days[i]:
            win_size += 1
        else:
            break
   return win_size
m = Model('ATM Optimize')

x={}
for i in range(N):
    for t in range(T):
        x[i,t] = m.addVar(vtype=GRB.BINARY, name="d(%s,%s)" % (i,t))
m.addConstr(quicksum(x[i,t] for i in range(N) for t in range(T)) == Q)
m.update()
obj=quicksum(quicksum((calc_F(atm_frame[i][t:t+find_window(i,t)]))*x[i,t] for t in range(T)) for i in range(N))
m.setObjective(obj, GRB.MINIMIZE)
m.optimize()

0
投票
 x={}
 for i in range(N):
      for t in range(T):
           x.update({(i,t): atm_frame[i][t]})

 obj=quicksum(quicksum(x[i,t]*d[i,t] for t in range(T)) for i in range(N))
 m.setObjective(obj, GRB.MINIMIZE)
 m.optimize()

 # this  will give you the result in dictionnary  
 if m.SolCount>0 or status == GRB.Status.OPTIMAL:
    sol_d=m.getAttr('x',d)
    D_d={}
    for i in range(N):
       for t in range(T):
          D_d.update({(i,t):sol_d[i,t]})
© www.soinside.com 2019 - 2024. All rights reserved.