Gitextensions - Github - Putty

Bir git macerası daha:
Yeni gui front-end'imiz: gitextensions Putty, msysgit ve kdiff3 kuruyor. Çok anlatılcak birşey yok da github ile bağlantı kurarken ssh keyler filan sorun çıkardı bir dolu vakit kaybı oldu. Yazayım burada bulunsun:

Github'ı remote olarak kullanmak için, shh key çiftlerine ihtiyacımız var.
Burada tutorial: Generating SSH keys (Win/msysgit). Aslında gitextensions'i kullanacağımız için tam olarak bunları yapmamıza gerek yok. Ancak yarın öbür gün bash'dan kullanmak gerekirse bu key'ler de bulunsun.
ssh git@github
Diye bir kez bağlanmayı unutmayın, github'ın public de bizim listemize eklenmiş oluyor böylece. Daha sonra PUSH ederken bir dolu soru sorunca kafamız karışmasın.

Gitextensionsa Putty kurduğu için (aslında iki seçenek var, bunu önermişler, ben de bunu kurdum), key formatı farklı. 
Gitextensions -> Remotes -> PuTTY -> Generate or Import Key  Menüsünden tahmin edin bakalım ne yapılacak? ya yeni key çifti yaratılacak ya da yukarıdaki keyleri import edip PuTTY formatına çevircez. Yeni key çifti yaratıldıysa github.com'a da girilecek.

Repository Clone'larken Load Key seçeneğine, putty'nin private key'ini ekleyeceğiz.
Yapılcak son şey:
~\GitExtensions\PuTTY>plink.exe -i PUTTY_PRIVATE_KEY.ppk git@github.com
Şeklinde bir kez bağlanmak. Yukarıdaki ile aynı mantık. Bunu yapmazsak gui saçmalıyor.

Dropbox + Git

Öncelikle dropbox hesabınız yoksa burdan buyrun: https://www.dropbox.com/referrals/NTY3MTcxNjk
Evet, bu sayade +kota kazanıyorum.

  • Github'da private repo.'lar paralı, gitorious'da hiç yok vs. vs. 
  • Kendimiz kolayca bir sunucu oluşturabiliriz. Apache gibi birşeye de ihtiyacımız yok. Ssh bağlantısı kurabilceğimiz bir pc yeterli. Ancak "asimetrik" dsl hattımızın upload hızını düşünürsek ev sunucusu pek mantıklı değil.
  • USB stickde yanımızda taşısak, autorun.inf'ler malware'ler elbet bir yerde karşımıza çıkacak.
Sonuçta dropbox ile .git repositorylerini "local" olarak sync tutmak mantıklı gibi.

local repomuz ve ilk commit'imiz:

cd ~/projectX
git init
touch readme
git add readme
git commit -m 'first commit'
remote repo. --bare parametresi bu repo da workspace dosyalarının tutulmasını sağlıyor. Daha sonra kaşılıklık çıkmaması için önerilen bir hareket.
cd ~/Dropbox
mkdir projectX.git
cd projectX.git
git init --bare
local repo'ya geri dönüp remote'a değişiklikleri gönderiyoruz:
cd ~/projectX
git remote add origin ~/Dropbox/projectX.git
git push origin master
Diğer bilgisayarlarda
Remote'dan projemizi çekmek için:
git clone ~/Dropbox/projectX.git

git init --bare ne işe yarar
Yukarıda  daha sonra karışıklık çıkmaması için önerilir demiştim. Bu durumda remote repo'da sadece .git klasörü tutuluyor. Çalışma dosyalarımız yer almıyor.
--bare kullanılmazsa bu dosyalarda yer alıyor.
Ortaya çıkan karışıklık şu:
push komutu remote'un local çalışma dosyalarına dokunamadığından .git klasörü güncellenirken, çalışma dosyaları eski kalıyor.
Remote repo sahibinin çalışmasına başlamadan önce "checkout" demezse problemler yaşanabilir diye bunu engellemişler. Yani --bare olmadan push kabul etmiyor.
By default, updating the current branch in a non-bare repository
is denied, because it will make the index and work tree inconsistent
with what you pushed, and will require 'git reset --hard' to match
the work tree to HEAD.
Bunu aşmanın yöntemi ise checkout edilmişin dışında bir branch push etmek, veya remote repo'da bu hatayı kapatmak.

