2016年11月15日 星期二

面試問題

今天面試考白版題,整個頭腦轉不過來...就只好回家檢討一下問題了

1.寫出一個反轉字串的方法
static String reverse(String str)
{
char[] charArray=str.toCharArray();
str="";
for(char element:charArray)
{
str=element+str;
}
return str;
}
view raw gistfile1.txt hosted with ❤ by GitHub

2.一樣是反轉字串的方法,但不行使用迴圈的方式

這部分我分兩個...一個是我自己寫的,一個是看網路上比較簡易的==

2.1

static String reverse(String str, int current)
{
current++;
if(current>str.length())
{
return "";
}
else
{
return reverse(str,current)+str.charAt(current-1);
}
}
view raw gistfile1.txt hosted with ❤ by GitHub
2.2

static String reverse(String str){
if(str.equals("")){
return "";
}
else{
return reverse(str.substring(1))+str.substring(0,1);
}
}
view raw gistfile1.txt hosted with ❤ by GitHub
然後需要檢討時間複雜度和空間複雜度的運算和StringBuffer...完全忘記了,這部分下次再補齊

補充知識

今天和一個朋友聊天,聊了很多知識東西,我想要把它記下來和補充


1.Override and overload的差別

override:子類別繼承父類別的函式,然後改寫其繼承的函式,但必須是函式名稱相同、參數型態個數相同,傳回型態相同。

overload:相同的函式名稱,但參數型態、參數個數、傳回型態只要任一個不同,就會呼叫不同的函數。

2.IO dead lock 是什麼如何處理

process的通常流程=要求資源->使用資源->釋放資源

而dead lock通常要滿足下面條件

  a.Mutul exclusion:一個資源(Instances)一次只能被ㄧ 個process使用。

  b.Hold and wait:當多個process發生mutul exclusion,然後尋求下一個資源時,都有process在      使用,造成一個等待資源動作出現。

  c.No preemption:而資源又不能經過其他方法來釋放,只能依靠使用的process來自行處理。

  d.Circular wait:就造成每個process都握有另一個process請求的資源,然後各自沒有釋放本身      持有的資源,造成一個循環出現。

那我們該如何處理
  a.完全無視他...反正出現死結機率很低,大不了重開機或重開程式讓他重新來過就好了...

  b.偵測死結發生,然後經由自己寫的程式邏輯來恢復運作。

  c.使用一個protocol來預防或避免死結發生。

3.繼承、封裝、多型,如何用最普通的講話來解釋?

因為我只會實作,真的沒想過如何用普通的講話說出來,我這裡試著用我想法講出來

這裏我舉一個汽車工廠的例子

當母公司做了一個汽車模組出來分送給底下的子公司,然後子公司依照所待的國家區域,來做調整,例如是顏色問題、燈的明暗度、和左右邊駕駛問題,而這就是「子繼承父」的觀念了。

而封裝就像是避免存取一些你不想讓人知道的東西,舉個例子來說,每個汽車裡都有一個微電腦,而開發汽車微電腦的人,不想有人亂動裡面機密的設定,避免造成車禍事件發生,所以他們就只提供,供應微電腦的電源連接器、微電腦輸出設定到儀表板上,而微電腦就是被封裝的東西,而電源連接器和輸出設定就是提供微電腦的介面方法。

多型,我就在繼承的例子,再改一下,當母公司做了一個汽車模組設計圖,而這個汽車模組設計圖依照各個國家、地區、氣候、政治的不同,有不同的設計成品出來,而這些設計成品的原型是從「同一個名稱的汽車模組設計圖」出來的。

4.Clean code and dirty code

dirty code指的是讓人覺得很難看得懂的程式,有可能是重複宣告、同樣的程式碼、髒亂的排版、沒有註解...等等,而會造成這個原因有可能是自身實力不足或者是為圖方便之類,從而造成程式碼越來越髒、當越髒時Bug也會越多,因為當你看不懂時就會亂改參數或者是重新寫一個新的,而通常這都會造成下一個問題出現,因為你看不懂程式碼,無法全面觀察改變之後會造成什麼事情出現,而clean code就是除去這些問題所寫的完美程式碼,我這裡推薦兩個網址,這裡詳述一些dirty code的問題。
http://www.ithome.com.tw/node/83209
http://keystonegame.pixnet.net/blog/post/17243817-%E7%A8%8B%E5%BC%8F%E7%A2%BC%E5%A3%9E%E5%91%B3%E9%81%93(code-bad-smell)

5.IPv4 Internal IP

6.Agile Scrum


參考資料:
http://sls.weco.net/node/21327
http://www.ithome.com.tw/node/83209
http://keystonegame.pixnet.net/blog/post/17243817-%E7%A8%8B%E5%BC%8F%E7%A2%BC%E5%A3%9E%E5%91%B3%E9%81%93(code-bad-smell)
https://toggl.com/developer-methods-infographic


2016年10月11日 星期二

C/C++ call by value, call by address, call by reference

標頭都加上
#include <iostream>
using namespace std;
然後使用dev c++

==============================================

int main()
{
  int i=1;
  cout<< i <<endl;  // print 1
}

==============================================

int main()
{
  int i=1;
  cout<< &i <<endl; // print i address
}

==============================================

int main()
{
  int i=1;
  int &j=i;  //讓j的位址指向i的位址(兩個位址會一樣)
  cout<< j << endl; //print j values (That is i values)
  cout<< &j << endl;  // print j address (That is i address)
}

==============================================

int main()
{
  int i=1;
  int *k=&i; //讓k的變數參照i的位址(兩個位址會不一樣)
  cout << k << endl;  // print k values => i address (所以k變數數值列印出來是i的位址
  cout << &k << endl; // print k address (是指k的位址不關變數i的事情)
  cout << *k << endl; // print i address pointer values (指的是k指標變數所參照i位址的數值)
}

=============================================


2016年10月7日 星期五

eclipse java project 應用於XAMPP MySQL

因為我是第一次用jdbc,所以就在這記錄一些事情


首先下載mysql-connector-java-XXXX-bin.jar

download link:http://dev.mysql.com/downloads/connector/j/


然後add external jars把jar檔放入

之後試著寫一段程式連接
private Connection conn=null; //Database variable
public void PracticeDB()
{
try
{
Class.forName("com.mysql.jdbc.Driver");
//register driver
conn=DriverManager.getConnection("jdbc:mysql://120.127.14.91:3306/test","root","110432008");
}catch(ClassNotFoundException e)
{
System.out.println("ClassNotFoundException:"+e.toString());
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("SQLException:"+e.toString());
}
}
view raw practiceDB hosted with ❤ by GitHub

會發現出現一個錯誤
ClassNotFoundException:java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

是因為MYSQL 預設是不允許通過遠端存取資料庫

所以必須在mysql command下指令:

1.改表

use mysql;
select user,host,password from user;

update user set host='%' where user='root';

2.授權法

grant all privileges on *.* to 'myuser'@'%' identified by 'mypassword' with grant option;

或者是特定主機才可以連線

grant all privileges on *.* to 'myuser'@'192.168.1.3' identified by 'mypassword' with grant option;

然後重開mysql,之後就能成功存取了


再來下面是實作結果
package PracticeDB;
import java.sql.*;
public class PracticeDB {
private Connection conn=null; //Database variable
private Statement stat=null;
private ResultSet rs=null;
private PreparedStatement pst=null;
private String dropDbSQL="Drop table User ";
private String createDbSQL="Create table User ( "+ "id Integer" + ", name Varchar(20) "+", passwd Varchar(20))";
//ifNULL 代表如果不是null時跑A,否則是
private String insertDbSQL="insert into User(id,name,passwd) "+"select ifNULL(max(id),0)+1,?,? From User";
private String selectDbSQL="select * from User";
public PracticeDB()
{
try
{
Class.forName("com.mysql.jdbc.Driver");
//register driver
conn=DriverManager.getConnection("jdbc:mysql://120.127.14.91:3306/test","root","110432008");
}catch(ClassNotFoundException e)
{
System.out.println("ClassNotFoundException:"+e.toString());
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("SQLException:"+e.toString());
}
}
public void creatTable()
{
try
{
stat=conn.createStatement();
stat.executeUpdate(createDbSQL);
}catch(SQLException e)
{
System.out.println("create DB SQLException:"+e.toString());
}
finally
{
close();
}
}
private void insertTable(String name, String passwd)
{
try {
pst=conn.prepareStatement(insertDbSQL);
pst.setString(1, name);
pst.setString(2, passwd);
pst.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
close();
}
}
public void selectTable()
{
try
{
stat=conn.createStatement();
rs=stat.executeQuery(selectDbSQL);
System.out.println("ID\t\tName\t\tPAAWORD");
while(rs.next())
{
System.out.println(rs.getInt("id")+"\t\t"+rs.getString("name")+"\t\t"+rs.getString("passwd"));
}
}catch(SQLException e)
{
System.out.println("select table SQLException:"+e.toString());
}
finally
{
close();
}
}
public void dropTable()
{
try
{
stat=conn.createStatement();
stat.executeUpdate(dropDbSQL);
}catch(SQLException e)
{
System.out.println("drop table SQLException:"+e.toString());
}
}
public void close()
{
try
{
if(rs!=null)
{
rs.close();
rs=null;
}
if(stat!=null)
{
stat.close();
stat=null;
}
if(pst!=null)
{
pst.close();
pst=null;
}
}catch(SQLException e)
{
System.out.println("close SQLException:"+e.toString());
}
}
public static void main(String args[])
{
PracticeDB paracticeDB=new PracticeDB();
paracticeDB.dropTable();
paracticeDB.creatTable();
paracticeDB.insertTable("mark","1234");
paracticeDB.selectTable();
}
}
view raw gistfile1.txt hosted with ❤ by GitHub
reference:
https://blog.yslifes.com/archives/918
https://my.oschina.net/weiweiblog/blog/664373

2016年9月30日 星期五

Java 關於ArrayList 深度複製

自從學會ArrayList泛型使用,我就開始愛上他來做陣列使用。

簡單的泛型使用類似下面code,第一段是簡單的int泛型,第二段是int[]的陣列。

static void parameterInt()
{
ArrayList<Integer> arrayList=new ArrayList<Integer>();
for(int i=0;i<10;i++)
{
arrayList.add(i);
}
for(int i:arrayList)
{
System.out.print(i+",");
}
}
static void parameterIntArray()
{
ArrayList<int[]> arrayList=new ArrayList<int[]>();
for(int i=0;i<10;i++)
{
int[] intArray=new int[10];
for(int j=0;j<10;j++)
{
intArray[j]=i*j;
}
arrayList.add(intArray);
}
for(int[] i:arrayList)
{
for(int j=0;j<i.length;j++)
{
System.out.print(i[j]+",");
}
System.out.println("");
}
}
然後ArrayList也能使用物件來當參數,例如下面:
static void parameterObject()
{
ArrayList<ParObject> arrayList=new ArrayList<ParObject>();
for(int i=0;i<10;i++)
{
ParObject parObject=new ParObject();
parObject.i=i;
parObject.s=String.valueOf(10-i);
arrayList.add(parObject);
}
for(ParObject parObject:arrayList)
{
System.out.println("ParObject i="+ parObject.i+",s="+parObject.s);
}
}
view raw gistfile1.txt hosted with ❤ by GitHub
class ParObject
{
int i;
String s;
}
view raw gistfile2.txt hosted with ❤ by GitHub


ArrayList使用容易,也很好分辨

如果你要複製一樣的ArrayList,可以用以下的式子
static void parameterInt()
{
ArrayList<Integer> arrayList=new ArrayList<Integer>();
for(int i=0;i<10;i++)
{
arrayList.add(i);
}
for(int i:arrayList)
{
System.out.print(i+",");
}
System.out.println();
ArrayList<Integer> arrayListCopy=new ArrayList<Integer>(arrayList);
for(int i:arrayListCopy)
{
System.out.print(i+",");
}
for(int i=0;i<10;i++)
{
arrayList.set(0, 5);
}
System.out.println();
for(int i:arrayListCopy)
{
System.out.print(i+",");
}
}
view raw gistfile1.txt hosted with ❤ by GitHub
但是,如果你是使用ArrayList<陣列 or 物件>,你就要特別小心了

例如下面
static void parameterIntArray()
{
ArrayList<int[]> arrayList=new ArrayList<int[]>();
for(int i=0;i<10;i++)
{
int[] intArray=new int[10];
for(int j=0;j<10;j++)
{
intArray[j]=i*j;
}
arrayList.add(intArray);
}
for(int[] i:arrayList)
{
for(int j=0;j<i.length;j++)
{
System.out.print(i[j]+",");
}
System.out.println("");
}
ArrayList<int[]> arrayListCopy=new ArrayList<int[]>(arrayList);
for(int[] i:arrayListCopy)
{
for(int j=0;j<i.length;j++)
{
System.out.print(i[j]+",");
}
System.out.println("");
}
for(int i=0;i<10;i++)
{
for(int j=0;j<10;j++)
{
arrayList.get(i)[j]=5;
}
}
for(int[] i:arrayListCopy)
{
for(int j=0;j<i.length;j++)
{
System.out.print(i[j]+",");
}
System.out.println("");
}
}
view raw gistfile1.txt hosted with ❤ by GitHub

可以發現到當arrayList改變時,arrayListCopy數值也會跟著改變,是因為ArrayList是淺度複製,當參數是單純變數時(例:int, String, boolean),複製的arrayListCopy不會改變,但當參數是陣列 or 物件,ArrayList<int[]> arrayListCopy=new ArrayList<int[]>(arrayList); arrayListCopy 和 arrayList指向的是同一個記憶體位置,所以會造成某個ArrayList改變時,另一個就會跟著改變。

而如果要簡單解決這問題的話,只要做下面的方法就行了:
ArrayList<int[]> arrayListCopy=new ArrayList<int[]>(arrayList);
改成
 ArrayList<int[]> arrayListCopy=new ArrayList<int[]>();
    
 for(int[] copy:arrayList)
 {
    arrayListCopy.add(copy.clone());
 }

    

一個一個陣列把他複製下來。

也可以使用 BeanUtils.cloneBean來把它複製。

2016年9月1日 星期四

Java使用Matlab封裝成的.jar檔(R2015b)

一開始必須要環境準備

1.設置Java JDK1.7X (不能使用JDK1.8以上的版本,會造成Error during packaging ,可以參考這篇文章)

2.設置環境變數(可以參考此文章來設置)
(1)JAVA_HOME (JDK的安裝位置,如C:\Program Files\Java\jdk1.7.0_79) 
  • 設置後,重啟matlab才有效果。
  • 使用getenv JAVA_HOME在Matlab的Command Window中下指令,看看得到的返回職是否正確,如正確會出現以下對話。
2Classpath
  • 添加matlabInstallRoot \toolbox\javabuilder\jar\javabuilder.jar
3Path
3.在Matlab Command Window 中下deploytool指令 ,會出現以下圖示|


之後點選Library Compiler,會出現以下圖示,然後在TYPE往下拉找到Java Package
這時候,這邊步驟先到此,因為我們必須先寫一個*.m副程式檔案出來,給Matlab封裝成.jar檔

我們寫的程式碼很簡單如下圖,可以參考此文章寫出matlab副程式,然後將此檔另存新黨到你想要的目錄底下
然後,我們再回到Library Compiler步驟,我們在藍色筆跡那邊點進去,然後把test.m檔給新增進去
然後輸入Library Nam,我是輸入LibraryTest,之後輸入下方的ClassName,我是輸入CallFunction,這時候可以發現到,我的test.m的方法已經出現在Class Name的旁邊

之後按下右上方的Package等他封裝完成在你Settings所指定的目錄底下就行了
之後會出現檔案目錄出來,之後點選for_testing目錄,可以看到LibraryTest.jar在裡面了





最後我以Intellij IDEA 來展示如何使用封裝後的*.jar檔案


1.先開一個空專案,如下圖
之後同時按下SHIFT+CTRL+ALT+S(window底下)開啟Project structure
有個+號點進去,之後點資料夾找到你的.jar檔所在,新增進去,之後Apply

然後在點+號,再新增一個Matlab會使用到的.jar檔,此檔案在

matlabInstallRoot \toolbox\javabuilder\jar\javabuilder.jar


之後在程式碼加上幾行指令,呼叫.jar檔裡的CallFunction類別,建立出物件(建立實例物件需要花費1~2S時間,不知道為什麼,還沒詳細爬文),
然後利用Object陣列變數接收所呼叫的值,這邊需要注意的是CallFunction.test(2,1),第一個參數是指回傳回來的參數個數,第二個是你要傳值給test方法計算的數值,如果你還有更多需要傳值的數值,就繼續寫在後面即可(但必須test方法裡也有符合的參數個數)

此外,你必須加上一個try catch接收Matlab jar有可能引發的錯誤訊息(如:
MWException e)

最後你就能看到你的程式碼執行成功了,如下圖

2016年6月29日 星期三

Java SocketServer的運用

最近實作簡單的SocketServer,可以互相多人通訊

先來講講 我實作的 Server Client 概念

我把SocketServer分為四個部分
public static void main (String[] args)
{
SocketServer socketServer=new SocketServer();
socketServer.initLayout();
socketServer.setIPAdrress();
socketServer.initRequestListener();
socketServer.serverReceiver();
}
view raw Main hosted with ❤ by GitHub

第一部分initLayout(),我利用swing來繪製程式,主要是宣告一個panel,然後把繪圖元件都丟進去panel裡,再利用fame新增panel,在更新畫面(fame.ravalidate())

第二部分setIPAdrress(),利用InetAddress物件,把自身IP放入在LBIpAds.setText()。

第三部分initRequestListener(),把TFmsg TextField增加傾聽者(KeyListener),傾聽
TFmsgKeyListener物件,裡面主要功能是keyReleased(KeyEvent event),當按下按鈕放開時,會觸發這個功能。

第四部分是serverReceiver(),我宣告兩個變數ServerSocket和ExecutorService,ServerSocket放入自身接收Port,LISTEN_PORT=2525,而ExecutorService 則是接收當有ServerSocket回應(
serverSocket.accept)把 ServerReceiveThread( socket )放入threadExecutor(Thread Pool)


我們來講解一下ServerReceiveThread部分,這是當有Client回應時,Server會專門創立一個Thread給它,一直傾聽有沒有訊息回來。而ServerRequestThread部分,則是Server想要發送訊息,或者是當有Client傳訊息到Serever再轉發給其他Client時,會使用的物件。


再來是SocketClient部分,也分為四個部分
public static void main (String[] args)
{
SocketClient socketClient=new SocketClient();
socketClient.initLayout();
socketClient.setIPAdrress();
socketClient.initSocketClient("10.105.1.56", LISTEN_PORT);
socketClient.initRequestListener();
}
view raw Main hosted with ❤ by GitHub
前兩個部分和Server一樣,
第三部分是initSocketClient(String host,int port)利用new Socket( host, port );連線遠端的Server給他一個Thread執行傾聽遠端Server的訊息這部分和Server一樣

而initRequestListener()部分,也是和Server一樣,傾聽鍵盤回應,然後發送給ClientRequestThread,讓他傳送到Server。

