1

我正在研究一個優化項目,並遇到一個小問題。對於我的項目,我使用AMPL和CPLEX作爲求解器。在我的代碼中,我有一些由e1,e2,...,en表示的元素。我也有一個包含這些元素內的元組的集合。我必須給每個元素分配一個1到'n'之間的數字,這樣我可以最大化moveTuples集中1個元組中每2個元素之間的距離(我需要對它們進行排序,但試圖保持同一元組中元素之間的距離) 。使用cplex的AMPL非二次非線性約束

每個元素必須只有1個分配號碼,每個號碼只能給1個元素。爲此,我寫了下面的代碼:

set Elements; 
set moveTuples dimen 2; 
set Numbers; 

var assign {Elements,Numbers} binary; 
var maximizer{moveTuples} integer >= 0; 

maximize obj: sum {(A,B) in moveTuples} maximizer[A,B]; 

subject to assign1NumberPerElement {i in Element}: sum {c in Numbers} assign[i,c] = 1; 
subject to assign1ElementPerNumber {c in Numbers}: sum {i in Element} assign[i,c] = 1; 


subject to moveApart {(A,B) in moveTuples}: abs(sum{i in Numbers}(assign[A,i]*i) - (sum{j in Numbers}x[B,j]*j)) - maximizer[A,B] = 0 ; 

data; 

set Elements:= e1 e2 e3; 
set Numbers:= 1 2 3; 
set moveTuples: e1 e2 e3:= 
(e1, e2); 


solve; 

display assign; 

現在的問題是明確的,對於前面的例子中,輸出必須是:

E1 - > 1

E2 - > 3

E3 - > 2

E1 - > 3

E2 - > 1

E3 - > 2

,因爲它需要僅E1 E2從使用所述元組移動(E1,E2)。運行前面的代碼時,我得到錯誤:...包含非二次非線性約束(絕對是「moveApart」約束)。你能指導我如何解決這個問題嗎?提前致謝。

+0

如果使用平方差而不是絕對差值,它會返回一個解決方案嗎?我也不明白爲什麼你打擾使用約束,是不可能僅僅使用「在MoveTuples中使用」最大化obj:sum {(A,B)} abs(sum {數組中的我}(assign [A,i] * i ) - (sum {j in Numbers} x [B,j] * j));「 (或相應的平方差目標函數)? – 2014-11-23 21:34:06

+0

謝謝先生。使用建議的目標不起作用,所以我必須稍微修改它才能工作。在移動時,最大化obj:sum {(A,B),Numbers中的i,i中的數字:i!= j}(assign [B,j] * assign [A,i] * num(i) - assign [A ,I] *分配[B,J] * NUM(J));'。唯一的問題是假設元組是(e1,e2),(e3,e4),(e2,e5)。現在的目標是6,它是正確的,但正確的順序必須是(e1,e3,e2,e4,e5),所以同一元組中沒有2個元素會相互跟隨,目標將保持爲6. AMPL生成序列(e5,e4,e2,e1,e3)==> obj = 6,但e1和e2是連續的。 – user3787524 2014-11-23 22:01:16

回答

0

約束moveApart是非線性的(和非二次的),因爲它包含對abs的調用。但是,由於你的問題是純粹的整數,你可以用CPLEX CP Optimizer (ilogcp)來解決它。