整数線形計画法


21

前書き

整数線形計画法のソルバーを記述します

チャレンジ

あなたの仕事は整数線形計画法(ILP)のソルバーを書くことです。ILPでは、一連の未知数(すべて整数)の線形不等式が与えられ、目標は線形関数の最小または最大を見つけることです。

たとえば、不等式の場合(混合整数線形計画法からの例)

 4x+2y-15≤0
  x+2y- 8≤0
  x+ y- 5≤0
- x      ≤0
   - y   ≤0

目的関数3x+2y、目的関数の最大値は12x=2,y=3)で、最小値は0x=y=0)でなければなりません。

入力は2D配列(または標準仕様に準拠する任意の同等物)として与えられ、各行は最終行を除く1つの不等式に対応します。配列内の数字は係数であり、その≤0部分は常に省略されます。n各行に要素がある場合、n-1未知の要素があることを意味します。

配列の最後の行は、線形関数に対応しています。係数がリストされます。

たとえば、上記の問題の入力配列は次のとおりです。

[[4,2,-15],[1,2,-8],[1,1,-5],[-1,0,0],[0,-1,0],[3,2,0]].

出力は、適切な形式で指定された最小値と最大値である必要があります。

次の問題の場合(上記の問題から2つの制限が取り除かれます):

[[4,2,-15],[1,2,-8],[1,1,-5],[3,2,0]].

最大値はまだ12ですが、最小値は存在せず、目的関数は任意の大きな(絶対値の意味で)負の値を持つことができます。この場合、プログラムは12、回答者が決定した偽の値に従ってを出力する必要があります。別のケースは、解決策がまったくないことです。たとえば、

[[4,2,-15],[-1,-2,7],[-1,0,3],[0,1,0],[3,2,0]].

この場合、偽の値も出力する必要があります。目的関数の「最適値」が無限である場合と、解がまったくない場合を識別するのは良いことですが、これは必要ではありません。

入力には、不等式と目的関数の両方の整数係数のみが含まれます。未知数もすべて整数です。不等式の係数行列は、完全なランクを持つことが保証されています。

テストケース

@KirillLの功績。元のテストスイートでバグを見つけ、ILPの問題についての理解を深めてくれました。

Input
Output

[[4,2,-15],[1,2,-8],[1,1,-5],[-1,0,0],[0,-1,0],[3,2,1]]
[1,13]

[[4,2,-15],[1,2,-8],[1,1,-5],[3,2,0]]
[-inf, 12]

[[4,2,-15],[-1,-2,7],[-1,0,3],[0,1,0],[3,2,0]]
[NaN, NaN]

[[-1,-1,-1,-1,-1,8],[1,1,1,1,0,0],[5,5,5,5,6,7]]
[55, inf]

[[-1,-1,-1,-1,-1,8],[1,1,1,1,0,0],[0,0,0,0,0,4]]
[4, 4]

[[4,2,-15],[-1,-2,7],[-1,0,3],[0,1,0],[0,0,4]]
[NaN, NaN]

スペック

  • 例外処理を心配する必要はありません。

  • これはであり、最小バイト数が勝ちます。

  • 未知数の最大数:9。不等式の最大数:12

  • 任意の標準フォームを使用して入力を取得し、出力を提供できます。フォーマットは自由に選択できます。

  • いつものように、デフォルトの抜け穴がここに適用されます。



タスクの説明で明示的に言及していませんが、既存のライブラリを利用する退屈なコードではなく、アルゴリズムの元の実装を探しているのではないでしょうか?それでも、Rでテストケースを試したところ、結果を正確に再現できませんでした。たとえば、[55、inf]ケースは、変数が非負に制限されている場合にのみ機能します。しかし、[-inf、12]の場合も、通常の結果[0、12]を生成します。一方、下限が-infの場合、[55、inf]の場合は、最小シナリオと最大シナリオの両方で解決できません。
キリルL.

