Monday, November 2, 2015

kmeans + Openstreet /үргэлжлэл/

Өмнөх постонд оруулсан Pokemon уудын байршил болон тоглогчдын байршлыг openstreet дээр байршуулав


    map = new OpenLayers.Map("mapdiv");
    map.addLayer(new OpenLayers.Layer.OSM());

    var fromProjection = new OpenLayers.Projection("EPSG:4326");   // Transform from WGS 1984
    var toProjection   = new OpenLayers.Projection("EPSG:900913"); // to Spherical Mercator Projection
    var size = new OpenLayers.Size(21,25);
    var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
    var zoom=9;
 
    var markers = new OpenLayers.Layer.Markers( "Markers" );
    map.addLayer(markers);
<?php
//clusteriin tseguuded marker zooh
$mar = 1; //icon uud solihod ashiglav
foreach ($clusterdata as $key => $value) {
  foreach ($value as $key => $v) {
    echo 'markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat('.$v[1].','.$v[0].').transform(fromProjection,toProjection), new OpenLayers.Icon("img/marker'.$mar.'.png", size, offset)));';
  }
  $mar++;
}
$centerlat=0;
$centerlng = 0;
//centroiduudiig haruulah
foreach ($centroids as $key => $value) {
  echo 'markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat('.$value[1].','.$value[0].').transform(fromProjection,toProjection), new OpenLayers.Icon("img/star.png", size, offset)));';
  $centerlat += $value[0];
  $centerlng += $value[1];
}

//map centert haruulah
echo 'var lonLat = new OpenLayers.LonLat( '.$centerlng/$k.','.$centerlat/$k.' )
          .transform(new OpenLayers.Projection("EPSG:4326"), 
            map.getProjectionObject()
          );
  map.setCenter (lonLat, zoom);';
?>  


Гаралт нь


Од гарсан хэсэгт покемонууд гарч ирэх харгалзах тоглогчдод байршлыг нь явуулна.

Sunday, November 1, 2015

k means алгоритм ашигласан хялбар жишээ /Pokemon/

Ерөнхийдөө k means алгоритм нь өгөгдсөн өгөгдлийн олонлогоос хамаарч k тооны cluster буюу ижил төрлийн эсвэл ойролцоо шинж чанар бүхий бүлгүүдийг үүсгэхэд ашигладаг. Хэрэгжүүлэхэд хялбар болон энгийн шинж чанараараа энэ алгоритм алдартай. Зардал бага "эрчим хүчинд хэмнэлттэй" тул ихэнхдээ аливаа их хэмжээний өгөгдөлд pre-cluster буюу илүү өндөр түвшний алгоритм д өгөгдлүүдийг бэлдэж өгөхөд хэрэглэгддэг.

Mobicom ын Дэлхийн аваргын үеэр явуулж байсан бөмбөг булаацалддаг тоглоом шиг дүрэмтэй тийм аппликешн хийх бодолтой байна. Одоогоор санаа нь бол Pocket Monster буюу Pokemon: Өдөрт тодорхой нэг байршилд pokemon гарч ирэх ба хэн түүнийг түрүүлж авч хамгийн их pokemon той болсон нь түрүүлэх юм. Үүнийг хэрэгжүүлэхэд хамгийн тохиромжтой нь k means алгоритм

Зорилго нь: Өдөрт k тооны Pokemon уудыг гаргах ба тоглогчид тэрхүү Pokemon уудыг түрүүлж олж өөрийн болгох ёстой. Мөн тоглогчид өөрт нь ойр байх pokemon ыг хэлэх ба энэ мэдээлэл хэдэн хүнд очсон өөрөөр хэлбэл өөрт нь хэдэн өрсөлдөгч байгааг сануулах юм. "It's always good to know your enemy Right?" Мөн нэг цагийн дараа гэхэд тухайн сегментээс хамаарч pokemon ы байршил өөрчлөгдөх болно, өөрөөр хэлбэл цэнтройдыг дахин бодох болно.

