Skip to content

Instantly share code, notes, and snippets.

@sugiartocokrowibowo
Created August 11, 2018 17:12
Show Gist options
  • Save sugiartocokrowibowo/2442bfb57ea73c2c7bdf7658a4c3493c to your computer and use it in GitHub Desktop.
Save sugiartocokrowibowo/2442bfb57ea73c2c7bdf7658a4c3493c to your computer and use it in GitHub Desktop.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package ga.turbin;
import java.util.ArrayList;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.Side;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.RowConstraints;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;
/**
*
* @author LENOVO
*/
public class UIGATurbin extends Application implements Runnable {
private final static int MAX_FPS = 10;//60;
private final static int MAX_FRAME_SKIPS = 5;
private final static int FRAME_PERIOD = 1000 / MAX_FPS;
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
//Thread
private Thread thread;
private volatile boolean running;
//Chart
private LineChart<Number, Number> chart;
double fMIN = 1;
double fMAX = 0;//0.02;
double interval = Math.abs(fMIN - fMAX) / 10.0;
NumberAxis xAxis = new NumberAxis(0, 20, 1);
NumberAxis yAxis = new NumberAxis(fMIN, fMAX, interval);
private XYChart.Series<Number, Number> fitnesElitismeDataSeries;
//UI
Scene scene;
TabPane tabPane = new TabPane();
Tab tab1 = new Tab();
Tab tab2 = new Tab();
Tab tab3 = new Tab();
Tab tab4 = new Tab();
BorderPane borderPane = new BorderPane();
TextArea taLogProsesGA = new TextArea();
Button btn1, btn2, btn3, btn4, btn5, btn6;
//input Parameter GA
private int n_baris;
private int n_kolom;
private double uo;
private int[] n_turbin_col;
private int n_turbin;
private double[] U;
private double p_turbin;
private double[] P;
private double[] sigma_p_col;
private double sigmap;
private double cost;
int n_generasi;
int n_Individu;
int n_individuTerseleksi;
double probabilitasMutasi;
int[] mask;
//variabel Run GA
ArrayList<Chromosome> individus = null;
Chromosome individuElitism = null;
int reachAt = Integer.MAX_VALUE;
int generasi = 0;
//output GA
ArrayList<Double> listFitnessTerbaikGenerasi = new ArrayList<Double>();
ArrayList<Chromosome> listIndividuTerbaikGenerasi = new ArrayList<Chromosome>();
ObservableList<FitnessGenerasi> dataFitnessGenerasi = FXCollections.observableArrayList();
//textfield parameters
TextField tfNBaris;
TextField tfNKolom;
TextField tfUo;
TextField tfPTurbin;
TextField tfNIndividu;
TextField tfNIndividuTerseleksi;
TextField tfPM;
TextField tfNGenerasi;
private TextField tfBestFitness;
@Override
public void start(Stage primaryStage) {
//constraints
ColumnConstraints col1 = new ColumnConstraints();
col1.setHgrow(Priority.NEVER);
col1.setPrefWidth(180);
ColumnConstraints col2 = new ColumnConstraints();
col2.setHgrow(Priority.ALWAYS);
//col2.setPercentWidth(60);
RowConstraints row1 = new RowConstraints();
row1.setVgrow(Priority.ALWAYS);
row1.setPercentHeight(100);
//Layout Grid Parameter
GridPane gridParameter = new GridPane();
gridParameter.setAlignment(Pos.TOP_LEFT);
gridParameter.setHgap(10);
gridParameter.setVgap(10);
gridParameter.setPadding(new Insets(20, 20, 20, 20));
Text scenetitle = new Text("Input Parameter GA Turbin");
scenetitle.setFont(Font.font("Tahoma", FontWeight.NORMAL, 14));
gridParameter.add(scenetitle, 0, 0, 2, 1);
Label lbNBaris = new Label("N-Baris");
gridParameter.add(lbNBaris, 0, 1);
tfNBaris = new TextField();
//tfNBaris.setPromptText("Masukkan jumlah baris gridParameter");
gridParameter.add(tfNBaris, 1, 1);
Label lbNKolom = new Label("N-Kolom");
gridParameter.add(lbNKolom, 0, 2);
tfNKolom = new TextField();
gridParameter.add(tfNKolom, 1, 2);
Label lbUo = new Label("Uo");
gridParameter.add(lbUo, 0, 3);
tfUo = new TextField();
gridParameter.add(tfUo, 1, 3);
Label lbPTurbin = new Label("P Turbin");
gridParameter.add(lbPTurbin, 0, 4);
tfPTurbin = new TextField();
gridParameter.add(tfPTurbin, 1, 4);
Label lbNIndividu = new Label("N-Individu");
gridParameter.add(lbNIndividu, 0, 5);
tfNIndividu = new TextField();
gridParameter.add(tfNIndividu, 1, 5);
Label lbNIndividuTerseleksi = new Label("N-Terseleksi");
gridParameter.add(lbNIndividuTerseleksi, 0, 6);
tfNIndividuTerseleksi = new TextField();
gridParameter.add(tfNIndividuTerseleksi, 1, 6);
Label lbPM = new Label("Prb Mutasi");
gridParameter.add(lbPM, 0, 7);
tfPM = new TextField();
gridParameter.add(tfPM, 1, 7);
Label lbNGenerasi = new Label("N-Generasi");
gridParameter.add(lbNGenerasi, 0, 8);
tfNGenerasi = new TextField();
gridParameter.add(tfNGenerasi, 1, 8);
//untuk testing
tfNBaris.setText("20");
tfNKolom.setText("20");
tfUo.setText("12");
tfPTurbin.setText("0.301593");
tfNIndividu.setText("300");
tfNIndividuTerseleksi.setText("150");
tfPM.setText("0.5");
tfNGenerasi.setText("20");
btn1 = new Button("Run GA");
btn1.prefWidthProperty().bind(gridParameter.widthProperty());
gridParameter.add(btn1, 0, 9, 2, 1);
btn1.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
resume();
}
});
btn2 = new Button("Break");
btn2.prefWidthProperty().bind(gridParameter.widthProperty());
gridParameter.add(btn2, 0, 10, 2, 1);
btn2.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
pause();
}
});
Label lbBestFit = new Label("Best Fitness");
gridParameter.add(lbBestFit, 0, 11);
tfBestFitness = new TextField();
tfBestFitness.setEditable(false);
gridParameter.add(tfBestFitness, 1, 11);
btn3 = new Button("Build Info");
btn3.prefWidthProperty().bind(gridParameter.widthProperty());
gridParameter.add(btn3, 0, 12, 2, 1);
btn3.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
enableButton();
showResult();
pause();
}
});
btn4 = new Button("Best Individu");
btn4.prefWidthProperty().bind(gridParameter.widthProperty());
gridParameter.add(btn4, 0, 13, 2, 1);
btn4.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
//drawIndividuTerbaik();
tabPane.getSelectionModel().select(1);
}
});
btn5 = new Button("Fitness Generasi");
btn5.prefWidthProperty().bind(gridParameter.widthProperty());
gridParameter.add(btn5, 0, 14, 2, 1);
btn5.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
//showFitnessGenerasi();
tabPane.getSelectionModel().select(2);
}
});
btn6 = new Button("Log Proses GA");
btn6.prefWidthProperty().bind(gridParameter.widthProperty());
gridParameter.add(btn6, 0, 15, 2, 1);
btn6.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
//showFitnessGenerasi();
tabPane.getSelectionModel().select(3);
}
});
//Layout Grid Chart
GridPane gridChart = new GridPane();
gridChart.setAlignment(Pos.BASELINE_LEFT);
gridChart.setHgap(10);
gridChart.setVgap(10);
gridChart.setPadding(new Insets(20, 20, 20, 20));
gridChart.getColumnConstraints().add(col2); //50 percent
//Chart Progress
chart = new LineChart<>(xAxis, yAxis);
chart.setCreateSymbols(false);
chart.setAnimated(false);
chart.setLegendVisible(false);
chart.setTitle("Progress Evolusi");
xAxis.setLabel("Generasi");
xAxis.setForceZeroInRange(false);
yAxis.setLabel("Fitness");
yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis, "", null));
fitnesElitismeDataSeries = new XYChart.Series<>();
fitnesElitismeDataSeries.setName("Fitnes_Elitism");
//fitnesElitismeDataSeries.getData().add(new XYChart.Data<Number, Number>(0, 1));
//chartProgress.getData().add(fitnesElitismeDataSeries);
gridChart.add(chart, 0, 0);
gridChart.getRowConstraints().add(row1);
//Layout Grid utama
GridPane gridUtama = new GridPane();
gridUtama.getColumnConstraints().add(col1); //25 percent
gridUtama.getColumnConstraints().add(col2); //50 percent
gridUtama.add(gridParameter, 0, 0);
gridUtama.add(gridChart, 1, 0);
StackPane root = new StackPane();
//Scene scene = new Scene(root, 400, 300, Color.WHITESMOKE);
tabPane = new TabPane();
tabPane.setSide(Side.BOTTOM);
tab1 = new Tab();
tab1.setText("Home");
tab1.setContent(gridUtama);
tab2 = new Tab();
tab2.setText("Best Individu");
borderPane = new BorderPane();
//borderPane.setCenter(new Rectangle(100, 100, Color.CRIMSON));
tab2.setContent(borderPane);
tab3 = new Tab();
tab3.setText("Fitness Generasi");
//tab3.setContent(new Rectangle(100, 100, Color.CRIMSON));
tab4 = new Tab();
tab4.setText("Log Proses GA");
taLogProsesGA = new TextArea();
tab4.setContent(taLogProsesGA);
tabPane.getSelectionModel().select(0);
tabPane.getTabs().addAll(tab1, tab2, tab3, tab4);
root.getChildren().add(tabPane);
//StackPane root = new StackPane();
//root.getChildren().add(gridUtama);
scene = new Scene(root, 1024, 700);
//Scene scene = new Scene(gridUtama, 1024, 700);
//gridUtama.prefHeightProperty().bind(scene.heightProperty());
gridChart.prefHeightProperty().bind(scene.heightProperty());
primaryStage.getIcons().add(new Image(getClass().getResourceAsStream("UNHAS_LOGO.png")));
primaryStage.setTitle("GA Turbin");
primaryStage.setScene(scene);
primaryStage.show();
}
private void enableButton() {
btn4.setDisable(false);
btn5.setDisable(false);
btn6.setDisable(false);
}
private void disableButton() {
btn4.setDisable(true);
btn5.setDisable(true);
btn6.setDisable(true);
}
private void resume() {
restartGA();
thread = new Thread(this);
running = true;
thread.start();
}
private void pause() {
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void showResult() {
//tampilkan Info proses GA
try {
drawIndividuTerbaik();
showFitnessGenerasi();
showLogProses();
} catch (Exception e) {
e.printStackTrace();
}
}
private void plot() {
if (generasi > 20) {
fitnesElitismeDataSeries.getData().remove(0);
}
yAxis.setUpperBound(fMAX);
yAxis.setLowerBound(fMIN);
yAxis.setTickUnit(interval);
// every hour after 24 move range 1 hour
if (generasi > 19) {
xAxis.setLowerBound(xAxis.getLowerBound() + 1);
xAxis.setUpperBound(xAxis.getUpperBound() + 1);
}
}
private void drawIndividuTerbaik() {
if (individuElitism != null) {
int[][] values = individuElitism.values;
double size = Math.min(scene.getHeight() - 40 - n_baris, scene.getWidth() - 40 - n_kolom) / Math.max(n_baris, n_kolom);
GridPane gridIndividu = new GridPane();
gridIndividu.setAlignment(Pos.CENTER);
gridIndividu.setHgap(1);
gridIndividu.setVgap(1);
for (int i = 0; i < values.length; i++) {
for (int j = 0; j < values[i].length; j++) {
if (values[i][j] == 1) {
gridIndividu.add(new Rectangle(size, size, Color.rgb(243, 156, 18, 0.9)), j, i);
} else {
gridIndividu.add(new Rectangle(size, size, Color.GRAY), j, i);
}
}
}
borderPane.setCenter(gridIndividu);
}
}
public void showFitnessGenerasi() {
if (dataFitnessGenerasi != null) {
TableColumn tableCol1 = new TableColumn();
tableCol1.setText("Generasi");
tableCol1.setCellValueFactory(new PropertyValueFactory("iGenerasi"));
TableColumn tableCol2 = new TableColumn();
tableCol2.setText("Fitness Terbaik Generasi");
tableCol2.setCellValueFactory(new PropertyValueFactory("fitnessValue"));
TableView tableView = new TableView();
tableView.setItems(dataFitnessGenerasi);
tableView.getColumns().addAll(tableCol1, tableCol2);
tab3.setContent(tableView);
}
}
private void showLogProses() {
//save proses ke taLogProsesGA
taLogProsesGA.setText("");
taLogProsesGA.appendText("Individu Terbaik Hasil Evolusi " + generasi + " Generasi\n");
taLogProsesGA.appendText("\nFitness: " + individuElitism.fitness + " Tercapai pada generasi ke-" + reachAt + "\n");
taLogProsesGA.appendText("\nChromosome Value:\n");
int[][] values = individuElitism.values;
if (values != null) {
for (int i = 0; i < values.length; i++) {
for (int j = 0; j < values[i].length; j++) {
taLogProsesGA.appendText(" " + values[i][j]);
}
taLogProsesGA.appendText("\n");
}
}
}
private void update() {
}
private void draw() {
}
@Override
public void run() {
long beginTime;
long timeDiff;
int sleepTime = 0;
int framesSkipped;
//LOOP Evolusi GA
while (running && generasi < n_generasi) {
try {
synchronized (this) {
beginTime = System.currentTimeMillis();
framesSkipped = 0;
//Run GA
//PROSES SELEKSI
ArrayList<Chromosome> individusTerseleksi = new ArrayList<Chromosome>();
for (int i = 0; i < n_individuTerseleksi; i++) {
individusTerseleksi.add(individus.get(i));
}
//PROSES CROSSOVER
int k = n_individuTerseleksi;
while (k < n_Individu) {
int iParent1 = randomBetweenInt(0, n_individuTerseleksi - 1);
int iParent2 = iParent1;
while (iParent1 == iParent2) {
iParent2 = randomBetweenInt(0, n_individuTerseleksi - 1);
}
Chromosome parent1 = individusTerseleksi.get(iParent1);
Chromosome parent2 = individusTerseleksi.get(iParent2);
//Gunakan Mask yang berbeda/random untuk setiap kali proses crossover
this.mask = generateRandomMask(n_baris * n_kolom);
Chromosome[] offsprings = parent1.crossover(parent2, this.mask);
if (k < n_Individu) {
individusTerseleksi.add(offsprings[0]);
k++;
}
if (k < n_Individu) {
individusTerseleksi.add(offsprings[1]);
k++;
}
}
//PROSES MUTASI
ArrayList<Chromosome> individuHasilMutasi = new ArrayList<Chromosome>();
for (int i = 0; i < n_Individu; i++) {
double rm = Math.random();
if (rm < probabilitasMutasi) {
//lakukan mutasi
Chromosome ind = individusTerseleksi.get(i);
Chromosome c = new Chromosome(ind.n_baris, ind.n_kolom, ind.uo, ind.p_turbin);
c.generateChromosome();
individuHasilMutasi.add(c);
} else {
Chromosome ind = individusTerseleksi.get(i);
Chromosome c = new Chromosome(ind.n_baris, ind.n_kolom, ind.uo, ind.p_turbin, ind.values);
c.evaluate();
individuHasilMutasi.add(c);
}
}
individus = new ArrayList<Chromosome>();
for (int i = 0; i < n_Individu; i++) {
individus.add(individuHasilMutasi.get(i));
}
//update Generasi
generasi++;
//UPDATE ELITISM
individus = sortByFitness(individus);
updateElitism(individus.get(0));
//PLOT
plot();
update();
draw();
}
timeDiff = System.currentTimeMillis() - beginTime;
sleepTime = (int) (FRAME_PERIOD - timeDiff);
if (sleepTime > 0) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
}
}
while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {
update();
sleepTime += FRAME_PERIOD;
framesSkipped++;
}
} finally {
}
}
}
private void restartGA() {
setParameterGAfromField();
individus = generatePopulasiAwal();
individuElitism = null;
listFitnessTerbaikGenerasi = new ArrayList<Double>();
listFitnessTerbaikGenerasi.clear();
listIndividuTerbaikGenerasi = new ArrayList<Chromosome>();
listIndividuTerbaikGenerasi.clear();
generasi = 0;
disableButton();
step0();
}
private void step0() {
taLogProsesGA.setText("");
individus = sortByFitness(individus);
dataFitnessGenerasi = FXCollections.observableArrayList();
dataFitnessGenerasi.clear();
fitnesElitismeDataSeries.getData().clear();
chart.getData().clear();
chart.getData().add(fitnesElitismeDataSeries);
xAxis.setLowerBound(0);
xAxis.setUpperBound(20);
yAxis.setLowerBound(0);
fMIN = 1;
fMAX = 0;//0.02;
interval = Math.abs(fMIN - fMAX) / 10.0;
//update elitism
updateElitism(individus.get(0));
}
private void updateElitism(Chromosome individu) {
if (individuElitism == null) {
individuElitism = individus.get(0);
reachAt = 0;
} else {
if (individuElitism.fitness > individus.get(0).fitness) {
individuElitism = individus.get(0);
reachAt = generasi;
}
}
if (individuElitism.fitness > fMAX) {
fMAX = individuElitism.fitness;
fMAX += 0.001;
}
if (individuElitism.fitness < fMIN) {
fMIN = individuElitism.fitness;
fMIN -= 0.001;
}
interval = Math.abs(fMIN - fMAX) / 2.0;
//Save Fitness Individu Terbaik
tfBestFitness.setText("" + individuElitism.fitness);
listFitnessTerbaikGenerasi.add(individuElitism.fitness);
//save fitness generasi ke table
dataFitnessGenerasi.add(new FitnessGenerasi(generasi, individuElitism.fitness));
listIndividuTerbaikGenerasi.add(individuElitism);
fitnesElitismeDataSeries.getData().add(new XYChart.Data<Number, Number>(generasi, individuElitism.fitness, "fit3"));
}
private void setParameterGAfromField() {
int n_generasi = Integer.parseInt(tfNGenerasi.getText().trim());
int n_individu = Integer.parseInt(tfNIndividu.getText().trim());
int n_individuTerseleksi = Integer.parseInt(tfNIndividuTerseleksi.getText().trim());
double probabilitasMutasi = Double.parseDouble(tfPM.getText().trim());
int n_baris = Integer.parseInt(tfNBaris.getText().trim());
int n_kolom = Integer.parseInt(tfNKolom.getText().trim());
double uo = Double.parseDouble(tfUo.getText().trim());
double p_turbin = Double.parseDouble(tfPTurbin.getText().trim());
setParameterGA(n_generasi, n_individu, n_individuTerseleksi, probabilitasMutasi, n_baris, n_kolom, uo, p_turbin);
}
private void setParameterGA(int n_generasi, int n_individu, int n_individuTerseleksi, double probabilitasMutasi, int n_baris, int n_kolom, double uo, double p_turbin) {
this.n_baris = n_baris;
this.n_kolom = n_kolom;
this.uo = uo;
this.p_turbin = p_turbin;
this.n_Individu = n_individu;
this.n_individuTerseleksi = n_individuTerseleksi;
this.probabilitasMutasi = probabilitasMutasi;
this.mask = generateRandomMask(n_baris * n_kolom);
this.n_generasi = n_generasi;
}
public int randomBetweenInt(int min, int max) {
return (int) (Math.random() * (max - min)) + min;
}
//Membangkitkan Populasi Awal
public ArrayList<Chromosome> generatePopulasiAwal() {
ArrayList<Chromosome> individuAwal = new ArrayList<Chromosome>();
for (int i = 0; i < this.n_Individu; i++) {
Chromosome individu = new Chromosome(n_baris, n_kolom, uo, p_turbin);
individu.generateChromosome();
individuAwal.add(individu);
//individu.cetakChromosom();
}
return individuAwal;
}
public ArrayList<Chromosome> sortByFitness(ArrayList<Chromosome> individus) {
ArrayList<Chromosome> result = new ArrayList<Chromosome>();
double[][] index = new double[individus.size()][2];
for (int i = 0; i < index.length; i++) {
index[i][0] = individus.get(i).fitness;
index[i][1] = i;
}
//sort
for (int i = 0; i < index.length - 1; i++) {
for (int j = 1 + i; j < index.length; j++) {
if (index[i][0] > index[j][0]) {
//tukar
double fTemp = index[i][0];
double iTemp = index[i][1];
index[i][0] = index[j][0];
index[i][1] = index[j][1];
index[j][0] = fTemp;
index[j][1] = iTemp;
}
}
}
Chromosome[] sortedIndividu = new Chromosome[index.length];
for (int i = 0; i < index.length; i++) {
int in = (int) index[i][1];
sortedIndividu[i] = individus.get(in);
}
for (int i = 0; i < index.length; i++) {
result.add(sortedIndividu[i]);
//result.get(i).cetakChromosom();
}
return result;
}
private int[] generateRandomMask(int length) {
int[] mask = new int[length];
for (int j = 0; j < mask.length; j++) {
int m = 0;
if (Math.random() < 0.5) {
m = 1;
}
mask[j] = m;
}
return mask;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment