2

私はスケジューリング モデルに取り組んでおり、この制約の使用方法を理解したいと考えています: Minizinc 2.0.2 バージョン & MinizincIDE-0.9.7-linux および G12-MIP & Gecode ソルバーを使用しています。

array[1..2,1..48] of var 0..1: table;
array[1..48] of int:demand;
array[1..2] of int: cost;
constraint forall(j in 1..48)(sum(i in 1..2)(table[i,j]) >= demand[j] );
solve minimize sum(i in 1..2)(sum(j in 1..48)(table[i,j])*cost[i]);
output [show(table)];

サンプル data.dzn ファイル:

demand=[0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
cost=[3,5];

G12-MIP ソルバーを使用した出力テーブル配列は、次の結果を示します。

[0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

このモデルは 2 ポイントと 48 時間 (つまり 2 日間) です。私が追加したい制約は、各従業員が割り当てられている場合、休憩なしで毎日シフトすることです。この目的の出力は次のとおりです。

[0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

私が試したアプローチ:

var 1..5: k;
array[1..2,1..2] of var 1..48: key2;
array[1..2,1..2] of var 1..48: key1;

% My aim is to store the first and last index for which table[i,j]=1 for each point (i) for each day (k)
constraint forall(i in 1..2,j in 1..48 where k= ceil(j/24))(if 
        table[i,j]==1 then key2[i,k]=j else true endif) 
         /\ forall(i in 1..2,j in 48..1 where k= ceil(j/24))(if 
        table[i,j]==1 then key1[i,k]=j else true endif);

% make all table[i,j]=1 between first index and last index for which table[i,j]=1
constraint forall(i in 1..2,k in 1..2)(forall(t in key1[i,k]..key2[i,k])(table[i,t]=1));   

次のコマンドを使用して Linux ターミナルから実行したところ、mzn-g12mip test.mzn data.dzn と同じ結果が得られました。MinizincIDE-0.9.7-linux で実行すると、次のエラーが発生しました。

MiniZinc: type error: type error in operator application for `..'. No matching operator found with left-hand side type `var int' and right-hand side type `var int'

このコードに問題はありますか、またはこの制約を満たす他の方法はありますか?

4

1 に答える 1

1

2 つの注意事項:

私はあなたと同じ結果を得ました.コマンドライン経由で実行するとうまくいきます. MiniZincIDE を使用しても同じエラーが発生しますが、MiniZincIDE.sh を実行するターミナルで MZN_STDLIB_DIR をリセットすると動作します。MZN_STDLIB_DIR を設定していますか? 次に、このコマンドでリセットしてみてください。

     export MZN_STDLIB_DIR=

シフト制約に関しては、おそらくグローバル制約「通常」を使用できます。例については、MiniZinc チュートリアルを参照してください。ここで必要な特定の制約は、すべての 1 が収集されることを要求する「隣接」制約です。MiniZinc には組み込まれていませんが、例として私のモデルを見ることができます: http://hakank.org/minizinc/contiguity_regular.mzn

これが、隣接性の定義を含む、あなたのモデルの私のバージョンです。

include "globals.mzn"; 

array[1..2,1..48] of var 0..1: table;
array[1..48] of int:demand;
array[1..2] of int: cost;

var int: z = sum(i in 1..2)(sum(j in 1..48)(table[i,j])*cost[i]);

constraint forall(j in 1..48)(sum(i in 1..2)(table[i,j]) >= demand[j] );

constraint
  forall(i in 1..2) (
    contiguity([table[i,j] | j in 1..48])
  )
;

predicate contiguity(array[int] of var int: a) =
  let {
        int: n_states = 3,
        int: input_max = 2,
        int: initial_state = 1,
        set of int: accepting_states = {1,2,3},
        % the transition matrix
        array[1..n_states, 1..input_max] of int: transition_fn =
    array2d(1..n_states, 1..input_max,
    [ 
      % note:all states are accepting states
      1,2, % state 1 (start): input 0 -> state 1, input 1 -> state 2 i.e. 0*
      3,2, % state 2: 1* 
      3,0, % state 3: 0* 
    ]),
      int: len = length(a),
      % note: regular cannot handle 0 values, it must be > 0
      array[1..len] of var 1..2: reg_input
  } in
   forall(i in 1..len) (
     reg_input[i] = a[i] + 1
   )
   /\
   regular(reg_input, n_states, input_max, transition_fn,
                    initial_state, accepting_states)
;


solve minimize z;

output [
  "table: ", show(table), "\n",
  "z: ", show(z), "\n",
]
++ ["\ntable:"] ++
[
  if j = 1 then "\n" else " " endif ++
    show(table[i,j])
  | i in 1..2, j in 1..48
]
;

demand=[0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
cost=[3,5];

このモデルを使用した最適なソリューションは、ユーザー 1 が必須タスク間のすべての「空の」タスクを実行する必要がある場合、需要のないタスクのコストがかかりすぎるため、ソリューションと同じではありません。このタスクの分離を許可しない他の制約がある場合は、これをモデルに追加する必要があります。

table:
0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
于 2015-06-05T06:29:43.460 に答える