/* File: Simplex.java */ /* Copyright (C) 1997 K. Ikeda */ import java.util.*; import java.awt.*; import java.

applet.*; class RN { int int n; d;

RN() {n=0; d=1;} RN(int n) {this.n=n; this.d=1;} RN(int n, int d) {this.n=n; this.d=d; reduce();} RN(String s) { int k = s.indexOf('/'); if (k>0) { d = Integer.valueOf(s.substring(k+1)).intValue(); s = s.substring(0,k); } else d = 1; n = Integer.valueOf(s).intValue(); reduce(); } int euclid(int a, int b) { int q,r; if (a < 0) a = -a; if (b < 0) b = -b; if (b == 0) if (a==0) return -1; else return a; for (;;) { q = a / b; r = a % b; if (r==0) break; a = b; b = r; } return b; } boolean reduce() { int c; if ((c = euclid(n,d))<0) return false; if (d<0) c *= -1; n /= c; d /= c; return true; } void set(int n) {this.n=n; this.d=1;} void set(int n, int d) {this.n=n; this.d=d;}

reduce(). return c.d. d = aa.d/c*a.reduce().a.} boolean ge(RN a) {RN c=new RN(n. if ((x = a. RN aa = new RN(n. d). c. if ((x = a. c. return c.} void mul(RN a) { a. y = 1.d. d=a.reduce().minus(a). c = euclid(d.d).n). a. this. } void div(RN a) { a. RN bb = new RN(a. reduce(). } boolean minus(RN a) { int c. d = y. if (c < 0) return false.} boolean plus(RN a) { int c.d. n = aa.void set(RN a) {n=a.d.d. a. d = x.n.d/c*n . y = 1. } else y = d/c*a. } void inv() {int x. return true. bb.reduce().n * bb. d = aa.n)==0) { x = 0.y.d * bb. } else y = d/c*a.y.n * bb.minus(a).d). a. n = x. this. if (c < 0) return false. aa.d). return true.n.d).d).n>0.d * bb. x = n. c = euclid(d. bb.x.reduce(). RN bb = new RN(a. n = aa. n = x. RN aa = new RN(n.d).d.reduce().n>=0.n. n = d.} .x. d = y. aa.reduce().reduce().n.d/c*n + d/c*a. } boolean gt(RN a) {RN c=new RN(n.n)==0) { x = 0.

for (int i = 0.getHeight().x+wd/2.x-wn.drawString(s.n.getAscent()). n = Integer.getHeight(). int sign.minus(a).y. j<n.y-1). . wd = fm.drawLine(x-wd/2. FontMetrics fm.parseInt(getParameter("m")).x. String message = "".x. wd = fm.d). int n) { Print(g.stringWidth(s). i++) { for (int j=0.getAscent()).x.d). if (rn.n)).cycle.n<=0.x.n).y-1.getHeight(). int[] base = new int[10].boolean eq(RN a) {RN c=new RN(n.n==0.minus(a). return c. RN rn) { int wn.drawString("-". h = fm. c. int h = fm. j++) { RN rn = new RN(0).".x-w/2. FontMetrics fm. j++) a[i][j] = new RN(st.d). c. } else { Print(g.n<0) sign = -1.fm. else sign = 1. return c. StringTokenizer st = new StringTokenizer(sdat. String sdat = getParameter("data").minus(a).} boolean lt(RN a) {RN c=new RN(n.sign*rn.d).fm.rn. FontMetrics fm.y-h/2-2. } void Print(Graphics g. } if (sign<0) { wn = wd/2+fm.fm.s. int y. } } void input_data() { m = Integer. g.y-wd/2+fm. base[i] = n+i. Print(g. g.sign*rn. int x.} boolean le(RN a) {RN c=new RN(n. } void Print(Graphics g. int y.parseInt(getParameter("n")). void Print(Graphics g. c. String s) { int w = fm.n).nextToken()). int x. if (wn>wd) wd = wn. wd = fm. wn = fm. int step. RN[][] a = new RN[10][20].y+h/2+2.n<0.stringWidth("-")+2. int y.y-h/2+fm.} } public class Simplex extends Applet { int m.d == 1) { Print(g.r. i<=m. j<n+m. for (int j=n.d).fm. g.stringWidth(""+(sign*rn."). wd.n). int x. return c.stringWidth(""+sign*rn.""+n). if (rn.stringWidth(""+rn.y.

s) */ for (int i=0. c. for (int j=0.set(a[m][s]).div(a[i][s]). j<=n.div(c). base[r] = s.set(1). } void step3() { /* pivot operation 1 */ RN c = new RN(). RN t = new RN(). } a[i][n+m] = new RN(st. i<m. i++) { if (a[i][s]. j<n. c. /* search pivot s of (r. r = -1. i++) { . j++) if (c.n>=0) { s = -1. } n += m.if (j == i+n) rn. } } if (r<0) return true. c. for (int i=0. } else return false. } boolean step1() { RN c = new RN().lt(c)) { r = i.set(a[i][n]). j++) a[r][j]. c. } boolean step2() { RN t = new RN(). else return false.set(t). s) */ s = 0.nextToken()).set(a[m][s]).n<=0) continue. RN c = new RN(). /* search pivot r of (r. for (int j=1. if (r<0 t. } void step4() { RN c = new RN(). return true.set(a[r][s]).gt(a[m][j])) { s = j. } if (c. i<=m. t. a[i][j] = rn. t.

if (i == r) continue."basis"). s = r = -1. j++) { t."x"+(j+1)). for (int j=0.h+1).x. } public void init() { input_data().h.setColor(getBackground()).getFontMetrics().getHeight()*2+4. c.y.y. j++) { x += w. g. g.y-h/2.mul(a[r][j]). for (int i=0.red. else if ((step==1&&i==m&&j<n&&a[i][j]. if ((step==1 && i==m && j==s) (step!=1 && i==r && j==s)) c = Color. step = cycle = 0.x. g. y += h. } x += w.x. } } r = s = -1. a[i][j].black. int x.h+1).(n+2)*w+1. g. w = fm. x = 25 + w/2.black).n<0) (step==2&&(j==s j==n)&&i<m&&a[i][s].set(c). int j) { Color c. setBackground(Color.fm.y."const"). t. else c = Color.y.y-h/2. message = "click here.setColor(Color.stringWidth("012345")+10.setColor(getBackground()). j<n. } public void paint(Graphics g) { int w.fm.setColor(Color.white). g.blue. Print(g.fm. for (int j=0.fillRect(x-w/2.minus(t). Print(g.setColor(c). i++) { x = 25 + w/2. int i. h = fm. g. g. j<=n. Print(g. y = 25 + h/2.(n+2)*w+1.set(a[i][s]). i<=m. .black). } void select_color(Graphics g.fillRect(x-w/2.n>0) (step==3&&(i==r j==s))) c = Color.". FontMetrics fm = g.

fillRect(25. g.getAscent()).120.(h-4)/2+1). Print(g. else Print(g. g. break. break. } public boolean mouseDown(Event ev.25+(m+2)*h+fm.y.". int x.if (i==m) Print(g. message = "Repeat the cycle.x. default: break. } step++. else message = "Select x"+(s+1)+" to enter th e basis. break.".x.(h-4)/2+1). break. for (int j=0. case 3: step4(). j<=n.setColor(Color. message = "Replace the simplex tableau. g.25. .fm. g.". message = "Click here".j). boolean isUnbounded = false. repaint().300. case 2: step3().25. else message = "Select x"+(base[r]+1)+" to le ave the basis. g.fm. int y) { boolean isOptimal = false.25+(m+2)*h. cycle++. case 1: if (isUnbounded=step2()) message = "Unbounded".drawString("Cycle "+cycle. j++) { select_color(g.25-h/2+fm.fm.setColor(getBackground()). switch (step) { case 0: if (isOptimal=step1()) message = "Optimal".black).y. return true.getAscent()). } } g. } public void update(Graphics g) { paint(g)."."-z").y. x += w.fillRect(25.i.a[i][j]).25-h/2. case 4: init().x."x"+(base[i]+1)).drawString(message.

repaint(). return true. if (isOptimal isUnbounded) step = 4. step %= 4. } } .

Sign up to vote on this title
UsefulNot useful