我正在研究一個優化項目,並遇到一個小問題。對於我的項目,我使用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」約束)。你能指導我如何解決這個問題嗎?提前致謝。
如果使用平方差而不是絕對差值,它會返回一個解決方案嗎?我也不明白爲什麼你打擾使用約束,是不可能僅僅使用「在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
謝謝先生。使用建議的目標不起作用,所以我必須稍微修改它才能工作。在移動時,最大化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