はい、オリジナルの実装を探しています。
ウェイジュン周

@KirillL。テストケース[55、inf]の関数が55より小さい値を与えるベクトルを提供できますか?オンラインソルバーで確認したところ、問題はないようです。このテストケースを作成するとき、次の理由があります。最初の制限ではすべての自由変数の合計がgeq 8である必要がありますが、2番目の制限では最後を除くすべての合計がleq 0である必要があります。最初の4つの自由変数のいずれかを減らすことで目標を達成するには、最終変数を同じ量だけ増やす必要があるため、目標の値は大きくなります。
ウェイジュン周

ここに私のスニペットがありますが、ライブラリがないためにTIOで動作しません。これは55になりますが、set.bounds行のコメントを外すと「model is unbounded」で終了します。おそらく、エラーは私の側にあります。オンラインソルバーへのリンクも教えてください。
キリルL.

回答:


2

Python 3、534バイト

import itertools as t
import operator as o
I=float("inf")
e=lambda p,A:sum([i[0]*i[1]for i in zip(p,A[:-1])])+A[-1]
def w(x,j):
	d=len(x[0])-1;C=[0]*d;v,w=I,I
	while 1:
		L={(*n,):(sum([0 if e(n,A)<=0 else e(n,A)for A in x[:-1]]),j*e(n,x[-1]))for n in [[sum(a) for a in zip(C,c)]for c in t.product(*[[-1,0,1]]*d)]};C,P=min(L.items(),key=o.itemgetter(1))[0],C;v,w,p,q=L[C][0],L[C][1],v,w
		if(all([e(C,A)<=e(P,A)for A in x[:-1]]))*(j*(e(C,x[-1])-e(P,x[-1]))<0)+(p==v>0):return I
		if(p==v)*(q<=w):return j*q
f=lambda x:(w(x,1),w(x,-1))

オンラインでお試しください!

概要

これは、オリゴから始まる反復アルゴリズムです。隣接する位置を収集し、潜在的な関数を割り当てます。x:(a,b)ここxで、位置aは、各線形不等式の半空間からの位置の距離の合計です。bでの目標の値です。

x:(a,b) < y:(c,d)IFF a<ca=c and b<d

反復は次の場合に停止します。

  • ポテンシャルの最初の座標は減少せず正であり、システムは実行不可能です
  • すべての半空間からの距離は、目的と同じように減少しました。システムは無制限です。
  • 前のものも潜在性も低下していません。最適な値です。

1

Matlab、226バイト

免責事項「オリジナル」の実装ではなく、楽しみのためだけです。

このintlinprog機能を活用したシンプルなソリューション:

function r=f(a);b=-1*a(1:end-1,end);p=a(end,1:end-1);c=a(1:end-1,1:end-1);[~,f,h]=intlinprog(p,1:size(a,2)-1,c,b);[~,g,i]=intlinprog(-p,1:size(a,2)-1,c,b);s=[inf,nan,f];t=[inf,nan,g];r=a(end,end)+[s(4-abs(h)) -t(4-abs(i))];end

最適値を返します。問題が無制限の場合はinf(-inf)、実行不可能な場合はnanを返します。

a = [4 2 -15; 1 2 -8; 1 1 -5; -1 0 0; 0 -1 0; 3 2 1]
b = [4 2 -15; 1 2 -8; 1 1 -5; 3 2 0]
c = [4 2 -15; -1 -2 7; -1 0 3; 0 1 0; 3 2 0]
d = [-1 -1 -1 -1 -1 8;  1 1 1 1 0 0; 0 0 0 0 0 4]
e = [4 2 -15; -1 -2 7; -1 0 3; 0 1 0; 0 0 4]

>> f(a)
ans =

     1    13

>> f(b)
ans =

   Inf    12

>> f(c)
ans =

   NaN   NaN

>> f(d)
ans =

     4     4

>> f(e)
ans =

   NaN   NaN
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.