顯示具有 Java 標籤的文章。 顯示所有文章
顯示具有 Java 標籤的文章。 顯示所有文章

2017年1月18日 星期三

[Java] 將照片的像素資料儲存成csv檔

之前Show Me The Code的講者介紹 Machine Learning 的 Python版本,上星期找到如何用 R 做之後,就只差準備資料。

記得學Java時有處理過圖片的。以下就是要將 3 (MaxN) 張 32*32 (Heigth*Width) 的JPEG 相片,轉換成灰階資料,儲存成 3*1024 的CSV 檔案。

當中幾個 Functions 提供以下功能:
  1. 相片轉換成灰度,記錄到 2D Array:
    convertTo2DUsingGetRGB() 或 convertTo2DWithoutUsingGetRGB()
  2. 2D Array 轉換成 1D Array:
    two2oneD()
  3. 3. 2D Array 儲存成 Csv 檔:
    save2csv()

2016年12月21日 星期三

[Java/Excel] 用 Eratosthenes Sieve (和 Euler Sieve) 求質數表,以及因式分解

上星期想破頭的數論之後,這星期都在看質數相關的Coding。

雖然最終要求的是:$ x^2+y^2 =N $ 的整數解,過程中也回顧了 Eratosthenes's Sieve 求質數表,和用質數表做因式分解 的方法。所用的語言方面,一個目標是自己想要熟習,而且資源又常見的Java;另一個是如果自己在中學時期想這樣做的話,應該會用到的VBA。

Java的例子不少,但試過才知道即使實現的是同一套算法,效率也可以有很大差別。從前只知道應用數學中會看一套算法的Big O去比較時間複雜度,但原來實踐起來用什麼語言、什麼變數物件,結果用什麼什麼形式去表現⋯⋯都會大大影響速度。就是為了找出實際運行得更快的寫法,就一頭栽到這個質數的做法上。雖然一開始時用LinkedList、Map等寫法真的很方便理解,但之後還是儘量換成基本的陣列。

下面這樣的Java寫的  Eratosthenes Sieve 求 一億($10^8$)之內的質數,大約是10秒。如果不計最後一個for loop用來製作傳回值的LinkedList<Integer>的話,主流程大約4秒。不過要求更大的質數,應該還要考慮該程式對使用整數的上限(int: [-2,147,483,648, 2,147,483,647]),大數字在記憶體的儲存方法,整數表的儲存方法等。很多事情都是這樣吧,開始時只要求做到是容易的,但要追求深究下去就會困難⋯⋯

最後還有兩個方法是Modified Eratosthenes Sieve 和 Euler Sieve,都是理論上應該更有效率的算法,不過實踐起來還是達不到應有的分別,要怪我對如何更好地寫代碼還是不熟識吧。 Eratosthenes Sieve的Modification的想法是一開始就不考慮2和3的倍數,只看6k+1和6k+5的情況。至於 Euler Sieve 是改善Eratosthenes Sieve中一個合成數會重覆被質數篩去而浪費的時間,例如,合成數6 會在篩選質數 2和3 的倍數時重覆考慮。理想中Eratosthenes Sieve的時間複雜度是 O( n*log(log(n)) ),而Euler Sieve的時間複雜度是O(n)。實測中,同樣求一億($10^8$)之內的質數,大約是2-3秒的時間。

2016年12月4日 星期日

Android + Arduino 小車的手機藍牙遙控計劃

對於手機的Android Apps今次是作為初學者的第一個項目。但不枉我在這次印度公幹期間,電腦之外,我都執了幾件零件和書。在印度試好了如何在Android上用藍牙連接Arduino,簡單的按鍵去傳送方向指令(數字),和預備日後作其他用途的顯示和輸入介面。詳細的檔案己經放到下面的dropbox link。
Arduino Sketch: https://dl.dropboxusercontent.com/u/71621110/Blogger/Sketch_CarBT.ino
Android Project: https://dl.dropboxusercontent.com/u/71621110/Blogger/myFirstBluetoothApp.zip

 Arduino

首先,Arduino 的Sketch中,令小車移動的指令是連接L298D的4個腳位控制個馬達的正轉反轉和速度。先把向前向後轉左轉右等指令包裝成forward()、backward()、left()、right()、brake()等指令:
int Left_motor_go=8;     //左馬達前進(IN1)
int Left_motor_back=9;     //左馬達後退(IN2)
int Right_motor_go=10;    // 右馬達前進(IN3)
int Right_motor_back=11;    // 右馬達後退(IN4)

void forward()     // 前進
{
  digitalWrite(Right_motor_go,HIGH);  // 右馬達前進
  digitalWrite(Right_motor_back,LOW);     
  digitalWrite(Left_motor_go,LOW);  // 左馬達前進
  digitalWrite(Left_motor_back,HIGH);
  
  analogWrite(Right_motor_go,200);
  analogWrite(Right_motor_back,0);  
  analogWrite(Left_motor_go,0);
  analogWrite(Left_motor_back,200);
}

連接藍牙到Arduino時要像以下般連接,藍牙模組會直播接連到板子上的TX,RX 腳位。當Arduino開始"setup()"時除了設定相關腳位的pinMode外,也需設定Serial的通訊。之後的程式上就可以像Serial 通訊般互傳指令。而Serial Rate 要跟自己藍牙模組的Baud Rate 相同,才可以在同一頻率下理解訊息。之前在電腦上搜尋這藍牙時,確定自己用的是HC-05的藍牙組件。HC-05出廠設定是rate=9600,配對密碼1234。
Bluetooth's TX  <-->  Arduino's RX
Bluetooth's RX  <-->  Arduino's TX
Bluetooth's GND  <-->  Arduino's GND
Bluetooth's VCC  <-->  Arduino's 5V