Бидэнд "Players" нэртэй хүснэгт түүн дотор тоглогчдын мэдээлэл, хамгийн гол нь гео байршлын мэдээлэл (latitude, longitude) нь байгаа гэж үзье. Гео байршлын мэдээлэл мэдээж үргэлж өөрчлөгдөж байна. Хамгийн сүүлд GPS асаалттай байсан цэгийг ачаалах (current) байршил гэж үзнэ.

class Data{
 var $dbhost;
 var $username;
 var $password;
 var $database;

 var $connection;

 function Data(){
        //construction
        $this->InitialDB();
    }
    //initialize with this next time
    function InitialDB(){
        $this->dbhost  = 'localhost';
        $this->username = 'root';
        $this->password  = '';
        $this->database  = 'pokemon';
    }
    /**
     * get geo data to proceed next step
     * @return  latitude, longitude mysql result
     */
    function GetGeoData(){
        if(!$this->DatabaseConnect())
        {
            return false;
        }
        $query = "SELECT latitude, longitude FROM players";
        
        $result = mysqli_query($this->connection,$query);
        return $result;
    }
    /**
     * db connector
     * @return  true or false; is DB successfully connected
     */
    function DatabaseConnect(){

        $this->connection = mysqli_connect($this->dbhost,$this->username,$this->password,$this->database);
  
        if(!$this->connection){   
            error_log("Login info wrong", 0);
            return false;
        }
        if(!mysqli_select_db($this->connection,$this->database)){
            error_log("DB error", 0);
            return false;
        }
        if(!mysqli_query($this->connection,"SET NAMES 'UTF8'")){
            error_log("UTF encoding error", 0);
            return false;
        }
        return true;
    }
}

Харин одоо үндсэн кластер хийх Kmeans классыг хэрэгжүүлье. Энэхүү арга нь бидэнд кластер үүсгэж өгөхөөс гадна тус бүрт нь цэнтройдуудын координатуудыг өгөх болно. Цэнтройдуудын байршил дээр манай покемонууд гарах ба харин тухайн цэнтройдын сегментэд орсон тоглогчдод мэдээлэл илгээх болно.


class Kmeans
{
    var $data;
    var $cluster_result; // cluster hiigdeh array
    var $centroids;
    var $centroid_distance; // centroid hurtelh zainii array
    /**
     * baiguulagch
     *
     * @param  data  ogogdliin sangaas irsen lat long olonlog
     */
    public function Kmeans(array $data)
    {
        if (count($data) < 2) {
            error_log('Data must have more than 2'); // dor hayj hoyr huvaagdahiin tuld
        }
        $this->data = $data;
    }

    /**
     * cluster hiih undsen arga, busad arguudaa aguulna
     *
     * @param   kcount   k toonii cluster bolgoh
     * @return  array    cluster hiigdsen array butsaana
     */
    public function cluster($kcount)
    {
        if ($kcount < 2) {
            throw new Exception('k have to greater than 1');
        }
        if ($kcount > count($this->data)) {
            throw new Exception('k have to less than data'); // huvaagch ni huvaagdagchaas ih bj bolohgui
        }

        do {
            if (empty($centroids)) {
                $centroids = $this->getRandomInitialization($kcount); // ehnii udaa achaalj centroid iig songoh
            } else {
                $centroids = $this->calculateCentroids($this->cluster_result); // bj boloh centroidiig oloh
            }

            $new_cluster_result = array_fill(0, $kcount, []);
            foreach ($this->data as $current) {
                $closest_centroid = $this->calculateClosestCentroid($current, $centroids);
                array_push($new_cluster_result[$closest_centroid], $current);
            }
        } while ($this->clusterResultCheck((array) $this->cluster_result, $new_cluster_result) === false);
        
        $this->centroids = $centroids;
        return $this->getClusteredData();
    }

    /**
     * bodogdson centroid iig avah
     * @return  array  centroids
     */
    public function getCentroids()
    {
        if (empty($this->centroids)) {
            return 0;
        }
        return $this->centroids;
    }

