【Bus Scheduling的代码注意事项】

子问题的建模

        """ add conflict decision variables """
        for key in schedule_pool.keys():

            self.SP_included_schedules[key] = schedule_pool[key]

            var_alpha_name = 'alpha|' + str(key)
            alpha[var_alpha_name] = self.SP_forward.addVar(lb=0, ub=0, vtype=GRB.BINARY, name=var_alpha_name)
            for j in range(max_departure_num): # 已经生成的 schedule 的 time
                for i in range(max_departure_num): # 决策出来的 schedule 的 time
                    var_rho_name = 'rho|x_' + str(i) + '|' + str(key) + '|t_' + str(j)
                    rho[var_rho_name] = self.SP_forward.addVar(lb=0, ub=0, vtype=GRB.BINARY, name=var_rho_name)

                    var_time_diff_name = 'var_diff|x_' + str(i) + '|' + str(key) + '|t_' + str(j)
                    var_time_diff[var_time_diff_name] = self.SP_forward.addVar(lb=100, ub=100, vtype=GRB.CONTINUOUS, name=var_time_diff_name)

                    abs_var_time_diff_name = 'var_abs_diff|x_' + str(i) + '|' + str(key) + '|t_' + str(j)
                    abs_var_time_diff[abs_var_time_diff_name] = self.SP_forward.addVar(lb=100, ub=100, vtype=GRB.CONTINUOUS, name=abs_var_time_diff_name)

这里,由于一些变量是没用到的,所以我们将其设置为0或者设置为很大的值,这样才会保证正确,否则就会等于0导致误判。

这里我们将

  • var_time_diff
  • abs_var_time_diff
    的上下界全部设置为100,因为后面有一些是没有用到的,因此这么设置就会保证不出问题,否则会出问题。

就像下面的

在这里插入图片描述

很多都会等于0,但是实际上是因为他们根本就没参与到模型中,就默认取0了。这就会导致错误。

改正过去以后,就对了。

在这里插入图片描述

然后我们在之后的代码中,用一个,我们就修改一个的lb和ub

                    for i in index_odd:  # [1, 3, 5]
                        # 提取表示 x_i - t_r^j 的变量
                        var_time_diff_name = 'var_diff|x_' + str(i) + '|' + str(schedule_name) + '|t_' + str(j)
                        var_time_diff = self.SP_backward.getVarByName(var_time_diff_name)
                        var_time_diff.lb = -1400
                        var_time_diff.ub = 1400
                        # 提取 x_i
                        var_x_i = self.SP_backward.getVarByName('x_' + str(i))
                        con_name = 'schedule_conflict_var_diff_' + str(schedule_name)
                        # 提取 t_r^j
                        departure_time_j = current_schedule[j]

                        # add diff constraints
                        self.SP_backward.addConstr(var_time_diff == var_x_i - departure_time_j, name=con_name)

                        # add abs diff constraints
                        abs_var_time_diff_name = 'var_abs_diff|x_' + str(i) + '|' + str(schedule_name) + '|t_' + str(j)
                        abs_var_time_diff = self.SP_backward.getVarByName(abs_var_time_diff_name)
                        abs_var_time_diff.lb = 0
                        abs_var_time_diff.ub = 1400
                        con_name_abs = 'schedule_conflict_var_diff_abs_' + str(schedule_name)
                        self.SP_backward.addGenConstrAbs(abs_var_time_diff, var_time_diff, name=con_name_abs)
 backward产生的schedule:[391.0 	523.0 	630.0 	731.0 	832.0 	969.0 	]
与之冲突的schedule:

y_1_f: [367, 524, 690, 810, 969, 1117]
y_2_f: [374, 546, 704, 832, 984, 1137]
y_4_f: [388, 590, 732, 876, 1040, 1184.0]
y_10_f: [415, 629, 992, 1166.0]
y_26_f: [522, 1077]
y_0_b: [390, 536, 689, 819, 993, 1170]

这就完全正确了。

在这里插入图片描述

第二个问题,update_RMP的错误

没更新前

