### 1.44.1 Αλγόριθμος `Simplex` : `simplex_reduce`

Η απλή περίπτωση
Η συνάρτηση `simplex_reduce` κάνει την αναγωγή με τον αλγόριθμο `simplex` για την εύρεση :

max(c.x), A.x ≤ b, x ≥ 0, b≥ 0

όπου c,x είναι διανύσματα του ℝn, b≥ 0 είναι ένα διάνυσμα του ℝp και A είναι ένας πίνακας με p γραμμές και n στήλες.
`simplex_reduce` παίρνει ως όρισμα `A,b,c` και επιστρέφει το `max(c.x)`, την επαυξημένη λύση του `x` (επαυξημένη επειδή ο αλγόριθμος δουλεύει προσθέτοντας `nrows(``A``)` βοηθητικές μεταβλητές) και τον ανηγμένο πίνακα.
Παράδειγμα
Βρείτε το

max(X+2Y) όπου

⎧
⎪
⎨
⎪
⎩

(X,Y) | ≥ | 0
−3X +2Y | ≤ | 3
X +Y | ≤ | 4

Είσοδος :

`simplex_reduce([[-3,2],[1,1]],[3,4],[1,2])`

Έξοδος :

`(7,[1,3,0,0],[[0,1,1/5,3/5,3],[1,0,(-1)/5,2/5,1], [0,0,1/5,8/5,7]])`

Το οποίο σημαίνει ότι το μέγιστο του `X+2Y` κάτω από αυτές τις συνθήκες είναι `7`, που προκύπτει θέτοντας `X=1,Y=3` επειδή το `[1,3,0,0]` είναι η επαυξημένη λύση και ο ανηγμένος πίνακας είναι ο :
`[[0,1,1/5,3/5,3],[1,0,(-1)/5,2/5,1], [0,0,1/5,8/5,7]]`.

