在AMPL中为约束索引添加边界

时间:2017-11-03 10:24:08

标签: optimization ampl

我正在尝试解决国际象棋棋盘优化问题,我的一个约束条件检查附近的小区是否被占用:

subject to attack_each_cell {i in 1..n,j in 1..n}:

    P[i,j]+P[i-1,j+2]+P[i-1,j-2]+P[i+1,j+2]+P[i+1,j-2]+P[i-2,j+1]+P[i-2,j-1]+P[i+2,j+1]+P[i+2,j-1]>=1

上面约束的问题是对于边框单元格我得到一个越界错误,所以我的第二种方法是对(i,j)索引的if-else语句:

P[i,j]
+ if i>1   and j<n-2 then P[i-1,j+2] 
+ if i>1   and j>2   then P[i-1,j-2] 
+ if i<n-1 and j<n-2 then P[i+1,j+2] 
+ if i<n-1 and j>2   then P[i+1,j-2] 
+ if i>2   and j<n-1 then P[i-2,j+1] 
+ if i>2   and j>1   then P[i-2,j-1] 
+ if i<n-2 and j<n-1 then P[i+2,j+1] 
+ if i<n-2 and j>1   then P[i+2,j-1]
>=1

这不起作用,因为它看起来是嵌套而不是按顺序执行。有关如何修复代码的任何建议?

1 个答案:

答案 0 :(得分:0)

选项1:添加括号以修复评估顺序。

选项2:重新制定约束条件。不是检查相对于参考单元的骑士移动位置,然后必须处理越界情况,检查棋盘上的所有位置并接受骑士从参考单元移动的位置:

.father {
  flex-grow: 1;              /*  needed to take full width being a flex row item  */
  
  display: flex;
  flex-wrap: wrap;
  align-content: flex-end;
  align-items: center;
  justify-content: space-around;
}

.child {
  border: 1px solid #fff;
  padding: 5px;
  color: white;
}

.bx-1 {
  background: #e51400;
}

.bx-2 {
  background: #fa6800;
}

.bx-3 {
  background: #f0a30a;
}

.bx-4 {
  background: #e3c800;
}

.bx-5 {
  background: #a4c400;
}

.bx-6 {
  background: #60a917;
}

.bx-7 {
  background: #00aba9;
}

.bx-8 {
  background: #1ba1e2;
}

.bx-9 {
  background: #aa00ff;
}

选项3:如上所述,但首先创建一个定义合法移动的集合,然后通过引用该集合来定义约束:

<div class="" style="display: flex; width: 100%; height: 300px; background-color: darkorange">
  <div class="father">
    <div class="child bx-1">Bella</div>
    <div class="child bx-2">Bella</div>
    <div class="child bx-3">Bella</div>
    <div class="child bx-4">Bella</div>
    <div class="child bx-5" style="height: 80px;">Bella</div>
    <div class="child bx-6">Bella</div>
    <div class="child bx-7">Bella</div>
    <div class="child bx-8">Bella</div>
    <div class="child bx-9">Bella</div>
    <div class="child bx-10">Bella</div>
  </div>
</div>

我最喜欢#3,因为它将“骑士如何移动”的逻辑从约束中分离出来“任何不包含骑士的细胞都必须受到骑士的威胁”。这使得定制更容易,例如如果你需要解决不同类型的问题,它可以很好地扩展到多种类型的问题:

subject to attack_each_cell {i in 1..n,j in 1..n}: 
  P[i,j] 
+ sum{i1 in 1..n, j1 in 1..n: abs(i-i1) = 2 and abs(j-j1) = 1} P[i1,j1]
+ sum{i1 in 1..n, j1 in 1..n: abs(i-i1) = 1 and abs(j-j1) = 2} P[i1,j1]
>= 1;

(编辑:好吧,如果你忽略了被他人阻止的非跳跃部分的问题,它就会这样做。)