Programmazione lineare intera


21

introduzione

Scrivi un solutore per la programmazione lineare intera .

Sfida

Il tuo compito è scrivere un risolutore per la programmazione lineare intera (ILP). Nell'ILP vengono fornite le disuguaglianze lineari di un insieme di incognite (che sono tutti numeri interi) e l'obiettivo è trovare il minimo o il massimo di una funzione lineare.

Ad esempio, per le disuguaglianze (esempio tratto dalla Programmazione lineare di numeri interi misti )

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

e la funzione obiettivo 3x+2y, il massimo della funzione obiettivo dovrebbe essere 12( x=2,y=3), mentre il minimo dovrebbe essere 0( x=y=0).

L'input è dato come un array 2d (o qualsiasi equivalente secondo le specifiche standard), ogni riga corrisponde a una disuguaglianza, ad eccezione dell'ultima riga. I numeri nella matrice sono i coefficienti e la ≤0parte viene sempre omessa. Se ci sono nelementi in ogni riga, significa che ci sono n-1incognite.

L'ultima riga dell'array corrisponde alla funzione lineare. I coefficienti sono elencati.

Ad esempio, l'array di input per il problema sopra è

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

L'output dovrebbe essere il minimo e il massimo, dato in qualsiasi forma ragionevole.

Per il seguente problema (due delle restrizioni sono state rimosse dal problema precedente):

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

Il massimo è ancora 12, ma il minimo non esiste e la funzione obiettivo può avere valori negativi arbitrariamente grandi (nel senso del valore assoluto). In questo caso, il programma dovrebbe essere emesso 12, seguendo un valore errato che viene deciso dal risponditore. Un altro caso è che non esiste alcuna soluzione, ad esempio,

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

In questo caso, dovrebbero essere emessi anche valori falsi. Sarebbe bello discernere il caso in cui il "valore ottimale" per la funzione obiettivo è l'infinito e il caso in cui non esistono soluzioni, ma ciò non è necessario.

L'input contiene solo coefficienti interi sia per le disuguaglianze sia per la funzione obiettivo. Tutte le incognite sono anche numeri interi. La matrice dei coefficienti delle disuguaglianze è garantita per avere il grado completo.

Casi test

Ringraziamo @KirillL. per trovare un bug nella suite di test originale e approfondire la mia comprensione dei problemi 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]

Specifiche

  • Non è necessario preoccuparsi della gestione delle eccezioni.

  • Questo è , vince il numero più basso di byte.

  • Numero massimo di incognite: 9. Numero massimo di disuguaglianze: 12.

  • Puoi prendere input e fornire output attraverso qualsiasi modulo standard e sei libero di scegliere il formato.

  • Come al solito, qui si applicano scappatoie predefinite .



Non l'hai menzionato esplicitamente nella descrizione dell'attività, ma sospetto che tu stia cercando implementazioni originali dell'algoritmo e non un codice noioso che faccia uso di librerie esistenti? Tuttavia, ho giocato con i tuoi casi di test in R e non sono riuscito a riprodurre esattamente i risultati. Ad esempio, il caso [55, inf] funziona solo quando le variabili sono limitate per essere non negative. Ma anche il caso [-inf, 12] produce risultati normali [0, 12]. D'altra parte, quando il limite inferiore è -inf, il caso [55, inf] non riesce a risolvere in entrambi gli scenari minimo e massimo.
Kirill L.

Sì, cerco implementazioni originali.
Weijun Zhou

@KirillL. Potete fornire un vettore in cui la funzione nel test case [55, inf] dia un valore inferiore a 55? L'ho appena confrontato con un risolutore online e il caso sembra andare bene. Ho il seguente ragionamento quando realizzo questo test: La prima restrizione richiede che la somma di tutte le variabili libere sia geq 8, ma la seconda richiede che la somma di tutte tranne l'ultima sia leq 0. Se proviamo mai a ridurre il obiettivo riducendo uno dei primi 4 var gratuiti, richiederebbe un aumento della var finale dello stesso importo, quindi un valore maggiore per l'obiettivo.
Weijun Zhou

Ecco il mio frammento , anche se non funzionerà su TIO a causa della libreria mancante. Questo dà 55, ma esce con "il modello è illimitato" quando decommento la riga set.bounds. Molto probabilmente, però, l'errore è dalla mia parte. Potresti anche dare un link al solutore online?
Kirill L.

Risposte:


2

Python 3 , 534 byte

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))

Provalo online!

Panoramica

È un algoritmo iterativo, a partire dall'origo. Raccoglie le posizioni vicine e assegna una potenziale funzione: x:(a,b)dov'è xla posizione, aè la somma delle distanze della posizione dai semispazi di ciascuna disuguaglianza lineare, bè il valore dell'obiettivo in quella posizione.

x:(a,b) < y:(c,d)iff a<coa=c and b<d

L'iterazione si interrompe quando:

  • la prima coordinata del potenziale non è diminuita e è positiva: il sistema è impossibile
  • la distanza da ogni mezzo spazio è diminuita proprio come l'obiettivo: il sistema è illimitato.
  • nessuno dei precedenti e il potenziale non è diminuito: è il valore ottimale.

1

Matlab, 226 byte

DISCLAIMER : non un'implementazione "originale", solo per divertimento.

Soluzione semplice che sfrutta la intlinprogfunzione:

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

Restituisce i valori ottimali, o inf (-inf) se il problema è illimitato o nan se non è fattibile.

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.