Karmaşık geldi bana, dropbox içinde ikinci bir "local" work copy tutmayı tercih ederim.

Hello World!

>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]
>++++++++[<++++>-] <.>+++++++++++[<++++++++>-]<-.--------.+++
.------.--------.[-]>++++++++[<++++>- ]<+.[-]++++++++++.
Brainfuck dilinde yazılmış Hello World!
Şurada javascript interpreter'i var:  http://www.lordalcol.com/brainfuckjs/
Ayrıca:
sudo apt-get install bf
Tüm bunlar nerden çıktı?
https://www.spoj.pl/problems/SBSTR1/

Sphere Online Judge

SPOJSphere Online Judge – is a problemset archive, online judge and contest hosting service accepting solutions in many languages.

6000 tanecik problem var şu anda, günde 1-2 tane çözsem (ki bazıları 1 haftadan uzun sürer gibi duruyor, nasıl günde 1-2 tane çözeceksem artık...) uzun süre oyalar.
Yarışmaları filan da var sanırım ama biraz kolay problemlerle önce bi ısınmak lazım.

Alper'le bir ara programming challenge arıyorduk, iyi oldu bu. Siz de girin kapışalım... http://www.spoj.pl/

PipedStream

Robot porjesinde RS232 üzerinden gönderilen komutlar bazen gitmiyor. Program başka bir iş yaparken serialport'a veya outputstream'a erişemiyoruzdur, timeout oluyordur vs. diye Sender için da thread açalım dedik.

Thread'lar arası data (buffer, stream ne denirse artık) göndermek için PipedStream tipleri varmış.

PipedOutputStream out = new PipedOutputStream();
PipedInputStream in = new PipedInputStream(out);
Sonra bunları farklı thread'larda
(OutputStream) out
(InputStream) in
Şeklinde kullanıyorsunuz istediğiniz gibi.
 Ama out.write(byte[])    in.read(byte[]) kullanımı yine birbirlerini block'layarak çalışacağı için bize bir yararı olmuyor (Götoş Sun).
Bunun yerine naapıyoruz?
out.write(byte []) olduğu gibi kalıyor. ve
<script src="http://gist.github.com/345368.js"> </script>
Kodunun çalışması için dua ediyoruz... İki komut arka arkaya geldiğinde birbirlerini ezecek gibi duruyor, ama hadi bakalım allah büyüktür...

Paralel Tepe Tırmanma ile Traveling Salesman

TSP yapısı gereği sadece son durumla ilgilenen, geçilen ara adımların önemsiz olduğu bir problem. Mesela satrançta ara adımların tek tek önemi vardır, çünkü rakip de sizin yaptığınıza göre bir hamle yapacaktır. Dolayısıyla TSP gibi bir problemde "bir adet durum tut, bu durumu en iyi hale getirmeye çalış" mantığı benimsenebilir.

Bu mantığın bir adım ilerisi "k adet durumu tut ve en iyi hale getirmeye çalış" mantığıdır. Paralel Tepe Tırmanma (Local Beam Search) bu mantıkla çalışır. O durumun iyiliği, aynı genetik algoritmadaki gibi bir fitness fonksiyonu ile ölçülür. Genetik Algoritma için belirlediğimiz fonksiyon burada da geçerli. (Rotanın toplam uzunluğu; kısaysa iyi, uzunsa kötü)