以下是程式碼,可以直接執行
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import javax.swing.*;
public class SocketClient {
String[] test={"cat","dog","fish"};
JFrame fame;
JPanel panel;//setLayout=null
JLabel LBmsg;
JTextField TFmsg;
JLabel LBIpAds;
JTextArea TAcontent;
JScrollPane SPcontent;
JButton BTdisconnectAll;
JButton BTdisconnectUser;
JComboBox CBuser;
public static final int LISTEN_PORT = 2525;
String msg="";
Socket socket = null;
public static void main (String[] args)
{
SocketClient socketClient=new SocketClient();
socketClient.initLayout();
socketClient.setIPAdrress();
socketClient.initSocketClient("10.105.1.56", LISTEN_PORT);
socketClient.initRequestListener();
}
public void initLayout()
{
fame=new JFrame("Socket Client");
panel=new JPanel(null);//setLayout=null
LBmsg=new JLabel("由此傳送訊息:");
TFmsg=new JTextField();
LBIpAds=new JLabel("IP Address:");
TAcontent=new JTextArea("");
SPcontent=new JScrollPane(TAcontent,ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
BTdisconnectAll=new JButton("斷開Server");
BTdisconnectUser=new JButton("斷開所選用戶");
CBuser=new JComboBox(test);
fame.setBounds(0,0,600,500);
fame.setVisible(true);
fame.setResizable(false);
LBmsg.setLocation(10,10);
LBmsg.setSize(100,30);
TFmsg.setLocation(110,10);
TFmsg.setSize(450,30);
LBIpAds.setLocation(10,50);
LBIpAds.setSize(400,30);
TAcontent.setLineWrap(true);
SPcontent.setLocation(10,90);
SPcontent.setSize(400,350);
BTdisconnectAll.setLocation(420,90);
BTdisconnectAll.setSize(150,50);
BTdisconnectUser.setLocation(420,150);
BTdisconnectUser.setSize(150,50);
CBuser.setLocation(420,220);
CBuser.setSize(150, 20);
panel.add(LBmsg);
panel.add(TFmsg);
panel.add(LBIpAds);
panel.add(SPcontent);
panel.add(BTdisconnectAll);
panel.add(BTdisconnectUser);
panel.add(CBuser);
fame.add(panel);
fame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
fame.revalidate() ;
}
public void setIPAdrress()
{
InetAddress adr = null;
try {
adr = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
LBIpAds.setText("IP Address:"+adr.getHostAddress());
}
public void initSocketClient(String host,int port)
{
try
{
socket = new Socket( host, port );
socket.setSoTimeout(100000);//處理時間過長,SocketTimeoutException
new Thread(new ClientReceiveThread()).start();
new Thread(new ClientRequestThread("test1")).start();
new Thread(new ClientRequestThread("test2")).start();
}
catch ( IOException e )
{
e.printStackTrace();
}
}
public void initRequestListener()
{
TFmsg.addKeyListener(new TFmsgKeyListener());
}
/**
* 處理Server端 User想要發送訊息。
*/
class TFmsgKeyListener implements KeyListener
{
@Override
public void keyReleased(KeyEvent event)
{
if(event.getKeyCode()==10)
{
TAcontent.append("ClientSelf:"+TFmsg.getText()+"\t\n");
new Thread(new ClientRequestThread(TFmsg.getText())).start();;
TFmsg.setText("");
}
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
}
class ClientReceiveThread implements Runnable
{
DataInputStream input = null;
public ClientReceiveThread()
{
try
{
input = new DataInputStream( socket.getInputStream() );
}
catch (IOException e)
{
// TODO Auto-generated catch block
System.out.println("ClientReceiveThread error:"+e);
}
}
@Override
public void run() {
String content = null;
try
{
content=input.readUTF();
while((content=input.readUTF()) !=null) //input.readUTF()會等待stream,直到傳東西回來
{
TAcontent.append(content +"\r\n");
}
}
catch(SocketTimeoutException e)
{
TAcontent.append("連線超時:"+ e +"\r\n");
try
{
socket.close();
} catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
System.out.println("ClientReceiveThread run error:"+e);
try
{
socket.close();
} catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
class ClientRequestThread implements Runnable
{
DataOutputStream output = null;
String msg;
public ClientRequestThread(String msg)
{
try
{
output = new DataOutputStream(socket.getOutputStream());
this.msg=msg;
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run()
{
try
{
output.writeUTF( msg );
output.flush();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
view raw SocketClient hosted with ❤ by GitHub
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.*;
public class SocketServer {
/*------------Layout Panel-------------*/
JFrame fame;
JPanel panel;
JLabel LBmsg;
JTextField TFmsg;
JLabel LBIpAds;
JTextArea TAcontent;
JScrollPane SPcontent;
JButton BTdisconnectAll;
JButton BTdisconnectUser;
JComboBox CBuser;
/*------------Use Variable-------------*/
public static final int LISTEN_PORT = 2525;
//define store all ArrayList of Socket and then package is sofe thread
public static List<Socket> socketList=Collections.synchronizedList(new ArrayList());
public static void main (String[] args)
{
SocketServer socketServer=new SocketServer();
socketServer.initLayout();
socketServer.setIPAdrress();
socketServer.initRequestListener();
socketServer.serverReceiver();
}
public void initLayout()
{
fame=new JFrame("Socket Server");
panel=new JPanel(null);//setLayout=null
LBmsg=new JLabel("由此傳送訊息:");
TFmsg=new JTextField();
LBIpAds=new JLabel("IP Address:");
TAcontent=new JTextArea("");
SPcontent=new JScrollPane(TAcontent,ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
BTdisconnectAll=new JButton("斷開Server");
BTdisconnectUser=new JButton("斷開所選用戶");
CBuser=new JComboBox();
fame.setBounds(0,0,600,500);
fame.setVisible(true);
fame.setResizable(false);
LBmsg.setLocation(10,10);
LBmsg.setSize(100,30);
TFmsg.setLocation(110,10);
TFmsg.setSize(450,30);
LBIpAds.setLocation(10,50);
LBIpAds.setSize(400,30);
TAcontent.setLineWrap(true);
SPcontent.setLocation(10,90);
SPcontent.setSize(400,350);
BTdisconnectAll.setLocation(420,90);
BTdisconnectAll.setSize(150,50);
BTdisconnectUser.setLocation(420,150);
BTdisconnectUser.setSize(150,50);
CBuser.setLocation(420,220);
CBuser.setSize(150, 20);
panel.add(LBmsg);
panel.add(TFmsg);
panel.add(LBIpAds);
panel.add(SPcontent);
panel.add(BTdisconnectAll);
panel.add(BTdisconnectUser);
panel.add(CBuser);
fame.add(panel);
fame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
fame.revalidate() ;
}
public void setIPAdrress()
{
InetAddress adr = null;
try {
adr = InetAddress.getLocalHost(); //IPv6
adr =Inet4Address.getLocalHost();//IPv4
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
LBIpAds.setText("IP Address:"+adr.getHostAddress());
}
public void initRequestListener()
{
TFmsg.addKeyListener(new TFmsgKeyListener());
}
public void serverReceiver()
{
ServerSocket serverSocket = null;
ExecutorService threadExecutor = Executors.newCachedThreadPool(); //建立Thread Pool,讓Client可以連進來不斷線
try
{
serverSocket = new ServerSocket( LISTEN_PORT );
TAcontent.append("Server listening requests..."+"\r\n");
while ( true )// 不斷接收來自網路客戶端的連接請求
{
Socket socket = serverSocket.accept();
synchronized(socketList)
{
socketList.add(socket);
System.out.println("123sum:"+socketList.size());
threadExecutor.execute( new ServerReceiveThread( socket ) );
}
}
}
catch ( IOException e )
{
e.printStackTrace();
}
finally
{
if ( threadExecutor != null )
threadExecutor.shutdown();
if ( serverSocket != null )
try
{
serverSocket.close();
}
catch ( IOException e )
{
e.printStackTrace();
}
}
}
/**
* 處理Server端 User想要發送訊息。
*/
class TFmsgKeyListener implements KeyListener
{
@Override
public void keyReleased(KeyEvent event)
{
if(event.getKeyCode()==10)
{
TAcontent.append("Server:"+TFmsg.getText()+"\t\n");
new Thread(new ServerRequestThread(TFmsg.getText())).start();;
TFmsg.setText("");
}
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
}
/**
* 處理Server端的Receive接收執行緒。
*/
class ServerReceiveThread implements Runnable
{
private Socket clientSocket;
DataInputStream input = null;
public ServerReceiveThread( Socket clientSocket )
{
this.clientSocket = clientSocket;
}
@Override
public void run()
{
TAcontent.append("有"+clientSocket.getRemoteSocketAddress() +"連線進來!"+"\r\n");
UpdateCBuser(String.valueOf(clientSocket.getRemoteSocketAddress()),"add"); //CBuser新增user
try
{
input = new DataInputStream( this.clientSocket.getInputStream() );
while ( true )
{
//這部分,Server回應太快,Client還沒開啟所以訊息會loss
new Thread(new ServerRequestThread(String.format("Hi, %s!\n", clientSocket.getRemoteSocketAddress() ))).start();
break;
}
String content=null;
while((content=readFromClient())!=null)
{
TAcontent.append(content + "\r\n");
new Thread(new ServerRequestThread(content)).start();
}
}
catch ( IOException e )
{
e.printStackTrace();
}
finally
{
try
{
if ( input != null )
{
input.close();
System.out.println("input close");
}
if ( this.clientSocket != null || !this.clientSocket.isClosed() )
{
this.clientSocket.close();
System.out.println("clientSocket close");
}
}
catch ( IOException e )
{
e.printStackTrace();
}
}
}
private String readFromClient()
{
try
{
return input.readUTF();
}
catch(IOException e)
{
socketList.remove(clientSocket);
UpdateCBuser(String.valueOf(clientSocket.getRemoteSocketAddress()),"remove"); //CBuser新增user
}
return null;
}
}
/**
* 處理Client端的Request請求執行緒。
*/
class ServerRequestThread implements Runnable
{
DataOutputStream output = null;
String msg="";
public ServerRequestThread(String msg)
{
this.msg=msg;
}
@Override
public void run() //這部分不知道Runnable run完會不會自動清除DataOutputStream output
{
// TODO Auto-generated method stub
synchronized(socketList)
{
System.out.println("sum:"+socketList.size());
for(Socket socket:socketList)
{
try
{
output = new DataOutputStream( socket.getOutputStream() );
output.writeUTF(this.msg);
output.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
void UpdateCBuser(String User ,String action)
{
if(action=="add")
{
CBuser.addItem(User);
CBuser.setSelectedIndex(0);
System.out.println(CBuser.getSelectedIndex());
}
else if(action=="remove")
{
CBuser.removeItem(User);
}
CBuser.revalidate();
CBuser.repaint();
panel.revalidate();
panel.repaint();
fame.revalidate();
fame.repaint();
}
}
view raw SocketServer hosted with ❤ by GitHub

2016年6月21日 星期二

字元與字串

講串流之前,先釐清字元與字串

字元
一個英文字母、數字、或其他符號,我們稱為字元,要表示成一個字元時,我們可以用一對單引號

e.gs.,   char a='b'

而java中有一些特殊字元可以使用,通常用反斜線與一個字元作組合,我們稱之為 逸出序列(escape sequence),而反斜線又稱為逸出字元(escape character)

常見的逸出序列有以下:
1.\n   換行符號
2.\t   水平定位鍵
3.\r   歸位字元
4.\\   列印反斜線
5.\"   列印雙引號

而電腦儲存字元的方式是以八位元整數(1 Byte)來儲存而儲存的整數與符號的對應關係我們稱之為ASCII碼(American Standard Code for Information Interchange) 以前常聽到的對應就是'a'=36 'A'=97

字串
字串顧名思義是一段文字,通常使用一對雙引號將一段文字夾起來,而英文字會佔1Byte,中文字佔2Bytes,而我們要判斷一段文字是否有中文則可以使用

String s="您好";
System.out.println((s.getBytes().length==s.length())?"無中文":"有中文");

利用Bytes總數和字串長度做比對。

2016年6月1日 星期三

粒子群演算法運用及Java程式碼


粒子群主要決策利用「自身經驗」與「其他人經驗」進行決策。

粒子每一次自身經驗都有適應值,可以衡量這次經驗的好壞,
並且有記憶性可以紀錄每次經驗的位置與適應值。

PSO流程圖


PSO表達式





Vid(t+1):下一次粒子的速度
Vid(t):這次粒子的速度
Pid(T):粒子所經過最好的位置(每個粒子都有一個最好位置)
Xid(t):粒子這次的位置
Gid(T):粒子群所經過最好的位置(一個粒子群只會有一個最好位置)
C1,C2:控制且避免數值太大
Xid(t+1):粒子下次的位置


演算法練習:

1.主要是初始化一開始粒子群Initialization,然後依據繁延代數,進行移動ParticleMove,在這個方法裡我有利用varyVector1、varyVector2來控制,避免數值太大,最後如果數值出過-4~4間,強迫介於在這,不然變化量太大造成位置移動有問題。

2.Parameter沒有使用到封裝,如果需要再自行更改程式碼。

3.利用JFreeChart free lib來畫出JFreeLineChart迭代圖



import java.util.Timer;
import java.util.TimerTask;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.ApplicationFrame;
public class JFreeLineChart extends ApplicationFrame
{
DefaultCategoryDataset dataset = new DefaultCategoryDataset( );
JFreeChart lineChart;
public JFreeLineChart(String title,String chartTitle)
{
super(title);
lineChart = ChartFactory.createLineChart(
chartTitle,
"Period","Fitness Number",
dataset,
PlotOrientation.VERTICAL,
true,true,false);
ChartPanel chartPanel = new ChartPanel( lineChart );
chartPanel.setPreferredSize( new java.awt.Dimension( 1000 , 500 ) );
setContentPane(chartPanel);
CategoryPlot plot = (CategoryPlot)lineChart.getPlot();
}
public void UpdataDataset(double fitness,String name,int period)
{
dataset.addValue( fitness , name , String.valueOf(period));
}
public void UpdataLayout(int timerStart,int timerSpeed)
{
Timer t = new Timer();
CategoryPlot plot = (CategoryPlot)lineChart.getPlot();
t.schedule(new TimerTask()
{
public void run()
{
plot.setDataset(dataset);;
}
},timerStart,timerSpeed);
}
}
view raw JFreeLineChart hosted with ❤ by GitHub
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Random;
import org.jfree.ui.RefineryUtilities;
/*
* topic
*
* find min number problem
*
* z=x1^2+2*x2^2-0.3cos(3*3.14*x1)-0.4cos(4*3.14*x2)+0.7
* x1,x2 belong -100~100
*
* first step ,define initialization
*/
public class main
{
private static int groupCount=100;
private static int period=1000000;
private static int max=100,min=-100;
private static int maxV=(max-min)/50; // max velocity
private static double varyVector1=0.1,varyVector2=0.1; //controller vary vector
private static ArrayList<Parameter> listParticle=new ArrayList<Parameter>();
private static Parameter gBest=new Parameter();
private static Particle particle;
private static JFreeLineChart jFreeLineChart;
public static void main(String args[])
{
createParticle();
createJFreeLineChart();
for(int i=0;i<period;i++)
{
listParticle=particle.ParticleMove(listParticle,gBest);
Parameter beforegBest=gBest; // not print too much value
gBest=particle.FindGlobalBest(listParticle.get(0),gBest);
if(beforegBest.pBestFitness>gBest.pBestFitness)
{
particle.showGlobal(i,gBest);
jFreeLineChart.UpdataDataset(gBest.pBestFitness, "Particle", i);
}
}
System.out.println("happy end");
}
private static void createParticle()
{
particle=new Particle(groupCount,max,min,maxV,varyVector1,varyVector2);
listParticle=particle.Initialization(listParticle);
gBest=listParticle.get(0);
}
private static void createJFreeLineChart()
{
jFreeLineChart=new JFreeLineChart("Particle Line Chart","Fitness of Particle");
jFreeLineChart.pack( );
RefineryUtilities.centerFrameOnScreen( jFreeLineChart );
jFreeLineChart.setVisible( true );
jFreeLineChart.UpdataLayout(1000,1000);
}
}
view raw main hosted with ❤ by GitHub
public class Parameter {
public double positionX1,positionX2,vectorX1,vectorX2;
public double fitness;
public double pBestFitness;
public double pBestPositionX1;
public double pBestPositionX2;
}
view raw Parameter hosted with ❤ by GitHub
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Random;
public class Particle
{
private int groupCount;
private int max,min;
private int maxV; // max velocity
private double varyVector1,varyVector2; //controller vary vector
private final DecimalFormat df = new DecimalFormat("###.#######"); //controller decimal format
private Random rand=new Random();
Particle(int groupCount,int max,int min,int maxV,double varyVector1,double varyVector2)
{
this.groupCount=groupCount;
this.max=max;
this.min=min;
this.maxV=maxV;
this.varyVector1=varyVector1;
this.varyVector2=varyVector2;
}
public ArrayList<Parameter> Initialization(ArrayList<Parameter> list)
{
Parameter parameter;
double number;
for(int i=0;i<groupCount;i++)
{
parameter=new Parameter();
number=rand.nextDouble()*(max-min)+min;
parameter.positionX1=number;
number=rand.nextDouble()*maxV-maxV/2;
parameter.vectorX1=number;
number=rand.nextDouble()*(max-min)+min;
parameter.positionX2=number;
number=rand.nextDouble()*maxV-maxV/2;
parameter.vectorX2=number;
parameter=FitnessEquation(parameter);
parameter.pBestFitness=parameter.fitness;
parameter.pBestPositionX1=parameter.positionX1;
parameter.pBestPositionX2=parameter.positionX2;
list.add(parameter);
}
list=sortList(list);
return list;
}
public ArrayList<Parameter> ParticleMove(ArrayList<Parameter> list,Parameter gBest)
{
ArrayList<Parameter> listMove=new ArrayList<Parameter>();
Parameter parameter;
for(int i=0;i<groupCount;i++)
{
parameter=new Parameter();
parameter.vectorX1=list.get(i).vectorX1
+varyVector1*(rand.nextDouble()*2-1)*(list.get(i).pBestPositionX1-list.get(i).positionX1)
+varyVector2*(rand.nextDouble()*2-1)*(gBest.positionX1-list.get(i).positionX1);
if(parameter.vectorX1>4) //avoid too large vector
parameter.vectorX1=4;
else if(parameter.vectorX1<-4)
parameter.vectorX1=-4;
parameter.positionX1=list.get(i).positionX1+list.get(i).vectorX1;
if(parameter.positionX1>max) // avoid x1 exceed range
parameter.positionX1=max;
if(parameter.positionX1<min)
parameter.positionX1=min;
parameter.vectorX2=list.get(i).vectorX2
+varyVector1*(rand.nextDouble()*2-1)*(list.get(i).pBestPositionX2-list.get(i).positionX2)
+varyVector2*(rand.nextDouble()*2-1)*(gBest.positionX2-list.get(i).positionX2);
if(parameter.vectorX2>4)//avoid too large vector
parameter.vectorX2=4;
else if(parameter.vectorX2<-4)
parameter.vectorX2=-4;
parameter.positionX2=list.get(i).positionX2+list.get(i).vectorX2;
if(parameter.positionX2>max)// avoid x2 exceed range
parameter.positionX2=max;
if(parameter.positionX2<min)
parameter.positionX2=min;
parameter=FitnessEquation(parameter);
listMove.add(parameter);
if(list.get(i).pBestFitness>listMove.get(i).fitness) //find
{
listMove.get(i).pBestFitness=listMove.get(i).fitness;
listMove.get(i).pBestPositionX1=listMove.get(i).positionX1;
listMove.get(i).pBestPositionX2=listMove.get(i).positionX2;
}
else
{
listMove.get(i).pBestFitness=list.get(i).pBestFitness;
listMove.get(i).pBestPositionX1=list.get(i).positionX1;
listMove.get(i).pBestPositionX2=list.get(i).positionX2;
}
}
listMove=sortList(listMove);
return listMove;
}
public Parameter FindGlobalBest(Parameter list,Parameter gbest)
{
if(gbest.pBestFitness>list.pBestFitness)
gbest=list;
return gbest;
}
public void showList(int age,ArrayList<Parameter> list)
{
System.out.println("第"+age+"代");
for(int i=0;i<groupCount;i++)
{
System.out.println("x1="+list.get(i).positionX1+",vx1="+list.get(i).vectorX1+
",x2="+list.get(i).positionX2+",vx2="+list.get(i).vectorX2+",適應值="+list.get(i).fitness);
}
}
public void showGlobal(int age,Parameter parameter)
{
System.out.println("第"+age+"代");
System.out.println("x1="+parameter.positionX1+",v1="+parameter.vectorX1+
",x2="+parameter.positionX2+",v2="+parameter.vectorX2+",適應值="+parameter.pBestFitness);
}
public Parameter FitnessEquation(Parameter parameter)
{
parameter.fitness=Math.pow(parameter.positionX1,2)+Math.pow(parameter.positionX2,2)-0.3*Math.cos(3*Math.PI*parameter.positionX1)-0.4*Math.cos(4*Math.PI*parameter.positionX2)+0.7;
return parameter;
}
public ArrayList<Parameter> sortList(ArrayList<Parameter> list)
{
//sort array
Collections.sort(list,new Comparator<Parameter>()
{
@Override
public int compare(Parameter o1, Parameter o2)
{
// TODO Auto-generated method stub
if(Double.compare(o1.fitness, o2.fitness)==-1)
return -1;//o1>o2 ,higher then the front
else if(Double.compare(o1.fitness, o2.fitness)==0)
return 0;
else
return 1;
}
});
return list;
}
}
view raw Particle hosted with ❤ by GitHub

2016年5月18日 星期三

Scala shell for Eclipse

在終端機下達指令brew install scala

Scala IDE for Eclipse 安裝

Help->Install New Software->Add

Name: Scala IDE
Location: http://download.scala-ide.org/sdk/lithium/e44/scala211/stable/site

把 Scala IDE for Eclipse 和 Scala IDE for Eclipse Development Support兩個選項打勾

然後等待一段時間下載


開一個Scala專案

輸入HolloWorld.scala 檔案

object HellWorld extends App {
  println("hello,")
}

執行看看有沒有差

不能使用Application 因為
Application has been deprecated from scala 2.9, probably it has been deleted in scala 2.11 (it still exists in scala 2.10) even though at the moment I can't find proofs for that, use App instead.

2016年5月8日 星期日

基因演算法運用及程式碼

碩士期間剛好有一堂是最佳演算法,講到基因演算法的運用和作業

剛好有機會記下來,與網友們一起討論使用

題目是:


1. 題目
Max f (x1, x2 ) = 21.5 + x1 sin(4πx1) + x2 sin(20πx2 )
−3.0 ≤ x1 ≤ 12.1, 4.1 ≤ x2 ≤ 5.8
試以基因演算法求最大值f
2. 基因演算法(以流程圖或虛擬碼表示即可)
3. 設計編碼方式 (使用二進位編碼來代表 x1 x2 的值)
4. 決定群體規模 (族群數量)
5. 設計適應函數 (決定個體適應度的評估標準)
6. 決定挑選與複製方法
7. 定義交配與交配機率
8. 定義突變與突變機率
9. 決定終止條件
10. 結果與討論(含收斂過程圖)

我的解法

2.基因演算法流程圖


3.編碼方式

假設某個數值x1=11.1
X1==11.1;
If(x1==11.1)
{
  x1=(x1+3)*10;
  x1_binary=
Integer.toBinary (x1);
}
x1_binary==10001101;

假設某個數值x1 二進位= 10001101
x1_binary==10001101;
If(x1_binary==10001101)
{
  x1=Integer.valueOf(x1_binary);
  x1=x1/10-3;
}
X1==11.1;
假設某個數值x1=-3.0
X1==0;
If(x1==-3.0)
{
  x1=(x1+3)*10;
  x1_binary=
Integer.toBinary (x1);
}x1_binary== 00000000;

假設某個數值x1 二進位= 00000000
x1_binary== 00000000;
If(x1_binary==00000000)
{
  x1=Integer.valueOf(x1_binary);
  x1=x1/10-3;
}
X1==0;

4.群體規模 (族群數量)

初始群體規模為
int groundCount=10;
經過第一次交配,以後規模擴增為
copulationCount=groundCount*2;
5.適應函數
直接代入
Max f (x1, x2 ) = 21.5 + x1 sin(4πx1) + x2 sin(20πx2 )
f當適應函數

6.
挑選與複製方法
樣本基因利用公式計算出來的各個f
取出
10%優秀f樣本基因、前30%優秀樣本基因、前70%優秀樣本基因、前90%優秀樣本基因(輪盤式選擇)
複製完後放入交配池(激增兩倍基因)

7.
交配與交配機率
一開始隨機取出兩對基因
把第一對x1前四碼和第二對x2前四碼交配出新基因的x1
把第一對x2前四碼和第二對x1前四碼交配出新基因的x2
強制交配出特定數量

8.
突變與突變機率   
 在交配的時候,有十分之一的機率發生突變,當發生突變的時候,隨機x1x2發生突變,突變是隨機挑選binary的其中一個做改變。

e.gs., 10001101=>10101101(第三位發生突變)

9.
終止條件 

其繁延代數跑完,就是終止條件


10.結果與討論

 因為我起始基因個數非常的低(設定為10),所以我依靠演化(交配、突變)來使基因越來越好,但非常依靠繁延代數。

總而言之,每一代的基因都有往好的地方發展出去!所以繁延代數越高,基因品質越好。



以下是程式碼:
package com.gene;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Random;
public class Gene
{
private static int groundCount; //The sum of individual genes
private static int copulationCount; //sum of copulation is grundCount double
private static int period; // sum of generation
private static double copulationRate; //is Probability can copulation
private static double mutationRate;//is Probability can mutation
private static double max_x1;
private static double min_x1;
private static int randParameter1_x1;
private static int randParameter2_x1;
private static double max_x2;
private static double min_x2;
private static int randParameter1_x2;
private static int randParameter2_x2;
private final static DecimalFormat df = new DecimalFormat("##.#");
private static Random rand=new Random();
Gene(int groundCount,int period,double copulationRate,double mutationRate
,double max_x1,double min_x1,int randParameter1_x1,int randParameter2_x1
,double max_x2,double min_x2,int randParameter1_x2,int randParameter2_x2)
{
this.groundCount=groundCount;
copulationCount=groundCount*2;
this.period=period;
this.copulationRate=copulationRate;
this.mutationRate=mutationRate;
this.max_x1=max_x1;
this.min_x1=min_x1;
this.randParameter1_x1=randParameter1_x1;
this.randParameter2_x1=randParameter2_x1;
this.max_x2=max_x2;
this.min_x2=min_x2;
this.randParameter1_x2=randParameter1_x2;
this.randParameter2_x2=randParameter2_x2;
}
/*
由於主函式被宣告為static,而
static method內的程式碼只能呼叫static method,因此
為了要讓主函式main呼叫,故必須宣告為static
method。
*/
public ArrayList<Parameter> createListParameter()
{
ArrayList<Parameter> listParameter=new ArrayList<Parameter>();
Parameter parameter;
//查看亂數數值有沒有符合範圍,有的話add
for(int i=0;i<groundCount;i++)
{
parameter=new Parameter();
double number=100; //先設定這樣
while (number>max_x1|| number<min_x1)
{
int integer=rand.nextInt(randParameter1_x1)+randParameter2_x1;
double doub=rand.nextDouble();
number=Double.parseDouble(df.format(integer+doub));
}
parameter.setNumberX1(number);
number=100;
while (number>max_x2|| number<min_x2)
{
int integer=rand.nextInt(randParameter1_x2)+randParameter2_x2;
double doub=rand.nextDouble();
number=Double.parseDouble(df.format(integer+doub));
}
parameter.setNumberX2(number);
// 十進位轉二進位
parameter.setBinaryX1(getBinary(parameter.getNumberX1()));;
parameter.setBinaryX2(getBinary(parameter.getNumberX2()));;
parameter=equation(parameter);
listParameter.add(parameter);
}
listParameter=sortListParameter(listParameter);
return listParameter;
}
//輪盤式選擇(roulette wheel selection)
public ArrayList<Parameter> reproduction(ArrayList<Parameter> ListParameter)
{
ArrayList<Parameter> ListParameterReproduction=new ArrayList<Parameter>() ;
ArrayList<Parameter> ListParameterTop10Percents=new ArrayList<Parameter>(ListParameter.subList(0, (int)(groundCount*0.1)));
ArrayList<Parameter> ListParameterTop30Percents=new ArrayList<Parameter>(ListParameter.subList(0, (int)(groundCount*0.3)));
ArrayList<Parameter> ListParameterTop70Percents=new ArrayList<Parameter>(ListParameter.subList(0, (int)(groundCount*0.7)));
ArrayList<Parameter> ListParameterTop90Percents=new ArrayList<Parameter>(ListParameter.subList(0, (int)(groundCount*0.9)));
ListParameterReproduction.addAll(ListParameterTop10Percents);
ListParameterReproduction.addAll(ListParameterTop30Percents);
ListParameterReproduction.addAll(ListParameterTop70Percents);
ListParameterReproduction.addAll(ListParameterTop90Percents);
// ArrayList<Parameter> ListParameterCreate=new ArrayList<Parameter>(createListParameter().subList(0, (int)(groundCount*0.3)));
// ListParameterReproduction.addAll(ListParameterCreate);
ListParameterReproduction=sortListParameter(ListParameterReproduction);
return ListParameterReproduction;
}
/*
* 設定交配機率,兩個基因的x1前四碼做交換,和x2的後四碼做交換,但如果交換後數值超過限定值的話,就不交配,隨機其中一組
*/
public ArrayList<Parameter> copulation(ArrayList<Parameter> ListParameter)
{
//隨機挑兩個數值
int option1,option2;
String option1_Binaryx1, option1_Binaryx2;
String option2_Binaryx1, option2_Binaryx2;
String subBinary;
boolean isRunning=true;
ArrayList<Parameter> ListParameterCopulation=new ArrayList<Parameter>();
Parameter parameter=new Parameter();
for(int i=0;i<copulationCount;i++)
{
parameter=new Parameter();
while(isRunning==true)
{
int Probability=rand.nextInt(10);
//突變
if(Probability<1)
{
int mutationOption=rand.nextInt(ListParameter.size());
parameter=mutation(ListParameter.get(mutationOption));
}
else
{
option1=rand.nextInt(ListParameter.size());
option2=rand.nextInt(ListParameter.size());
option1_Binaryx1=ListParameter.get(option1).getBinaryX1();
option1_Binaryx2=ListParameter.get(option1).getBinaryX2();
option2_Binaryx1=ListParameter.get(option2).getBinaryX1();
option2_Binaryx2=ListParameter.get(option2).getBinaryX2();
subBinary=option1_Binaryx1.substring(0, 4)+option2_Binaryx1.substring(4, 8);
parameter.setBinaryX1(subBinary);
subBinary=option2_Binaryx2.substring(0, 4)+option1_Binaryx2.substring(4, 8);
parameter.setBinaryX2(subBinary);
parameter=getDecimal(parameter);
}
if (checkRange(parameter)==true)
isRunning=false;
}
isRunning=true;
parameter=equation(parameter);
ListParameterCopulation.add(parameter);
parameter=null;
}
ListParameterCopulation.addAll(ListParameter);
ListParameterCopulation=sortListParameter(ListParameterCopulation);
return ListParameterCopulation;
}
public Parameter mutation(Parameter parameter)
{
int mutationPart=rand.nextInt(2);
String binary;
boolean isRunning=true;
while(isRunning==true)
{
mutationPart=rand.nextInt(8);
binary=parameter.getBinaryX1();
if(mutationPart==0)
{
mutationPart=rand.nextInt(8);
binary=parameter.getBinaryX1();
if(binary.charAt(mutationPart)=='1')
{
if(mutationPart==0)
binary='0'+binary.substring(1);
else if(mutationPart==7)
binary=binary.substring(0, 7)+'0';
else
binary=binary.substring(0, mutationPart)+'0'+binary.substring(mutationPart+1);
System.out.println("原本:"+parameter.getBinaryX1()+"部分"+mutationPart+"後來:"+binary);
}
else
{
if(mutationPart==0)
binary='1'+binary.substring(1);
else if(mutationPart==7)
binary=binary.substring(0, 7)+'1';
else
binary=binary.substring(0, mutationPart)+'1'+binary.substring(mutationPart+1);
System.out.println("原本:"+parameter.getBinaryX1()+"部分"+mutationPart+"後來:"+binary);
}
parameter.setBinaryX1(binary);
parameter=getDecimal(parameter);
parameter=equation(parameter);
if(checkRange(parameter)==true)
{
isRunning=false;
return parameter;
}
}
else
{
mutationPart=rand.nextInt(8);
binary=parameter.getBinaryX2();
if(binary.charAt(mutationPart)=='1')
{
if(mutationPart==0)
binary='0'+binary.substring(1);
else if(mutationPart==7)
binary=binary.substring(0, 7)+'0';
else
binary=binary.substring(0, mutationPart)+'0'+binary.substring(mutationPart+1);
System.out.println("原本:"+parameter.getBinaryX1()+"部分"+mutationPart+"後來:"+binary);
}
else
{
if(mutationPart==0)
binary='1'+binary.substring(1);
else if(mutationPart==7)
binary=binary.substring(0, 7)+'1';
else
binary=binary.substring(0, mutationPart)+'1'+binary.substring(mutationPart+1);
System.out.println("原本:"+parameter.getBinaryX1()+"部分"+mutationPart+"後來:"+binary);
}
parameter.setBinaryX1(binary);
parameter=getDecimal(parameter);
parameter=equation(parameter);
if(checkRange(parameter)==true)
{
isRunning=false;
return parameter;
}
}
}
return parameter;
}
public void showListParameter(ArrayList<Parameter> list ,String action)
{
System.out.println(action);
for(int i=0;i<list.size();i++)
System.out.println("第"+(i+1)+"組:x1:"+list.get(i).getNumberX1()+",xb1:"+list.get(i).getBinaryX1()+",x2:"+list.get(i).getNumberX2()+",xb2:"+list.get(i).getBinaryX2()+",f:"+list.get(i).getF());
}
public ArrayList<Parameter> sortListParameter(ArrayList<Parameter> list)
{
//sort array
Collections.sort(list,new Comparator<Parameter>()
{
@Override
public int compare(Parameter o1, Parameter o2)
{
// TODO Auto-generated method stub
if(Double.compare(o1.getF(), o2.getF())==-1)
return 1;//o1>o2 ,higher then the front
else if(Double.compare(o1.getF(), o2.getF())==0)
return 0;
else
return -1;
}
});
return list;
}
public Parameter getDecimal(Parameter parameter)
{
String binaryX1=parameter.getBinaryX1();
String binaryX2=parameter.getBinaryX2();
DecimalFormat df = new DecimalFormat("##.#");
double numberX1=(double)(Integer.valueOf(binaryX1,2))/10-3;
double numberX2=(double)(Integer.valueOf(binaryX2,2))/10-3;
numberX1=Double.parseDouble(df.format(numberX1));
numberX2=Double.parseDouble(df.format(numberX2));
parameter.setNumberX1(numberX1);
parameter.setNumberX2(numberX2);
return parameter;
}
public String getBinary(double number)
{
int binary;
binary=(int)((number+3)*10);
//二進位補零算式
String binaryString=Integer.toBinaryString(0x100 | binary).substring(1);
return binaryString;
}
public boolean checkRange(Parameter parameter)
{
double numberX1=parameter.getNumberX1();
double numberX2=parameter.getNumberX2();
if(min_x1<=numberX1 && numberX1<=max_x1 && min_x2<=numberX2 && numberX2<=max_x2)
return true;
else
return false;
}
public Parameter equation( Parameter parameter)
{
double f=21.5+parameter.numberX1*Math.sin(4.0*Math.PI*parameter.numberX1)+parameter.numberX2*Math.sin(20.0*Math.PI*parameter.numberX2);
f=Double.parseDouble(df.format(f));
parameter.setF(f);
return parameter;
}
}
view raw Gene hosted with ❤ by GitHub
package com.gene;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Random;
/**
*
* @author Mark
* topic:
* Max f (x1, x2 ) = 21.5 + x1 sin(4πx1) + x2 sin(20πx2 )
* then −3.0 ≤ x1 ≤ 12.1, 4.1 ≤ x2 ≤ 5.8
*
* Genetic algorithm to find the maximum value f
*
*/
public class Main
{
public final static int groundCount=20; //The sum of individual genes
public final static int copulationCount=groundCount*2; //sum of copulation is grundCount double
public final static int period=100; // sum of generation
public final static double copulationRate=0.5; //is 0.6 Probability can copulation
public final static double mutationRate=0.1;//is 0.1 Probability can mutation
public final static double max_x1=12.1;
public final static double min_x1=-3.0;
public final static int randParameter1_x1=16;
public final static int randParameter2_x1=-3;
public final static double max_x2=5.8;
public final static double min_x2=4.1;
public final static int randParameter1_x2=2;
public final static int randParameter2_x2=4;
public final static DecimalFormat df = new DecimalFormat("##.#");
public static Random rand=new Random();
public static void main(String[] args)
{
Gene gene=new Gene(groundCount,period,copulationRate,mutationRate
,max_x1,min_x1,randParameter1_x1,randParameter2_x1,
max_x2,min_x2,randParameter1_x2,randParameter2_x2);
//create initial ListParameter
ArrayList<Parameter> ListParameter=new ArrayList<Parameter>(gene.createListParameter());
gene.showListParameter(ListParameter,"createListParameter");
for(int i=0;i<period;i++)
{
ArrayList<Parameter> ListParameterReproduction=new ArrayList<Parameter>(gene.reproduction(ListParameter));
ArrayList<Parameter> ListParameterCopulation=new ArrayList<Parameter>(gene.copulation(ListParameterReproduction));
ListParameter.removeAll(ListParameter);
ListParameter.addAll(ListParameterCopulation.subList(0, copulationCount));
gene.showListParameter(ListParameter,"第"+(i+1)+"代");
}
System.out.println(Integer.toBinaryString(0x100 | 0).substring(1));
}
}
view raw Main hosted with ❤ by GitHub
package com.gene;
public class Parameter
{
double numberX1;
String binaryX1;
double numberX2;
String binaryX2;
double f;
void setNumberX1(double numberX1)
{
this.numberX1=numberX1;
}
void setBinaryX1(String binaryX1)
{
this.binaryX1=binaryX1;
}
double getNumberX1()
{
return numberX1;
}
String getBinaryX1()
{
return binaryX1;
}
void setNumberX2(double numberX2)
{
this.numberX2=numberX2;
}
void setBinaryX2(String binaryX2)
{
this.binaryX2=binaryX2;
}
double getNumberX2()
{
return numberX2;
}
String getBinaryX2()
{
return binaryX2;
}
void setF(double f)
{
this.f=f;
}
double getF()
{
return f;
}
void clear()
{
numberX1=0;
binaryX1=null;
numberX2=0;
binaryX1=null;
f=0;
}
}
view raw Parameter hosted with ❤ by GitHub