Google Or-Tools在求解器之前操纵变量

发布于 2025-01-26 06:06:24 字数 2766 浏览 1 评论 0原文

我是Or-Tools的新手,我正在尝试通过12个变量解决一个优化问题(我知道受虐狂)。

每个变量表示每个人(2中的2分)应在特定设备模型上(2分)(3中的2分)工作。新设备每天到达,几天前积压的设备都会到达。每个设备需要在到达后的2天内处理。

基本上,我想最大限度地提高设备总数后2天内进行处理的设备的比例(其中一些设备需要花费2天以上,因为没有足够的人员和时间)。

我有一张这样的表,显示哪个设备模型到达时(天-2)意味着它在昨天的前一天到达,0今天):

    item    arrival day
0   ITEM 1  -2
1   ITEM 1  -2
2   ITEM 1  -2
3   ITEM 1  -2
18  ITEM 1  2
17  ITEM 1  1
16  ITEM 1  1
14  ITEM 1  0
...

我的目标是工作算出每个设备需要处理多少天,所以我想在此表中添加一列,该列显示该项目的处理,然后另一个列显示了花费了多少天(“年龄”)这花费了2天以上:

    item    arrival day  processed date  age  success (within 2 days)?
0   ITEM 1  -2               0            2           1
1   ITEM 1  -2               0            2           1
2   ITEM 1  -2               1            3           0
3   ITEM 1  -2               2            4           0
18  ITEM 1  2                2            0           1
17  ITEM 1  1                2            1           1
16  ITEM 1  1                2            1           1
14  ITEM 1  0                1            1           1

在此示例中,有6个设备在总共2天内进行了处理,因此成功率为6/8。我想最大化这个成功率。

我不知道如何在“或者”中为此创建目标函数。我试图将该表重新创建为数据框架,然后将目标函数作为最后一列中的总和,但是处理的日期列取决于优化模型中的变量,因此我可以't在求解模型之前创建此表。

我尝试了此(其中a10,b10,a11,b11,a12,b12是我的变量,s1a,s1b是常数)。 什么不起作用:

# define variables
a10 = model.NewIntVar(0, 8, 'a10')
a11 = model.NewIntVar(0, 8, 'a11')
a12 = model.NewIntVar(0, 8, 'a12')
b10 = model.NewIntVar(0, 8, 'b10')
b11 = model.NewIntVar(0, 8, 'b11')
b12 = model.NewIntVar(0, 8, 'b12')

# to create the dataframe with `item` and `arrival day` columns
total_demand = [backlog, incoming]
total_demand = pd.concat(total_demand, ignore_index=True)
total_demand = total_demand.sort_values('item')


# then an attempt to create the `processed date` column
item1_repair_day = []
count = 0

for i in range(0, (a10*s1a + b10*s1b + a11*s1a + b11*s1b + a12*s1a + b12*s1b)):
    if a10*s1a + b10*s1b > count:
        item1_repair_day.append(0)
        count += 1
    else:
        if a11*s1a + b11*s1b > count:
            item1_repair_day.append(1)
            count += 1
        else:
            if a12*s1a + b12*s1b > count:
                item1_repair_day.append(2)
                count += 1
            else:
                print("No item 1's were processed on Day 0, Day 1, and Day 2")

total_demand['repair day'] = item1_repair_day

我可以从那里算出age成功从那里获得目标功能,但是上面的代码不起作用。

我想要的目标

objective_function = total_demand['success'].sum()

model.Maximize(objective_function)

solver = cp_model.CpSolver()
status = solver.Solve(model)

I am new to OR-Tools and I am trying to solve an optimisation problem with 12 variables (masochism, I know).

Each variable represents how much time each person (out of 2) should work on a particular device model (out of 2) each day (out of 3). New devices arrive each day and there are many devices in the backlog that arrived several days ago. Each device needs to be processed within 2 days of arrival.

Basically, I want to maximise the proportion of devices that get processed within 2 days of arrival out of the total number of devices (some of them take more than 2 days because there are not enough people and time).

I have a table like this that shows which device model arrives when (day -2 means it arrived the day before yesterday, day 0 is today):

    item    arrival day
0   ITEM 1  -2
1   ITEM 1  -2
2   ITEM 1  -2
3   ITEM 1  -2
18  ITEM 1  2
17  ITEM 1  1
16  ITEM 1  1
14  ITEM 1  0
...

My goal is to work out how many days each device takes to be processed, so I want to add a column to this table that shows on which day that item gets processed, then another column showing how many days that took ('age'), then another showing if it took more than 2 days:

    item    arrival day  processed date  age  success (within 2 days)?
0   ITEM 1  -2               0            2           1
1   ITEM 1  -2               0            2           1
2   ITEM 1  -2               1            3           0
3   ITEM 1  -2               2            4           0
18  ITEM 1  2                2            0           1
17  ITEM 1  1                2            1           1
16  ITEM 1  1                2            1           1
14  ITEM 1  0                1            1           1

In this example there are 6 devices that were processed within 2 days out of 8 total, so the success rate is 6/8. I want to maximise this success rate.

I don't know how to create the objective function for this in OR-Tools. I tried to recreate this table as a dataframe and then have the objective function as the sum of the 1's in the last column, but the processed date column depends on the variables in the optimisation model, so I can't create this table before the model is solved.

I tried this (where a10, b10, a11, b11, a12, b12 are my variables and s1a, s1b are constants). What doesn't work:

# define variables
a10 = model.NewIntVar(0, 8, 'a10')
a11 = model.NewIntVar(0, 8, 'a11')
a12 = model.NewIntVar(0, 8, 'a12')
b10 = model.NewIntVar(0, 8, 'b10')
b11 = model.NewIntVar(0, 8, 'b11')
b12 = model.NewIntVar(0, 8, 'b12')

# to create the dataframe with `item` and `arrival day` columns
total_demand = [backlog, incoming]
total_demand = pd.concat(total_demand, ignore_index=True)
total_demand = total_demand.sort_values('item')


# then an attempt to create the `processed date` column
item1_repair_day = []
count = 0

for i in range(0, (a10*s1a + b10*s1b + a11*s1a + b11*s1b + a12*s1a + b12*s1b)):
    if a10*s1a + b10*s1b > count:
        item1_repair_day.append(0)
        count += 1
    else:
        if a11*s1a + b11*s1b > count:
            item1_repair_day.append(1)
            count += 1
        else:
            if a12*s1a + b12*s1b > count:
                item1_repair_day.append(2)
                count += 1
            else:
                print("No item 1's were processed on Day 0, Day 1, and Day 2")

total_demand['repair day'] = item1_repair_day

I could then work out the age and success columns from there and get the objective function, but the code above doesn't work.

What I want as my objective function

objective_function = total_demand['success'].sum()

model.Maximize(objective_function)

solver = cp_model.CpSolver()
status = solver.Solve(model)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

屋檐 2025-02-02 06:06:24

这没有任何意义:

for i in range(0, (a10*s1a + b10*s1b + a11*s1a + b11*s1b + a12*s1a + b12*s1b)):

a10是一个变量。 A10 * S1A是线性表达式。它不会评估为范围表达式的数字。

您应该查看基本的CP-SAT示例,以了解如何访问求解后分配给变量的值。

this makes no sense:

for i in range(0, (a10*s1a + b10*s1b + a11*s1a + b11*s1b + a12*s1a + b12*s1b)):

a10 is a variable. a10 * s1a is a linear expression. It does not evaluate as a number for the range expression.

You should look at basic CP-SAT example to understand how to access the value assigned to the variables after the solve.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文