Μια πιο περίπλοκη περίπτωση που ανάγεται στην απλή περίπτωση
Για να καλέσουμε την `simplex_reduce`, πρέπει το πρόβλημα να έχει μετασχηματισθεί στην κανονική του μορφή (για περισσότερες λεπτομέρειες δείτε και http://en.wikipedia.org/wiki/Simplex_algorithm). Δηλαδή πρέπει να έχουν γίνουν τα ακόλουθα :

- οι περιορισμοί να έχουν ξαναγραφεί στη μορφή xk ≥ 0,
- οι μεταβλητές χωρίς περιορισμούς να έχουν απαλειφεί,
- να έχουν προστεθεί (χαλαρές) μεταβλητές ( slack variables) ώστε όλοι οι περιορισμοί να εκφράζονται με ισότητες.

Για παράδειγμα, βρείτε :

min(2x+y−z+4) όπου

⎧
⎪
⎪
⎨
⎪
⎪
⎩

x | ≤ | 1
y | ≥ | 2
x+3y−z | = | 2
2x−y+z | ≤ | 8
−x+y | ≤ | 5

Αν θέσουμε x=1−X, y=Y+2, z=5−X+3Y τότε το παραπάνω πρόβλημα είναι ισοδύναμο με την εύρεση του ελαχίστου της παράστασης (−2X+Y−(5−X+3Y)+8) όπου :

⎧
⎪
⎨
⎪
⎩

X | ≥ | 0
Y | ≥ | 0
2(1−X)−(Y+2)+ 5−X+3Y | ≤ | 8
−(1−X) +(Y+2) | ≤ | 5

το οποίο είναι ισοδύναμο με την εύρεση του ελαχίστου της παράστασης :

(−X−2Y+3) όπου

⎧
⎪
⎨
⎪
⎩

X | ≥ | 0
Y | ≥ | 0
−3X+2Y | ≤ | 3
X +Y | ≤ | 4

Δηλαδή το πιο σύνθετο πρόβλημα ανάγεται στο να βρούμε το μέγιστο της παράστασης −(−X−2Y+3)=X+2Y−3 κάτω από συνθήκες, που είναι ίδιες με εκείνες της εύρεσης του μεγίστου της παράστασης X+2Y (απλή περίπτωση). Στην απλή περίπτωση η απάντηση ήταν `7`, συνεπώς, το αποτέλεσμα εδώ είναι το `7-3=4`.

Η γενική περίπτωση
Ένα πρόβλημα γραμμικού προγραμματισμού μπορεί, γενικά, να μην ανάγεται άμεσα στην απλή περίπτωση όπως παραπάνω. Ο λόγος είναι ότι, πριν την εφαρμογή του αλγορίθμου simplex, πρέπει να βρεθεί μια αρχική κορυφή (αρχικό σημείο). Επομένως, `simplex_reduce` μπορεί να κληθεί συγκεκριμενοποιώντας αυτήν την αρχική κορυφή. Στην περίπτωση αυτή, όλα τα ορίσματα, συμπεριλαμβανομένης και της αρχικής κορυφής, ομαδοποιούνται σε ένα μόνο πίνακα.

Επεξηγούμε αρχικά αυτό το είδος της κλήσης στην απλή περίπτωση όπου για το αρχικό σημείο δεν απαιτείται η επίλυση βοηθητικού προβλήματος. Εάν ο `A` έχει p γραμμές και n στήλες και αν ορίσουμε :

`B:=augment(A,idn(p));` `C:=border(B,b);`
`d:=append(-c,0$(p+1));` `D:=augment(C,[d]);`

τότε η εντολή `simplex_reduce` μπορεί να κληθεί με το `D` σαν το μόνο όρισμα.
Για το προηγούμενο παράδειγμα, εισάγετε :

`A:=[[-3,2],[1,1]];B:=augment(A,idn(2)); C:=border(B,[3,4]); D:=augment(C,[[-1,-2,0,0,0]])`

Εδώ το `C=[[-3,2,1,0,3],[1,1,0,1,4]]`
και το `D=[[-3,2,1,0,3],[1,1,0,1,4],[-1,-2,0,0,0]]`
Είσοδος :

`simplex_reduce(D)`

Έξοδος είναι το ίδιο αποτέλεσμα όπως πριν.

Επανερχόμαστε στην γενική περίπτωση.
Η κανονική μορφή ενός προβλήματος γραμμικού προγραμματισμού είναι ίδια με την απλή περίπτωση παραπάνω, αλλά με ισότητα Ax=b (αντί Ax≤ b) και x≥ 0. Μπορούμε επιπλέον να υποθέσουμε ότι b≥ 0 (εάν όχι, μπορούμε να αλλάξουμε το πρόσημο της αντίστοιχης γραμμής).

- Το πρώτο πρόβλημα είναι να βρούμε ένα x που να ικανοποιεί Ax=b, x≥ 0 . Έστω m ο αριθμός των γραμμών του A. Προσθέτουμε τις χαλαρές μεταβλητές y1,...,ym και μεγιστοποιούμε το άθροισμα −∑yi κάτω από τις συνθήκες Ax=b, x ≥ 0, y ≥ 0 ξεκινώντας με την αρχική τιμή x=0 και y=b (για να λυθεί αυτό με το `Xcas`, καλούμε ``simplex_reduce`` με μονaδικό όρισμα τον πίνακα που προκύπτει επαυξάνοντας τον A με τον ταυτοτικό πίνακα, την στήλη b αμετάβλητη και μία επαυξημένη γραμμή c με 0 κάτω από τον A και 1 κάτω από τον ταυτοτικό). Εάν το μέγιστο υπάρχει και είναι 0, μας δίνεται και μια λύση x , όπου όλες οι χαλαρές μεταβλητές είναι 0.
- Στην συνέχεια κάνουμε μια δεύτερη κλήση στο ``simplex_reduce`` με το αρχικό c και τον ανηγμένο πίνακα που βρίσκουμε λύνοντας το πρώτο πρόβλημα παραπάνω.
- Παράδειγμα : βρείτε το ελάχιστο του 2x+3y−z+t με x,y,z,t≥ 0 και :

  ⎧
  ⎨
  ⎩

  −x−y+t | = | 1
  y−z+t | = | 3

  Αυτό είναι ισοδύναμο με το να βρούμε το μέγιστο του αντίθετου −(2x+3y−z+t). Προσθέτουμε δύο χαλαρές μεταβλητές y1 και y2, και εισάγουμε

      simplex_reduce([[-1,-1,0,1,1,0,1],
                      [ 0,1,-1,1,0,1,3],
                      [ 0,0, 0,0,1,1,0]])

  Έξοδος: βέλτιστο=0, λύση x=(0,1,0,2,0,0) όπου οι χαλαρές μεταβλητές=0 (τα δύο μηδενικά στο τέλος του διανύσματος x), και ο ανηγμένος πίνακας

  ⎛
  ⎜
  ⎜
  ⎝

  −1/2 | 0 | −1/2 | 1 | 1/2 | 1/2 | 2
  1/2 | 1 | −1/2 | 0 | −1/2 | 1/2 | 1
  0 | 0 | 0 | 0 | 1 | 1 | 0

  ⎞
  ⎟
  ⎟
  ⎠

  Επομένως, x=(0,1,0,2) είναι ένα αρχικό σημείο που ικανοποιεί τις συνθήκες. Για να βρούμε την λύση του αρχικού προβλήματος, αντικαθιστούμε τις γραμμές του Ax=b με τις πρώτες δύο γραμμές του παραπάνω ανηγμένου πίνακα, αφαιρώντας τις τελευταίες στήλες που αντιστοιχούν στις χαλαρές μεταβλητές. Προσθέτουμε το c ως τελευταία γραμμή.

      simplex_reduce([[-1/2,0,-1/2,1,2],
                      [ 1/2,1,-1/2,0,1],
                      [  2, 3, -1, 1,0]])

  Έξοδος: `maximum=-5`, γι’ αυτό το ελάχιστο του αντίθετου είναι 5, και προκύπτει από την λύση x=(0,1,0,2), μετά την αντικατάσταση x=0, y=1, z=0 και t=2.

Για περισσότερες λεπτομέρειες, ψάξτε στο `google` τον ``simplex algorithm``.