在这里插入图片描述

 headway_|y_0_f: y_0_f <= 1
 headway_|y_1_f: y_1_f <= 1
 headway_|y_2_f: y_2_f <= 1
 headway_|y_3_f: y_3_f <= 1
 headway_|y_4_f: y_4_f <= 1
 headway_|y_5_f: y_5_f <= 1
 headway_|y_6_f: y_6_f <= 1
 headway_|y_7_f: y_7_f <= 1
 headway_|y_8_f: y_8_f <= 1
 headway_|y_9_f: y_9_f <= 1
 headway_|y_10_f: y_10_f <= 1
 headway_|y_11_f: y_11_f <= 1
 headway_|y_12_f: y_12_f <= 1
 headway_|y_13_f: y_13_f <= 1
 headway_|y_14_f: y_14_f <= 1
 headway_|y_15_f: y_15_f <= 1
 headway_|y_16_f: y_16_f <= 1
 headway_|y_17_f: y_17_f <= 1
 headway_|y_18_f: y_18_f <= 1
 headway_|y_19_f: y_19_f <= 1
 headway_|y_20_f: y_20_f <= 1
 headway_|y_21_f: y_21_f <= 1
 headway_|y_22_f: y_22_f <= 1
 headway_|y_23_f: y_23_f <= 1
 headway_|y_24_f: y_24_f <= 1
 headway_|y_25_f: y_25_f <= 1
 headway_|y_26_f: y_26_f <= 1
 headway_|y_0_b: y_0_b <= 1
 headway_|y_1_b: y_1_b <= 1
 headway_|y_2_b: y_2_b <= 1
 headway_|y_3_b: y_3_b <= 1
 headway_|y_4_b: y_4_b <= 1
 headway_|y_5_b: y_5_b <= 1
 headway_|y_6_b: y_6_b <= 1
 headway_|y_7_b: y_7_b <= 1
 headway_|y_8_b: y_8_b <= 1
 headway_|y_9_b: y_9_b <= 1

两个子问题个生成了一列,变量名为

  • y_BnP_0_cg_1_b
  • y_BnP_0_cg_1_f

加入后变成了

 headway_|y_0_f: y_0_f <= 1
 headway_|y_1_f: y_1_f + y_BnP_0_cg_1_f + y_BnP_0_cg_1_b <= 1
 headway_|y_2_f: y_2_f + y_BnP_0_cg_1_f + y_BnP_0_cg_1_b <= 1
 headway_|y_3_f: y_3_f <= 1
 headway_|y_4_f: y_4_f + y_BnP_0_cg_1_f + y_BnP_0_cg_1_b <= 1
 headway_|y_5_f: y_5_f + y_BnP_0_cg_1_f <= 1
 headway_|y_6_f: y_6_f <= 1
 headway_|y_7_f: y_7_f <= 1
 headway_|y_8_f: y_8_f <= 1
 headway_|y_9_f: y_9_f <= 1
 headway_|y_10_f: y_10_f + y_BnP_0_cg_1_b <= 1
 headway_|y_11_f: y_11_f <= 1
 headway_|y_12_f: y_12_f <= 1
 headway_|y_13_f: y_13_f <= 1
 headway_|y_14_f: y_14_f <= 1
 headway_|y_15_f: y_15_f <= 1
 headway_|y_16_f: y_16_f <= 1
 headway_|y_17_f: y_17_f + y_BnP_0_cg_1_f <= 1
 headway_|y_18_f: y_18_f <= 1
 headway_|y_19_f: y_19_f + y_BnP_0_cg_1_f <= 1
 headway_|y_20_f: y_20_f <= 1
 headway_|y_21_f: y_21_f <= 1
 headway_|y_22_f: y_22_f <= 1
 headway_|y_23_f: y_23_f <= 1
 headway_|y_24_f: y_24_f + y_BnP_0_cg_1_f <= 1
 headway_|y_25_f: y_25_f <= 1
 headway_|y_26_f: y_26_f + y_BnP_0_cg_1_b <= 1
 headway_|y_0_b: y_0_b <= 1
 headway_|y_1_b: y_1_b + y_BnP_0_cg_1_b <= 1
 headway_|y_2_b: y_2_b <= 1
 headway_|y_3_b: y_3_b <= 1
 headway_|y_4_b: y_4_b <= 1
 headway_|y_5_b: y_5_b <= 1
 headway_|y_6_b: y_6_b <= 1
 headway_|y_7_b: y_7_b <= 1
 headway_|y_8_b: y_8_b <= 1
 headway_|y_9_b: y_9_b <= 1
 headway_|y_BnP_0_cg_1_f: y_1_f + y_2_f + y_4_f + y_5_f + y_17_f + y_19_f
   + y_24_f + y_BnP_0_cg_1_f <= 1
 headway_|y_BnP_0_cg_1_b: y_1_f + y_2_f + y_4_f + y_10_f + y_26_f + y_1_b
   + y_BnP_0_cg_1_b <= 1

前面的约束没问题,但是就是约束

  • headway_|y_BnP_0_cg_1_f:
  • headway_|y_BnP_0_cg_1_b:
    出问题了,只能说, headway_|y_BnP_0_cg_1_b:分别与其余的约束不能相容,但是不能说跟所有的都不相容。人家其余的两个本来可以都选,我们全部加到一个约束中,这样其他的不能被同时选了,这样就是错误的。

因此,一个约束,最多只能包含2个schedule。

