유전자 알고리즘 프로그래밍 소스 코드를 원하시면..
제가 대충 쓸려고 만든거라, 최적화 등등이 제대로 되어 있지 않지만, 제가 만든거 보여드리겠습니다. 참조용으로 쓰세요.
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/*
* Gene.h
*
* Created on: Mar 4, 2014
* Author: whitesun
*/
#ifndef GENE_H_
#define GENE_H_
namespace Genetic {
class Chromosome {
public:
char gene[100];
// 본래 bit로 하는게 맞지만, 개발 편의를 위해서 char 썼습니다. 여기에 들어가는 값이 0과 1만 되도록 프로그래밍하실때 주의하세요
int length;
int score;
Chromosome()
:length(0), score(0)
{
for(int i = 0; i < 100; ++i){
gene[0] = 0;
}
}
virtual ~Chromosome();
};
} /* namespace Genetic */
#endif /* GENE_H_ */
-------------------------------------------------------------------------------------------------------
#ifndef NATURE_H_
#define NATURE_H_
#include <vector>
#include "Chromosome.h"
#include <time.h>
#include <stdlib.h>
#include <iostream>
namespace Genetic {
class GeneticAlgorithm {
public:
std::vector<Chromosome*> species;
int crossRatio;
int mutantRatio;
GeneticAlgorithm(){
crossRatio = 70;
mutantRatio = 10;
// crossRatio는 교차율로 1/100 값이고 mutantRatio 변이율이고 1/1000 값입니다.
}
virtual ~GeneticAlgorithm();
void setSpecies(Chromosome *gene){
species.push_back(gene);
}
void select(){
int sumpoint = 0;
int size = species.size();
srand((unsigned int) time(NULL));
//srand는 rand()의 seed 값을 정해주는 부분입니다. 사실 rand() 가 정확한 난수 발생기는 아니죠. rand()가 정확한 난수가 아니라는 것은 이 프로그램의 단점 중 하나입니다.
std::vector<Chromosome*> descendants;
for(int i = 0; i < size ; ++i){
sumpoint += ((Chromosome*)species[i])->score;
}
int count = 0;
while(count < size){
Chromosome *A = species[selectOne(sumpoint, size)];
Chromosome *B = species[selectOne(sumpoint, size)];
//각각의 최적 점수에 기반해서 두개의 유전자를 선택하는 부분입니다.
Chromosome *dA = new Chromosome;
Chromosome *dB = new Chromosome;;
dA->length = A->length;
dB->length = B->length;
//두 부모 유전자를 교차시켜서 자식 유전자에게 내려주는 부분입니다. 저는 구간을 교차시키는 것이 아니라 각 유전자 각각을
교차시키는 방식으로 했는데, 이 방식이 우월하다는 학술적 근거는 딱히 없습니다. 이 방식도 값 찾는데는 무난하네요.
for(int i = 0; i < dA->length; ++i){
if(rand()% 100 >= crossRatio){
dA->gene[i] = A->gene[i];
dB->gene[i] = B->gene[i];
}else{
dA->gene[i] = B->gene[i];
dB->gene[i] = A->gene[i];
}
//교배시키고 바로 변이를 시켜줍니다.
if(getMutantRatio() <= mutantRatio){
dA->gene[i] = (dA->gene[i] == 0)?1:0;
}
if(getMutantRatio() <= mutantRatio){
dB->gene[i] = (dB->gene[i] == 0)?1:0;
}
}
descendants.push_back(dA);
descendants.push_back(dB);
count += 2;
}
species.clear();
for(int i = 0; i < size ; ++i){
species.push_back(descendants[i]);
}
}
private:
//각각 적합도 점수에 기반해서 하나를 선택하는 부분입니다.
int selectOne(int sumpoint, int size) {
int point = rand() % sumpoint + 1;
int subSum = 0;
int pos = 0;
for (; pos < size; ++pos) {
subSum += ((Chromosome*) (species[pos]))->score;
if (subSum >= point)
break;
}
return pos;
}
int getMutantRatio() {
int point = rand() % 1000+1;
return point;
}
};
} /* namespace Genetic */
#endif /* NATURE_H_ */
-----------------------------------------------------------------------------------------------------------------------
그리고 이 부분은 위에서 만든 클래스를 실제 돌리는 부분입니다.
for(int i = 0; i < mmCount; ++i){
Genetic::Chromosome* chromosome = new Genetic::Chromosome;
lm[i]->setToChromosome(chromosome);
//lm[i]는 제가 백테스트를 진행한 거래로직입니다. 거래로직으로부터 입력변수를 이진코드로 만든 값을 받습니다.
GA.setSpecies(chromosome);
}
BackTest::BackTester* test = new BackTest::BackTester;
int count = 0;
while(count < 200){
test->RunBackTest();
//백테스트를 실행합니다.
++count;
for(int i = 0; i < mmCount; ++i){
lm[i]->ToString();
//이 부분은 실행결과 화면에 보기 위한 부분입니다.
GA.species[i]->score = lm[i]->GetScore();
//백테스트를 실행한 뒤의 적합도 점수를 기록합니다.
}
GA.select();
//유전자를 교차시킵니다.
for(int i = 0; i < mmCount; ++i){
lm[i]->getFromChromosome(GA.species[i]);
//이진코드로부터 입력변수를 입력 받습니다.
}
}
'backup' 카테고리의 다른 글
[책 리뷰]17 Proven Currency Trading Strategies (2) | 2014.03.31 |
---|---|
권지아-씨스루 (1) | 2014.03.07 |
유전자 알고리즘(Genetic Algorithm) 시스템 트레이딩 활용하기 (4) | 2014.03.06 |
HFT와 프로그래밍 언어 (2) | 2014.03.04 |
시계열 분석과 트레이딩 (2) | 2014.03.02 |