在這個優化問題的主要挑戰是在自然界中的數學。
你的目標,我可以從你的gen_abc
方法的定義中推斷出來,是通過找到各種變量的邊界間隔來修剪你的搜索空間($a
,$b
等)。)
最好的策略是從你的全套約束提取儘可能多的線性約束,試圖推斷出界(使用linear programming技術,見下文),然後用詳盡的(或不確定性繼續)審訊中─對修剪的變量空間進行錯誤檢測。
典型linear programming problem是以下形式:
minimize (maximize) <something>
subject to <constraints>
例如,給定三個變量,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
...和調整的限制,使得僅=
,<=
和>=
(在)等式被使用(對於我們的變量假定離散即整數值):
- '... < 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)
元組都已經被測試,以避免再次測試它們的散列),當且僅當:
- 被測試的方法比的哈希查找更昂貴的(不是這種情況用上面提供的示例代碼,但可能會或可能不會成爲您的真實代碼的問題)
- 散列不會增長到很大比例(要麼所有變量都受有限時間間隔限制,其產品是合理的數量 - 哪種情況下檢查散列大小可以指示您是否已經完全探究整個空間 - 或者您可以定期清除散列,所以至少在一段時間內你有一些碰撞檢測)
- 最終,如果您認爲上述內容可以適用於您,則可以使用各種實現選項(包含和不包含散列)並查看是否值得實施。
這個問題的主要挑戰是數學性質。您的目標是通過查找諸如$ a,$ c等值的值間隔來修剪搜索空間,然後計算諸如$ c之類的因變量的邊界間隔。 – vladr 2009-02-22 20:29:21