    /**
     * bodogdson cluster iig avagch
     * @return  array  clustered data array
     */
    public function getClusteredData()
    {
        if (empty($this->cluster_result)) {
            throw new Exception('Clustered data have not been hydrated yet - run cluster method first');
        }

        return $this->cluster_result;
    }
    /**
     * Sanamsarguigeer centroid uudiig songoh function
     * @param   $kcount  heden shirheg cluster bolgoh ve
     * @return  array k shirheg elementtei array
     */
    protected function getRandomInitialization($kcount)
    {
        $random_keys = array_rand($this->data, $kcount);
        $random_keys = array_flip($random_keys);
        return array_intersect_key($this->data, $random_keys);
    }

    /**
     * huvaagdsan clusteruudaas centroid oloh function
     *
     * @param   $cluster_result
     * @return  centroiduud butsaana
     */
    protected function calculateCentroids(array $cluster_result)
    {
        $centroids = [];
        foreach ($cluster_result as $cluster) {
            $cluster_sum = array_fill(0, count(current($cluster)), 0);
            foreach ($cluster as $current) {
                foreach ($current as $key => $value) {
                    $cluster_sum[$key] += $value;
                }
            }
            $centroid = array_fill(0, count(current($cluster)), 0);
            foreach ($cluster_sum as $key => $value) {
                $centroid[$key] = $value / count($cluster);
            }
            array_push($centroids, $centroid);
        }
        return $centroids;
    }

    /**
     * ajiglaj bui olonlog dotorh hamgiin oir centroid iig olj bolomjit shiljiltiig zaah
     *
     * @param   $current     datasetees ajiglaj bui array
     * @param   $centroids   centroiduud
     * @return  shiljih index
     */
    protected function calculateClosestCentroid(array $current, array $centroids)
    {
        $centroid_distance = [];
        foreach ($centroids as $centroid) {
            array_push($centroid_distance, $this->calculateDistance($current, $centroid));
        }
        asort($centroid_distance);
        $centroid_distance = array_keys($centroid_distance);
        return array_shift($centroid_distance);
    }

    /**
     * clustert zow huvaaj duussan esehiig shalgah
     *
     * @param   $cluster_result      omnoh cluster hiigdsen
     * @param   $new_cluster_result  suuld cluster hiigdsen
     * @return  omnohoosoo iluu bish bnu ugui yu boolean butsaana
     */
    protected function clusterResultCheck(array $cluster_result, array $new_cluster_result)
    {
        //medeej hooson bol davtalt yvagdah yostoi false butsaa
        if (empty($cluster_result)) {
            $this->cluster_result = $new_cluster_result;
            return false;
        }
        //omnohoos neg l elm oor clustert orvol tsaash yvah yostoi
        foreach ($cluster_result as $key => $cluster) {
            foreach ($cluster as $c) {
                if (!in_array($c, $new_cluster_result[$key])) {
                    $this->cluster_result = $new_cluster_result;
                    return false;
                }
            }
        }
        //oorchlolt bhgui tul davtalt duusnaa
        return true;
    }

    /**
     * hoyor tsegiin hoorondoh zaig eucled iin theorem ashiglaj oloh
     */
    protected function calculateDistance($point_a, $point_b)
    {
        $distance = 0;
        for ($i = 0, $count = count($point_a); $i < $count; $i++) {
            $difference = $point_a[$i] - $point_b[$i];
            $distance += pow($difference, 2);
        }
        //haritsuulaltad ashiglaj bgaa bolohoor sqrt buyu yzguur avah shaardlagagui
        return $distance;
    }
}
Харин одоо view хэсэгт дараах байдалтай хэрэгжүүллээ. Энэ нь ихэнхдээ сервис байдалтай ашиглагдана гэж үзээд ямар нэг хэвжүүлэлт хийсэнгүй, мөн дурын гэдгийг анзаарсан байх.


require_once("src/KMeans.php");
require_once("src/Data.php");

$data = new Data();
$array = array();
$k = 3; //3 cluster uusgeh

//populate data
$result = $data->GetGeoData();
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
    $array[] = array($row['latitude'], $row['longitude']);
}

$kmeans = new Kmeans($array);