下面是错误的版本

        """ Constraint 2: if two schedules form a blocking schedule pair, then add a constraint """
        for var_name_A in self.schedule_pool.keys():

            con_name_headway = 'headway_|' + str(var_name_A)
            vay_y_A = self.RMP.getVarByName(var_name_A)
            lhs = LinExpr()
            lhs.addTerms(1, vay_y_A)

            for var_name_B in self.schedule_pool.keys():
                if(var_name_A != var_name_B):
                    schedule_A = self.schedule_pool[var_name_A]
                    schedule_B = self.schedule_pool[var_name_B]

                    direction_A = ''
                    direction_B = ''
                    if (var_name_A.endswith('f')):
                        direction_A = 'f'
                    else:
                        direction_A = 'b'

                    if (var_name_B.endswith('f')):
                        direction_B = 'f'
                    else:
                        direction_B = 'b'

                    is_blocking_schedule_pair = self.check_is_blocking_schedule_pair(schedule_A=schedule_A,
                                                                                     schedule_B=schedule_B,
                                                                                     direction_A=direction_A,
                                                                                     direction_B=direction_B,
                                                                                     min_forward_interval=self.min_forward_interval,
                                                                                     min_backward_interval=self.min_backward_interval)

                    if(is_blocking_schedule_pair == True):
                        # get var by name
                        # vay_y_A = self.RMP.getVarByName(var_name_A)
                        vay_y_B = self.RMP.getVarByName(var_name_B)

                        lhs.addTerms(1, vay_y_B)

                        # _ = self.RMP.addConstr(vay_y_A + vay_y_B <= 1, name=con_name_headway)
                        #
                        # constraint_added = True
                        #
                        # break

            _ = self.RMP.addConstr(lhs <= 1, name=con_name_headway)

上面这个版本是错误的。

错误3:添加主问题的blocking schedule的时候出错

虽然只能一行2个,但是需要互不重叠才行。

我之前的的处理方法:

                    is_blocking_schedule_pair = self.check_is_blocking_schedule_pair(schedule_A=schedule_A,
                                                                                     schedule_B=schedule_B,
                                                                                     direction_A=direction_A,
                                                                                     direction_B=direction_B,
                                                                                     min_forward_interval=self.min_forward_interval,
                                                                                     min_backward_interval=self.min_backward_interval)

                    if(is_blocking_schedule_pair == True):
                        # get var by name
                        vay_y_B = self.RMP.getVarByName(var_name_B)

                        con_name_headway = 'headway_|' + str(var_name_A) + '|' + str(var_name_B)

                        _ = self.RMP.addConstr(vay_y_A + vay_y_B <= 1, name=con_name_headway)

                        break

这样是不行的,这样会导致:

各个约束一直都是添加第一个blocking的,其余的blocking的并没有加进来。

导致后面这样的结果

y_6_b = 1.0, 	 | schedule: [450, 620, 731, 909, 1042, 1217.0]
y_BnP_0_cg_2_f = 1.0, 	 | schedule: [360.0, 480.0, 608.0, 703.0, 821.0, 1070.0]
y_BnP_0_cg_9_f = 1.0, 	 | schedule: [394.0, 517.0, 633.0, 725.0, 833.0, 1076.0]
y_BnP_0_cg_11_f = 1.0, 	 | schedule: [392.0, 515.0, 650.0, 741.0, 866.0, 1018.0]
y_BnP_0_cg_13_f = 1.0, 	 | schedule: [393.0, 516.0, 628.0, 720.0, 823.0, 995.0]
y_BnP_0_cg_14_f = 1.0, 	 | schedule: [393.0, 516.0, 628.0, 720.0, 823.0, 995.0]
y_BnP_0_cg_17_f = 1.0, 	 | schedule: [360.0, 480.0, 606.0, 830.0, 992.0, 1170.0]
y_BnP_0_cg_18_f = 1.0, 	 | schedule: [360.0, 480.0, 720.0, 992.0, 1211.0, 1319.0]
y_BnP_0_cg_19_f = 1.0, 	 | schedule: [360.0, 480.0, 630.0, 722.0, 824.0, 1080.0]
y_BnP_0_cg_20_f = 1.0, 	 | schedule: [360.0, 480.0, 630.0, 722.0, 824.0, 1080.0]
y_BnP_0_cg_22_f = 1.0, 	 | schedule: [396.0, 518.0, 630.0, 733.0, 1219.0, 1320.0]
y_BnP_0_cg_24_f = 1.0, 	 | schedule: [392.0, 515.0, 630.0, 727.0, 1080.0, 1299.0]
y_BnP_0_cg_25_f = 1.0, 	 | schedule: [392.0, 515.0, 630.0, 727.0, 1080.0, 1299.0]
y_BnP_0_cg_26_f = 1.0, 	 | schedule: [392.0, 515.0, 630.0, 727.0, 1080.0, 1299.0]

例如

A, B, C,D

冲突。

遍历A, A和B冲突,我就加入约束
x A + x B ⩽ 1 x_A + x_B \leqslant 1 xA+xB1
然后break

遍历B, B和A冲突,我就加入约束
x A + x B ⩽ 1 x_A + x_B \leqslant 1 xA+xB1
然后break

遍历C, C和A冲突,我就加入约束
x A + x C ⩽ 1 x_A + x_C \leqslant 1 xA+xC1
然后break

这样不行,还是应该遍历所有的pair,全部添加。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值