この最適化問題の主な課題は、本質的に数学的です。
メソッドの定義から推測できるように、あなたの目標は、さまざまな変数 (など)gen_abc
の境界間隔を見つけることにより、検索スペースを削減することです$a
。$b
最良の戦略は、制約の完全なセットから可能な限り多くの線形制約を抽出し、(線形計画法の手法を使用して、以下を参照してください) 境界の推測を試みてから、完全な (または非決定論的な) 試行錯誤テストを実行することです。刈り込まれた変数空間。
典型的な線形計画問題は次の形式です。
minimize (maximize) <something>
subject to <constraints>
たとえば、3 つの変数 、a
、b
およびc
次の線形制約があるとします。
<<linear_constraints>>::
$a < $b
$b > $c
$a > 0
$c < 30
$a
、$b
およびの上限と下限は$c
次のように見つけることができます。
lower_bound_$a = minimize $a subject to <<linear_constraints>>
upper_bound_$a = maximize $a subject to <<linear_constraints>>
lower_bound_$b = minimize $b subject to <<linear_constraints>>
upper_bound_$b = maximize $b subject to <<linear_constraints>>
lower_bound_$c = minimize $c subject to <<linear_constraints>>
upper_bound_$c = maximize $c subject to <<linear_constraints>>
Perlでは、この目的のためにMath::LPを使用できます。
例
線形制約の形式は " C eqop C1×$V1 ± C2×$V2 ± C3×$V3 ...
" です。
eqop
<
、、、、>
のいずれか==
です>=
。<=
$V1
など$V2
は変数であり、
C
、などは定数でC1
、C2
0 に等しい可能性があります。
たとえば、与えられた...
$a < $b
$b > $c
$a > 0
$c < 30
...すべての変数 (およびその係数) を不等式の左側に移動し、唯一の定数を不等式の右側に移動します。
$a - $b < 0
$b - $c > 0
$a > 0
$c < 30
=
...そして、 、<=
および>=
(in)equals のみが使用されるように制約を調整します(変数に離散値、つまり整数値を想定):
- 「... < C」は「... <= C-1」になります
- 「... > C」は「... >= C+1」になります
...あれは、
$a - $b <= -1
$b - $c >= 1
$a >= 1
$c <= 29
...次に、次のように記述します。
use Math::LP qw(:types); # imports optimization types
use Math::LP::Constraint qw(:types); # imports constraint types
my $lp = new Math::LP;
my $a = new Math::LP::Variable(name => 'a');
my $b = new Math::LP::Variable(name => 'b');
my $c = new Math::LP::Variable(name => 'c');
my $constr1 = new Math::LP::Constraint(
lhs => make Math::LP::LinearCombination($a, 1, $b, -1), # 1*$a -1*$b
rhs => -1,
type => $LE,
);
$lp->add_constraint($constr1);
my $constr2 = new Math::LP::Constraint(
lhs => make Math::LP::LinearCombination($b, 1, $c, -1), # 1*$b -1*$c
rhs => 1,
type => $GE,
);
$lp->add_constraint($constr2);
...
my $obj_fn_a = make Math::LP::LinearCombination($a,1);
my $min_a = $lp->minimize_for($obj_fn_a);
my $max_a = $lp->maximize_for($obj_fn_a);
my $obj_fn_b = make Math::LP::LinearCombination($b,1);
my $min_b = $lp->minimize_for($obj_fn_b);
my $max_b = $lp->maximize_for($obj_fn_b);
...
# do exhaustive search over ranges for $a, $b, $c
もちろん、上記は任意の数の変数V1
, V2
, ... (例: $a
, $b
, $c
, $d
...) と任意の係数C1
, C2
, ... (例: -1, 1, 0, 123 など) に一般化できます。 ) および任意の定数値C
(例: -1、1、30、29 など) は、制約式を次のような対応する行列表現に解析できる場合に提供されます。
V1 V2 V3 C
[ C11 C12 C13 <=> C1 ]
[ C21 C22 C23 <=> C2 ]
[ C31 C32 C33 <=> C3 ]
... ... ... ... ... ...
あなたが提供した例に適用すると、
$a $b $c C
[ 1 -1 0 <= -1 ] <= plug this into a Constraint + LinearCombination
[ 0 1 -1 >= 1 ] <= plug this into a Constraint + LinearCombination
[ 1 0 0 >= 1 ] <= plug this into a Constraint + LinearCombination
[ 0 0 1 <= 29 ] <= plug this into a Constraint + LinearCombination
ノート
補足として、非決定論的 ( に基づく) テストを実行する場合、再テストを回避するために、どのタプルが既にテストされているrand
かを (たとえばハッシュで) 追跡することは良い考えかもしれませんし、そうでないかもしれません。そして次の場合のみ:($a,$b,$c)
- テストされているメソッドは、ハッシュ ルックアップよりもコストがかかります (これは、上記で提供したサンプル コードには当てはまりませんが、実際のコードでは問題になる場合とそうでない場合があります)
- ハッシュは膨大な割合に成長しません (すべての変数が有限の間隔で束縛され、その積が妥当な数になります。この場合、ハッシュ サイズをチェックすると、スペース全体を完全に探索したかどうかを示すことができます)、またはクリアすることができます。ハッシュは定期的に行われるため、少なくとも一度に 1 つの時間間隔で衝突検出が行われます。)
- 最終的に、上記が当てはまると思われる場合は、さまざまな実装オプション (ハッシュの有無にかかわらず) の時間を計り、実装する価値があるかどうかを確認できます。