//mother of all process - cluster hiih
$kmeans->cluster($k);

//ene hesegt heseg delay hiij bolno (optional)
//cluster bolgoson segmentuudee avah
$clusterdata = $kmeans->getClusteredData();
//clusteruudiin centroid iig avah
$centroids = $kmeans->getCentroids();

echo "Pokemon гарах байршлууд 
-----------------------
";
echo json_encode($centroids);
echo "
__________________________
Тоглогчдын сегментүүд 
-----------------------
";
echo json_encode($clusterdata);

Энэ бүхний гаралт дараах байдалтай гарч байна. Тест учир харьцангуй цөөн өгөгдлүүдтэй байгаа. Их хэмжээний өгөгдөл дээр илүү тогтвортой ажиллах болно. k нь 3 буюу 3 сегмент болголоо.



Дүгнэлт: K means алгоритм ашиглан хялбар жишээ хийж үзлээ. Ямар нэгэн дээд түвшний кластер хийгээгүй буюу өөрөөр хэлбэл зөвхөн гео мэдээлэл үндэслэж гаргасан тул янз бүрийн байшин объект гол мөрөн эсвэл ямар нэгэн боломжгүй цэг дээр манай цэнтройд байрлахыг үгүйсгэхгүй.

Thursday, May 21, 2015

Java EE эхлэл (Section 2)

Ажилтны бүртгэл хийх, тайлан гаргах жижигхэн жишээ аппликешнээ үргэлжлүүлье. model controller хэсгүүдээ тохируулсан тул одоо view хэсгийг хийнэ. Хэрэглэгчтэй харилцах хуудсууд нь JSF буюу xhtml өргөтгөлтэй байна. Мөн jsp байж болно. Онцын ялгаа байдаггүй ч сүүлийн хувилбар нь xhtml болсон.
Эхлээд jsf д зориулсан Managed Bean классыг үүсгэж өгнө. war -> New ->JSF Managed Bean


Managed Bean дараах байдалтай байна

 
package lu.ajiltan.managed;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import lu.ajiltan.beans.AjiltanFacadeLocal;
import lu.ajiltan.beans.AjiltniibolovsrolFacadeLocal;
import lu.ajiltan.beans.UlsFacadeLocal;
import lu.ajiltan.models.Ajiltan;
import lu.ajiltan.models.Ajiltniibolovsrol;
import lu.ajiltan.models.Uls;

/**
 *
 * @author Bilgee
 */
@ManagedBean
@ViewScoped
public class AjiltanManage implements Serializable{

    //enterprise java bean uud local interface eer holbogdono
    
    @EJB
    AjiltanFacadeLocal ajiltanfacade;
    
    @EJB
    AjiltniibolovsrolFacadeLocal ajiltanbolovsrolfacade;
    
    @EJB
    UlsFacadeLocal ulsfacade;
    
    //olon bolovsroliin medeelel oruulahiin tuld list ashiglana
    List bolovsrollist = new ArrayList();
    
    //ulsuudiig select One songoltond haruulahad ashiglana
    List ulslist = new ArrayList();
    
    //ehelj ajillahad songoltond ulsuudiig haruulahad post construct annotation ashiglana
    @PostConstruct
    public void init(){
        ulslist = ulsfacade.findAll();
    }

    //html page tei holbohdoo encapsulated tul get set ashiglana
    public List getUlslist() {
        return ulslist;
    }

    public void setUlslist(List ulslist) {
        this.ulslist = ulslist;
    }

    public List getBolovsrollist() {
        return bolovsrollist;
    }

    public void setBolovsrollist(List bolovsrollist) {
        this.bolovsrollist = bolovsrollist;
    }
    
    //model toroltei huvisagchuud hadgalah bolon ynz burin zuild ashiglana
    Uls ulsuud = new Uls();
    Ajiltniibolovsrol bolovsroluud = new Ajiltniibolovsrol();
    Ajiltan ajiltan = new Ajiltan();

    public Ajiltan getAjiltan() {
        return ajiltan;
    }

