import * as Bluelib from "@steffo/bluelib-react"
import { BaseElement } from "@steffo/bluelib-react/dist/components/BaseElement"
import { Section, Box, Split, Panel, r, ILatex, BLatex, PLatex, Latex, Help, Example, Color, TablePanel, Code, Plus, Minus, BaseLink, Todo, Image } from "../../components/compat1"
import type { NextPage } from 'next'
import { WarningPorted, WarningUnchecked } from "../../components/warnings";
const Min = ({ children = undefined, ...props }) => (
Problemi che cercano di
Spesso sono detti anche problemi di LP.
La funzione da
Il vettore dei suoi coefficienti è detto
In genere, la funzione obiettivo è scritta in forma di combinazione lineare tra le incognite e i coefficienti:
Funzione della funzione obiettivo che restituisce la direzione del suo aumento più
veloce.
Equazioni e disequazioni a cui devono sottostare le incognite perchè esse formino una soluzione
valida.
I loro coefficienti sono contenuti nella matrice
L'insieme che racchiunde tutte le soluzioni ammissibili di un problema.
Può essere
La soluzione di un problema, ricavabile dal
prodotto
In particolare, il valore ottimo è un vertice del poliedro, detto vertice ottimo.
Un problema con:
Un problema con:
Un problema con:
Applica questa conversione a ogni equazione nel sistema:
Aggiungi una variabile slack
Sdoppia ogni variabile non-vincolata in due variabili con vincolo di non-negatività:
Un modo per rappresentare sistemi in forma standard, anche noto come matrice equivalente
completa del sistema.
Un tableau è un sistema di equazioni in forma matriciale completa.
È possibile effettuare senza che cambi il risultato finale le seguenti trasformazioni:
Variabili che hanno tutti 0 e un solo 1 nella loro colonna del tableau.
La loro controparte sono le variabili fuori base, che hanno qualsiasi altro valore.
Il valore della funzione obiettivo che si otterrebbe se tutte le variabili fuori base
valessero 0.
Procedendo nella risoluzione (descritta in seguito) del tableau, questo valore aumenterà, fino a
raggiungere il valore ottimo quando la risoluzione sarà completata.
Il sistema:
Diventa il tableau:
Con i seguenti elementi:
Un algoritmo per trovare efficientemente il valore ottimo e le coordinate di un vertice
ottimo in problemi di ottimizzazione lineare.
Perchè sia possibile effettuare il Simplex è necessario che l'origine sia nel poliedro:
pertanto, non è possibile che un problema risolto con il Simplex sia
Scegli la prima variabile fuori base con
coefficiente
Scegli la variabile in base con il minor rapporto
positivo:
Pivot: trasforma tutte le funzioni del sistema in modo che abbiano 0
nella colonna della variabile entrante, tranne nella riga della variabile uscente,
in cui avrà 1.
Una soluzione con almeno una variabile di valore
Senza Regola di Bland e in presenza di vincoli ridondanti si rischia di trovarsi a fare
pivot infiniti.
Un estensione del Simplex per permettere la risoluzione di problemi la cui origine non
è una soluzione ammissibile.
Prevede l'introduzione di un problema ausiliario, le cui incognite sono
dette artificiali.
Il vettore delle incognite artificiali è solitamente chiamato
Una versione semplificata di un problema nella quale si ignora la violazione di uno o più
vincoli.
Un rilassamento che permette di misurare di quanto i vincoli vengono violati.
I vincoli, moltiplicati per coefficienti di rilassamento, vengono inseriti nella funzione
obiettivo.
Il vettore dei coefficienti di rilassamento solitamente è indicato
con
Il sistema:
diventa:
Il sistema che
Possiamo trasporre il tableau e sostituire le variabili
I maggiori e minori dei vincoli diventeranno maggiori e minori delle variabili e viceversa.
Variabili e vincoli del duale corrispondono rispettivamente a vincoli e variabili del primale.
In particolare:
Una disuguaglianza lineare
Il teorema che dimostra l'equivalenza tra primale e duale.
Se uno dei due problemi è finito, la soluzione di uno coincide con la soluzione dell'altro.
Il teorema che dimostra che il valore della funzione obiettivo del duale (di un qualsiasi
tableau) è sempre
Il teorema che ci permette di passare dalla soluzione del duale alla soluzione del
primale.
Si deriva combinando le seguenti condizioni:
Ne risulta che una soluzione è ottima se e solo se:
Un'estensione al Simplex primale che opera sul problema duale.
Funziona esattamente come il Simplex primale, ma opera sul duale.
Un procedimento che misura di quanto può variare il termine noto di un
vincolo
Particolari problemi di ottimizzazione lineare in cui le variabili sono vincolate ad essere
numeri interi.
Spesso detti anche problemi di ILP.
Un rilassamento che rimuove il vincolo di integrità a un problema, trovando la sua soluzione
continua.
Un modo per passare dalla soluzione del rilassamento alla soluzione intera di un problema
di ILP.
Consiste nel calcolare la soluzione di ogni singolo punto incluso nel poliedro, e selezionare
la
Trova sicuramente la soluzione giusta, ma il costo computazionale è
esponenziale
Un altro modo per passare dalla soluzione del rilassamento alla soluzione intera di un
problema di ILP.
Consiste nell'arrotondare tutte le variabili al loro valore intero più vicino, e
calcolarne il valore ottimo.
Funziona bene per valori grandi, ma più essi si avvicinano allo 0 più l'errore diventa
grande.
Un altro modo ancora per passare dalla soluzione del rilassamento alla soluzione intera
di un problema di ILP.
Consiste nel tagliare il poliedro con nuovi vincoli (piani secanti) che riducono le
possibili soluzioni continue ma non quelle intere.
Per selezionare i vincoli, si usano i tagli di Gomory:
Per ogni valore noto frazionario si viene quindi a creare una nuova variabile in base e
un nuovo vincolo formato dall'opposto di tutti i valori frazionari dei coefficienti fuori base.
Il tableau:
v
s
Significato
Incognite
Variabili slack
Coefficienti della funzione obiettivo
Coefficienti dei vincoli
Termini noti dei vincoli
Incognite artificiali
Coefficienti di rilassamento
Valore ottimo di un problema
Incognite in base
Coefficienti della funzione obiettivo delle variabili in base
Coefficienti dei vincoli delle variabili in base
Incognite fuori base
Coefficienti della funzione obiettivo delle variabili fuori base
Coefficienti dei vincoli delle variabili fuori base
Simboli
Significato
Soluzione del problema
Vincoli in forma standard
Funzione obiettivo
Soluzione del problema duale
Vincoli del problema duale in forma standard
Arrotondamento per difetto di x
Arrotondamento per eccesso di x
Parte frazionaria di x (se non è negativo)
TN
Ex_LP_testo
.
Vincolo
Variabile
Vincolo
Variabile
Vincolo
Variabile libera
Variabile
Vincolo
Variabile
Vincolo
Variabile libera
Vincolo
TN
Diventa:
TN | |||||
---|---|---|---|---|---|
È possibile usare la tecnica divide et impera per rendere più efficiente l'enumerazione totale.
Si divide il problema principale (trovare il valore ottimo di un problema di ILP) in più sottoproblemi (trovare il valore ottimo di un problema di ILP con una variabile impostata a un valore fisso).
Si crea così un albero.
È possibile chiudere in anticipo alcuni nodi dell'albero se il loro miglior possibile
valore ottimo è inferiore a uno precedentemente trovato o se il loro poliedro è
È possibile utilizzare diverse strategie di esplorazione dell'albero:
È possibile combinare il metodo dei tagli secanti con la tecnica divide et impera per raggiungere ancora più velocemente a una soluzione.
Si effettuano poche iterazioni del metodo dei tagli secanti, e sul risultato di quelle iterazioni si applica il divide et impera.
Insieme di nodi
Può essere diretto se gli archi hanno una direzione.
Nodi connessi da un arco.
Arco connesso a un dato nodo.
Un arco diretto che termina o inizia da un dato nodo.
Conteggio degli archi incidenti di un nodo.
Si può calcolare anche relativamente agli archi entranti o agli archi uscenti.
Sequenza di archi consecutivi.
Due nodi sono connessi se tra loro esiste almeno un percorso.
Un grafo è connesso se tutti i suoi nodi sono connessi.
Percorsi rispettivamente indiretti e diretti in cui l'inizio coincide con la fine.
Grafo in cui ogni nodo è connesso con ogni altro.
Se diretto, contiene
VediAlgoritmi .
VediAlgoritmi .
Sottoinsieme di archi che connettono due sottoinsiemi di nodi.
Può essere anche uscente o entrante; in tal caso include solo gli archi entranti o uscenti dal sottoinsieme.
Sottoinsieme di nodi e archi di un grafo.
Tutti gli archi di un sottografo possono connettere solo nodi all'interno di esso.
Sottografo connesso e aciclico.
Albero che include tutti i nodi di un grafo.
Crea uno spanning tree.
Trova l'ordine topologico di un albero.
Trova i percorsi di costo minimo in un albero.
VediAlgoritmi .
Costruisci il grafo residuo e vedi se c'è un percorso che va dalla sorgente alla destinazione.
Valori che sono calcolati al momento della compilazione del programma:
param nomeparametro;
Si possono assegnare valori ai parametri nel codice con:
nomeparametro := 123 + 234;
Insiemi di parametri:
set NOMESET;
Si possono definire i contenuti dei set con:
{r`
set DA_UNO_A_DIECI := 1 .. 10;
set DA_UNO_A_PARAMETRO := 1 .. parametro;
`}
Si possono effettuare operazioni su set con:
{r`
set UNIONE := SET_A union SET_B;
set INTERSEZIONE := SET_A inter SET_B;
`}
Valori che sono calcolati al momento dell'esecuzione del programma:
var nomevariabile;
È possibile richiedere che un parametro o una variabile soddisfino certi requisiti.
Si può richiedere che siano
{r`
param positivo, > 0;
var non_positiva, <= 0;
`}
Si può richiedere che appartengano a un dato set:
{r`
param intero_positivo, integer, > 0;
var zero_oppure_uno, binary;
`}
È possibile creare anche un "array" di parametri o variabili:
{r`
param dieci_parametri{1..10};
var quadrato{1..10, 1..10};
var cubo{1..10, 1..10, 1..10};
`}
Si possono usare anche set:
{r`
param dieci_parametri{DA_UNO_A_DIECI};
`}
La funzione obiettivo può comparire solo una volta nel programma.
Si definisce con:
{r`
minimize valore_ottimo_min: espressione;
maximize valore_ottimo_max: espressione;
`}
I vincoli a cui sono soggette le variabili si definiscono con:
{r`
nome_vincolo_1: espressione <= 1;
nome_vincolo_2: espressione >= parametro;
`}
I vincoli possono essere indicizzati:
{r`
// La diagonale del quadrato deve essere minore di 1
v_3{i in DA_UNO_A_DIECI}: quadrato[i, i] <= 1;
// Tutti i valori del quadrato devono essere minori o uguali a 1
v_4{i in DA_UNO_A_DIECI, j in DA_UNO_A_DIECI}: quadrato[i, j] <= 1;
`}
Esistono anche operatori aggregati:
{r`
// La somma degli elementi della diagonale deve essere maggiore o uguale a 0
v_5: sum{i in DA_UNO_A_DIECI} quadrato[i, i] >= 0;
// Il prodotto degli elementi della diagonale deve essere maggiore o uguale a 0
v_6: prod{i in DA_UNO_A_DIECI} quadrato[i, i] >= 0;
`}
Si possono anche aggiungere requisiti agli indici:
{r`
v_7: sum{i in DA_UNO_A_DIECI, i <= 5} quadrato[i, i] >= 0;
v_8: prod{i in SET, i not in ALTRO_SET} quadrato[i, i] >= 0;
`}
Perchè il programma calcoli i valori di tutte le variabili, è necessaria l'istruzione:
{r`
solve;
`}
Per stampare i valori calcolati, è possibile usare:
{r`
printf "%d \n", nomevar;
`}
Eventualmente, anche in un ciclo for:
{r`
for{i in DA_UNO_A_DIECI} {
printf "%d: %d \n", i, x[i];
}
`}
Per compilare ed eseguire il programma, è sufficiente eseguire:
glpsol --math nomefile.mod
È possibile specificare i dati in un file separato da quello del modello; in tal caso, si dovrà eseguire:
glpsol --math -m modello.mod -d dati.mod
Per salvare i risultati su file e visualizzarli a schermo:
glpsol --math nomefile.mod | tee risultati.txt