Paralel Tepe Tırmanma ile TSP genel adımları:

  1. K adet rasgele rota oluştur. Aynı rotanın iki kez oluşmadığından emin ol.
  2. Bu aşamada yukarıdaki rota kümesinde rasgele swap'lar (iki şehrin yerini değiştirmek) yapılarak yeni oluşan rotalar listeye eklenecek. Burada farklı yöntemler kullanılabilir. Ben 1. adımda oluşturduğumuz her rota için, ardışık komşuların yerlerini değiştirerek yeni rotalar oluşturdum.
  3. Bu rotalar fitness değerlerine göre sıralanarak en iyi K tanesi seçilir.
  4. İstenen döngü sayısına ulaşılıncaya veya istenen düşüklükte fitness değeri elde edilene kadar 2. adımdan devam edilir.

20 şehirli haritada K=100 için 200'lü döngü içerisinde çalıştırılınca 9 sn. gibi bir sürede, Genetik Algoritma'nın 28 sn.'de ulaştığı sonuca ulaşılabiliyor.

K=50 için 200'lü döngüde çalıştırıldığında 2 sn. sonunda yine GA'nın 28 sn.'de verdiğinden daha iyi bir sonuç alınıyor.

Media_httpmediatumblr_wrdwt

K değeri şehir sayısına bağlı olarak, iterasyon sayısı da K değerine bağlı olarak doğru seçildiğinde oldukça hızlı sonuç alınabiliyor.

Genetik Algoritma ile Traveling Salesman

Program "pure" genetik algoritma üzerinde çalıştığından, 2-opt, greedy vs. bir heuristic kullanan genetik algoritmaya göre daha yavaş sonuca ulaşır. Bu algoritmanın genel adımları şöyle:

  1. Tüm şehirlerden bir kez geçilen bir "rota" oluştur. Bu işlemi genetik algoritma X nüfus üzerinde çalışacaksa X kez tekrarla. Tabii aynı rotanın 2 kez olmaması için gerekli önlemleri de almak gerek. Bu rota bizim kromozomumuz olacak.
  2. Rulet tekeri yöntemi veya sıralama seçimi kullanarak 2 rotayı ebeveyn olarak seç. Kısaca daha iyi durumdaki yollara daha yüksek olasılık vererek 2 adet rota seçilecek.
  3. Seçilen ebeveyn kromozomlar özel bir yöntemle çaprazlanacak. Normal çaprazlama TSP'de işe yaramıyor çünkü bir kromozomda aynı şehir iki kez bulunmamalı. Keyword: Order-based crossover
  4. Oluşan çocukların küçük bir ihtimal mutasyona uğrama şansı var. Mutasyon işlemi random iki şehrin yerinin değiştirilmesi şeklinde olabilir.
  5. Çocuklar en kötü iki rota yerine geçiyor. Böylece her jenerasyonda nüfusun iyiye gitmesi sağlanmaya çalışılıyor.
Burada bir rotanın iyi mi kötü mü olduğu değerlendirilirken (fitness function) o rotanın toplam uzunluğu dikkate alınıyor. Uzunsa kötü, kısaysa iyi. 20 şehir içeren bir haritada bu algoritma çalıştırılırken iyi bir sonuç alabilmek için 100000 nüfusun 1000 jenerasyon boyunca yaşaması gerekiyor. 28 saniye sürüyor çalışması. Multi-threaded kodlanırsa düşer tabii bu süre. Bir de benim dandik kodlamış olma ihtimalim var :)

Mutasyonu yüzde 10 yapınca, yüzde 5'e göre sonuç kötüleşiyor. Yani mutasyon olayını abartmamak gerekiyor.

Burada önemli bir faktör, heuristic kullanılsaydı daha az nüfus ve daha kısa bir jenerasyon süresi sonunda aynı veya daha iyi bir sonuca ulaşmak mümkündür.

Media_httpmediatumblr_pydaq

Sonraki yazı Paralel Tepe Tırmanma (Local Beam Search) ile çözümü anlatacak.