    public void setAjiltan(Ajiltan ajiltan) {
        this.ajiltan = ajiltan;
    }

    public Ajiltniibolovsrol getBolovsroluud() {
        return bolovsroluud;
    }

    public void setBolovsroluud(Ajiltniibolovsrol bolovsroluud) {
        this.bolovsroluud = bolovsroluud;
    }

    public Uls getUlsuud() {
        return ulsuud;
    }

    public void setUlsuud(Uls ulsuud) {
        this.ulsuud = ulsuud;
    }
    
    //Add lists, olon ajiltnii bolovsroliig ehleed listed hiine, list populate hiih arga
    
    public String addAjiltanBolovsrol(){
        bolovsrollist.add(bolovsroluud);
        bolovsroluud = new Ajiltniibolovsrol();
        return null;
    }
    
    //Medeelliig hadgalah undsen function
    public String saveAjiltan(){
        try{
            //listed populate hiisen medeelliig Ajiltnii Bolovsrol d hadgalah
            for(Ajiltniibolovsrol bo : bolovsrollist){
                bo.setAjiltniiDugaar(ajiltan);
            }
            
            //ajiltnii medeelliig ajiltan d hadgalah
            ajiltanfacade.create(ajiltan);
            return null;
        }
        catch(Exception ex){
            return ex.toString();
        }
    }
    
    public AjiltanManage() {    
    } 
}

Харин холбогдох хэсэг буюу Facade классуудад entity manager автоматаар үүссэн байх ба бага зэрэг код бичиж entity Тэй холбоно. Үүнд жишээгээр AjiltanFacade ийг авч үзвэл дараах байдалтай байна

@Stateless
public class AjiltanFacade extends AbstractFacade implements AjiltanFacadeLocal {
    @PersistenceContext(unitName = "AjiltanBurtgel-ejbPU")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public AjiltanFacade() {
        super(Ajiltan.class);
    }
    
    @Override
    public Ajiltan find(Object id){
        return em.find(Ajiltan.class, id);
    }
    
    //haruulah bolon list populate hiihed ashiglagdana
    @Override
    public List findAll(){
        List returnlist = new ArrayList();
        TypedQuery query = em.createNamedQuery("Ajiltan.findAll", Ajiltan.class);
        try{
            returnlist = query.getResultList();
        }
        catch(Exception ex){
            ex.toString();
        }
        return returnlist;
    }
    //hadgalahad ashiglana
    @Override
    public void create(Ajiltan empl){
        try{
            em.persist(empl);
        }
        catch(Exception ex){
            System.out.println(ex.toString());
        }
        finally{}
    }
}

харагдах хэсэг буюу Jsf page ийн хувьд үүсгэхдээ war->New->JSF Page сонгоно. Managed bean тэй холбохдоо #{managedBean} шигтгээ ашиглана.

ajiltan.xhtml


    
        Ажилтан жишээ
    
    
        
        
                
                    
                                     
                        
                    
                    
                    
                                     
                        
                    

                
        
                  
                      
                        Сургууль нэмэх
                    

                      
                        
                    
                      
                     
                 
                
                        
                    
        
        
              
            
            

            
              
             
            

              
             
            

             
              
            
    
            
            
              
                          
                         
                        
            
            

             
            
    


Wednesday, May 20, 2015

Java EE ejb эхлэл тохиргоо (Section 1)

Java ee 7, Glassfish ашиглан Ажилтны мэдээлэл хадгалж харуулах бяцхан жишээ хийе. Өгөгдлийн санд суурилсан буюу бэлэн хийгдсэн өгөгдлийн сан дээр суурилан хөгжүүлэх эсвэл шууд өгөгдлийн сангаа үүсгэх байдлаар хийх боломж байдаг. Ихэнх хөгжүүлэлтийн загварчлалд эхлээд өгөгдлийн сангаа төлөвлөдөг тул өгөгдлийн санд суурилсан аргыг сонголоо.
Өгөгдлийн сангаараа нээлттэй эх PostgreSQL ийг сонголоо. ERD г харвал

SQL Power Architect ийг загварчлахад ашиглав


