data_placement.py 中使用pyomo建模时的一个约束问题
- Dominant language
- C++
- Stars
- 10.2k
- Forks
- 1.1k
- PR merge metrics
- No merged PRs in 30d
Description
#### 问题复现
首先按照 README 中提供的参数,执行 data_placement.py 生成一个解:
```
-ql -relax -type CR -v 5 -min_r 6 -k 3 -j 1
```
再对这个解添加一个节点,尝试利用 RebalanceTrafficModel 生成一个新的解:
```
-ql -relax -type CR -v 6 -min_r 6 -k 3 -j 1 -m output\DataPlacementModel-v_5-b_10-r_6-k_3-λ_2-lb_1-ub_1\incidence_matrix.pickle
```
此时 check_solution 报错:
```
AssertionError: peer_traffic=0.5 < self.max_recovery_traffic_on_peer=2 - 1
```
#### 原因分析
在 chain_table_type="CR" 时 λ(也即 max_recovery_traffic_on_peer)被定义为 r / (v - 1),这与 BIBD 中的 λ = r * (k-1) / (v-1) 不同(为什么要这样定义?)。在 pyomo建立模型时,对于 peer_recovery_traffic 的计算相当于 λ 在 BIBD 中的定义,而其上下限约束则使用了 r / (v - 1) 这个定义,因此提供的约束条件会与预期不符。我不确定这是 bug 还是我错误理解,但我尝试修改了代码以使得约束与预期一致。如果确为 bug 我再提 PR。
#### 修改约束
```
#修改前
def peer_recovery_traffic_upper_bound(model, disk, peer):
if self.balanced_incomplete_block_design:
return calc_peer_recovery_traffic(model, disk, peer) == self.max_recovery_traffic_on_peer
else:
return calc_peer_recovery_traffic(model, disk, peer) <= self.max_recovery_traffic_on_peer + self.relax_ub
model.peer_recovery_traffic_upper_bound_eqn = po.Constraint(model.disk_pairs, rule=peer_recovery_traffic_upper_bound)
def peer_recovery_traffic_lower_bound(model, disk, peer):
return calc_peer_recovery_traffic(model, disk, peer) >= max(0, self.max_recovery_traffic_on_peer - self.relax_lb)
# 修改后
def peer_recovery_traffic_upper_bound(model, disk, peer):
if self.balanced_incomplete_block_design:
return calc_peer_recovery_traffic(model, disk, peer) == self.max_recovery_traffic_on_peer / self.recovery_traffic_factor * (self.group_size - 1)
else:
return calc_peer_recovery_traffic(model, disk, peer) <= (self.max_recovery_traffic_on_peer + self.relax_ub) / self.recovery_traffic_factor * (self.group_size - 1)
model.peer_recovery_traffic_upper_bound_eqn = po.Constraint(model.disk_pairs, rule=peer_recovery_traffic_upper_bound)
def peer_recovery_traffic_lower_bound(model, disk, peer):
return calc_peer_recovery_traffic(model, disk, peer) >= max(0, self.max_recovery_traffic_on_peer - self.relax_lb) / self.recovery_traffic_factor * (self.group_size - 1)
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.