子问题的建模
""" 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):
for i in range(max_departure_num):
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:
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
var_x_i = self.SP_backward.getVarByName('x_' + str(i))
con_name = 'schedule_conflict_var_diff_' + str(schedule_name)
departure_time_j = current_schedule[j]
self.SP_backward.addConstr(var_time_diff == var_x_i - departure_time_j, name=con_name)
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):
vay_y_B = self.RMP.getVarByName(var_name_B)
lhs.addTerms(1, vay_y_B)
_ = 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):
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?+xB??1 然后break
遍历B, B和A冲突,我就加入约束
x
A
+
x
B
?
1
x_A + x_B \leqslant 1
xA?+xB??1 然后break
遍历C, C和A冲突,我就加入约束
x
A
+
x
C
?
1
x_A + x_C \leqslant 1
xA?+xC??1 然后break
这样不行,还是应该遍历所有的pair,全部添加。
|