Програмыг хөгжүүлэх орчноор Netbeans ийг сонголоо, учир нь Glassfish сервертэй хамт суугддаг багцтай. Project ээ эхлүүлэхдээ Java EE хавтсан дотроос Enterprise Application гэснийг сонгоно.


Дараагийн алхам бол Project дээ нэр өгч Серверээ сонгон EJB болон WAR модулуудаа үүсгэх


Одоо өгөгдлийн сантайгаа холбох хэрэгтэй. Манай тохиолдолд Postgresql дээр үүсгэсэн байгаа сантай холбох connection хийх юм. Үүний тулд netbeans ийн Services цонхон дахь Database хэсэг дээр дарж New Connection ийг сонгоно


Driver ийг сонгох хэсгээс PostgreSQL ийг сонгоно. Ихэнх тохиолдолд цаанаасаа Postgresql суусан байдаг ба хэрвээ өөр төрлийн өгөгдлийн сан сонгох бол Driver ийг суулгах шаардлагатай. Үүний дараа Postgre тэй холбох цонх гарч ирнэ. Postgre ажиллаж байгаа эсэхээ шалгаарай. 

Дараа нь Glassfish серверээ асааж, Admin Console хэсэгт нэвтрэн Connection Pool болон JNDI г нь тохируулах хэрэгтэй. Үүнийг хэд хэдэн янзаар хийх боломжтой хамгийн найдвартай нь Admin Console дээрээс үүсгэх юм билээ.

Одоо харин өгөгдлийн сантай холбогдох давхаргыг үүсгэе. EJB хэсэгт шинэ Entity Classes from Database үүсгэхийг сонгоно.

Data source хэсэгт үүсгэсэн jndi г оруулахад бүх хүснэгтүүд орж ирэх ба ашиглах хүснэгтүүдээ сонгож оруулна. Энэ нь автоматаар өгөгдлийн сантай холбогдох entity классуудыг үүсгэх юм.


Package ийн нэрийг сонгож үүсгэх классуудын тохиргоог дараах байдалтай тохирууллаа

Ингэж үүсгэсний дараа entity package д хүснэгттэй холбогдох классууд үүссэн байх ёстой. Мөн custom query нүүдийг энэ классуудад нэмэх боломжтой.


Дараагийн EJB д нэмэх хэсэг бол Модел хэсэг юм. Facade pattern ашиглах болно. Классуудыг автоматаар үүсгэхдээ New -> Session Beans for Entity Classes г сонгоно. Дараах жишээнд Local гэсэн интерфэйсийг мөн нэмж өгөв. Энэ нь view хэсгээс зөвхөн интерфэйсээр дамжиж моделд хандах боломжтой болгож байгаа.


Энэ бүхний дараа прожект ийн бүтэц дараах байдалтай болжээ. Enterprise Bean үүд нь автоматаар үүсгэгдснийг ажигласан байх.

Одоо харин Web Application хэсэг буюу jsf хуудас болон Managed bean үүдийг дараагийн хэсэгт хийе. Их орой болсон байна.

Monday, February 23, 2015

Pill Heals тоглоом

Энэхүү тоглоом нь гар утас болон таблетад зориулагдсан бөгөөд төхөөрөмжийн хурдатгал болон чиглэл мэдрэгчийг ашигласан. Тоглоомын гол зарчим нь олон төрлийн эмийн хүчийг саармагжуулагч вирусүүдээс бултаж өвчний голомтуудад очин эдгээх юм. Бүх насны хүмүүст тохиромжтой ба мөн зарим эмүүдийн тайлбарыг мэдлэг өгөх зорилгоор оруулж өгсөн. Тоглоом нь үе давах, Arcade болон Survival гэсэн 3 төрөлтэй. Arcade болон Survival төрлөөс авсан оноогоороо найзуудтайгаа болон бүх тоглогчидтой өрсөлдөх боломжтой(facebook account).

Дэлгэцийн зураг






Танилцуулга үзүүлэн



Одоогоор бүх утсан дээр туршиж үзээгүй байна