여기에는 유전자 알고리즘의 상세한 원리와 구체적인 정의를 소개하지 않습니다. 알고 싶다면 Baidu를 사용하여 배울 수 있습니다. 여기서는 유전자 알고리즘에 대한 이해를 간단히 소개하겠습니다. 이 기사는 유전자 인코딩에 이진 규칙을 사용합니다.
알고리즘 아이디어 :
유전자 알고리즘은 다윈의 진화 이론을 말하며 종은 긍정적 인 방향으로 발달하고 있다고 생각하므로 (적합한 가장 적합한 생존), 충분한 대수 후에 얻은 최대 값은 실제 최대 값에 매우 가깝다는 것을 고려할 수 있습니다.
알고리즘 단계 :
알고리즘 구현 생성 부분
1. 개별 집단 (여기서 염색체로 간주 됨), 개인에서는 개인의 유전자 및 유전자에 해당하는 피트니스 (기능 가치)라는 두 가지 속성을 추가합니다.
공개 클래스 염색체 {private boolean [] 유전자; // 유전자 서열 개인 이중 점수; // 해당 기능 점수} 2. 유전자 서열을 무작위로 생성한다. 유전자의 각 위치가 0 또는 1인지 여부는이를 달성하는 완전히 무작위적인 방법입니다.
public 염색체 (int size) {if (size <= 0) {return; } initGenesize (크기); for (int i = 0; i <size; i ++) {gene [i] = math.random ()> = 0.5; }} private void initGenesize (int size) {if (size <= 0) {return; } gene = 새로운 부울 [크기]; } 3. 유전자를 해당 값으로 변환합니다. 예를 들어, 101에 해당하는 숫자는 5이고 비트 작업은 여기에서 구현하기 위해 사용됩니다.
public int getnum () {if (gene == null) {return 0; } int num = 0; for (부울 부울 : 유전자) {num << = 1; if (bool) {num += 1; }} return num; } 4. 유전자 돌연변이가 발생하면 돌연변이의 위치는 무작위로 완전히 구현된다. 돌연변이 원리는 1에서 0 및 0에서 1으로 변하는 것입니다.
공공 공간 돌연변이 (int num) {// 돌연변이 int size = gene.length; for (int i = 0; i <num; i ++) {// 돌연변이 위치를 찾으십시오 int at = ((int) (math.random () * size)) % 크기; // 돌연변이 후의 값 부울 부울 =! gene [at]; 유전자 [at] = bool; }} 5. 클로닝 유전자는 차세대를 생산하는 데 사용됩니다. 이 단계는 기존 유전자를 복사하는 것입니다.
공공 정적 염색체 클론 (최종 염색체 c) {if (c == null || c.gene == null) {return null; } 염색체 카피 = 새로운 염색체 (); copy.initgenesize (c.gene.length); for (int i = 0; i <c.gene.length; i ++) {copy.gene [i] = c.gene [i]; } 반환 사본; } 6. 두 부모 모두 차세대를 생산하고, 여기서 두 개인은 두 명의 개인 자손을 생산합니다. 특정 유전자가 학생과 다른 것은 완전히 무작위입니다.
공공 정적 목록 <염색체> 유전자 (염색체 P1, 염색체 P2) {if (p1 == null || p2 == null) {// 비어 있고 차세대 리턴 NULL을 생성하지 않는 염색체 중 하나가 있습니다. } if (p1.gene == null || p2.gene == null) {// 유전자 서열이없고 차세대 리턴 NULL을 생성하지 않는 염색체 중 하나가 있습니다. } if (p1.gene.length! = p2.gene.length) {// 염색체 유전자 서열의 길이는 차세대 리턴 널을 생성하지 않습니다. } 염색체 C1 = 클론 (P1); 염색체 C2 = 클론 (P2); // 크로스 스웨이 위치 생성 무작위로 int size = c1.gene.length; int a = ((int) (math.random () * size) % 크기; int b = ((int) (math.random () * size)) % 크기; int min = a> b? B : A; int max = a> b? A : B; // (int i = min; i <= max; i ++) {boolean t = c1.gene [i]; c1.gene [i] = c2.gene [i]; c2.gene [i] = t; } list <Chromosome> list = new arraylist <Chromosome> (); list.add (c1); list.add (c2); 반환 목록; } 알고리즘 구현 생성 알고리즘
1. 유전자 알고리즘의 경우, 인구 수, 유전자 길이, 유전자 돌연변이 수, 유전자 돌연변이 속도 등을 설정 해야하는 상응하는 인구와 일부 상수가 필요합니다. 자세한 내용은 다음 코드를 참조하십시오.
공개 초록 클래스 GeneticalGorithm {private list <Chromosome> 집단 = New Arraylist <Chromosome> (); // 인구 개인 int popsize = 100; // 인구 번호 개인 int genesize; // 최대 길이의 개인 int maxiternum = 500; // 최대 반복 비공개 돌연변이 레이트 = 0.01; // 유출 int maxutation maxutation maxutation maxutation maxutation maxutation maxutation. 비동기 길이 개인 int 생성 = 1; // 현재 몇 세대가 상속되어 있습니까? BESTSCORE; // BEST SCORE PRIVATE PRIVATE DOUBLESTSCORE; // 최악의 점수 개인 이중 총 스코어; // 총 점수 개인 이중 평균 점수; // 평균 점수 개인 이중 X; // 역사적 모집단에서 최고의 X 값을 기록하십시오 프리 개인 이중 Y; // 역사적 인구에서 가장 좋은 y 가치를 기록하십시오 Private int genei; // XY가있는 대수} 2. 인구를 초기화하십시오. 유전자 알고리즘이 시작될 때 원래 1 세대 인 원래 모집단을 초기화해야합니다.
private void init () {for (int i = 0; i <popsize; i ++) {ogulation = new arraylist <Chromosome> (); 염색체 chro = 새로운 염색체 (유전자 크로스 사이즈); 인구 .add (chro); } cacultEcore (); } 3. 초기 인구가 존재하면 인구의 체력뿐만 아니라 최고의 체력, 최악의 체력 및 평균 체력 등을 계산해야합니다.
Private void cacultecore () {setchromosomescore (usulod.get (0)); BestScore = ouscal.get (0) .getScore (); 최악의 스코어 = 인구 (0) .getScore (); 합계 코어 = 0; for (염색체 chro : 집단) {setchromosomescore (chro); if (chro.getScore ()> bestscore) {// 최고의 유전자 값 BestScore = chro.getScore (); if (y <bestscore) {x = changex (chro); y = BestScore; genei = 세대; }} if (chro.getScore () <최악의 스코어) {// 최악의 유전자 값을 설정하고 최악의 스코어 = chro.getScore (); } TotalScore += chro.getScore (); } AveragesCore = TotalScore / Popsize; // 정확도 문제로 인한 평균 값은 최고 값보다 크고 평균 값을 최고 값 AveragesCore = AveragesCore> BestScore로 설정합니까? BestScore : Averagescore; } 4. 개별 체력을 계산할 때 유전자에 따라 해당 Y 값을 계산해야합니다. 여기서 우리는 클래스 구현을 통해 특정 구현을 구현하기위한 두 가지 추상 방법을 설정했습니다.
개인 void setchromosomescore (염색체 chro) {if (chro == null) {return; } double x = changex (chro); double y = caculatey (x); chro.setscore (y); } / ** * @param chro * @return * @description : 바이너리를 해당 x * / public acpract double changex (염색체 chro)로 변환합니다. / ** * @param x * @return * @description : x y = f (x) */ public acholding double caculatey (double x)를 기준으로 Y 값을 계산합니다. 5. 인구 체력을 계산 한 후 턴테이블 도박 방법을 사용하여 차세대를 생산할 수있는 개인을 선택해야합니다. 여기에는 개인의 체력이 평균 체력보다 낮은 경우에만 차세대가 태어날 수있는 조건이 있습니다 (적합한 것이 생존).
개인 염색체 getparentchromosome () {double slice = math.random () * TotalScore; 이중 합계 = 0; for (염색체 chro : 집단) {sum += chro.getScore (); // 해당 위치로 이동하면 피트니스가 평균 체력보다 낮습니다. if (sum> slice && chro.getScore ()> = AveragesCore) {return chro; }} return null; } 6. 차세대를 생산할 수있는 개인을 선택한 후에는 다음 세대를 생산하기 위해 결합해야합니다.
Private Void Evolve () {list <Chromosome> childpopulation = new Arraylist <Chromosome> (); // 다음 세대 인구를 생성하는 동안 (childpopulation.size () <popsize) {Chromosome p1 = getparentchromosome (); 염색체 p2 = getparentchromosome (); 목록 <Chromosome> children = Chromosome.genetic (p1, p2); if (children! = null) {for (염색체 chro : children) {childpopulation.add (chro); }}} // 노령 인구를 새로운 인구 목록으로 바꾸십시오 <Chromosome> t = 집단; 인구 = 아동 인구; t.clear (); t = null; // 유전자 돌연변이 돌연변이 (); // 새로운 모집단의 체력 계산 Cacultescore (); } 7. 유전자 돌연변이는 다음 세대를 생산하는 과정에서 발생할 수 있습니다.
private void mutation () {for (염색체 chro : 집단) {if (math.random () <mutationrate) {// 유전자 돌연변이는 int mutationnum = (int) (math.random () * maxmatualnum); chro.matute (Mutationnum); }}} 8. 위의 단계를 하나씩 반복하십시오.
public void caculte () {// 인구 생성 초기화 = 1; init (); while (generation <maxiternum) {// 인기있는 유전자 진화 (); 인쇄(); 세대 ++; }}구현 클래스를 작성하십시오
위의 유전자 알고리즘의 클래스는 추상 클래스이므로 [6,106]에서 Y = 100-log (x)의 최대 값을 계산한다고 가정 할 때 특정 사례에 대한 구현 클래스를 작성해야합니다.
1. 유전자의 길이는 24라고 가정합니다 (유전자의 길이는 필요한 결과의 유효 길이에 의해 결정됨) 따라서 해당 바이너리 최대 값은 1 << 24입니다. 다음 설정을 만듭니다.
Public Class GeneticalGorithmtest는 GeneticalGorithm {public static final int num = 1 << 24; public geneticalgorithmtest () {super (24); }} 2. x 값의 추상 방법을 구현하십시오
@override public double changex (염색체 chro) {// todo 자동 생성 메소드 스터브 리턴 ((1.0 * chro.getnum () / num) * 100) + 6; } 3. y의 추상 방법을 구현하십시오
@override public double caculty (double x) {// todo 자동 생성 메소드 스터브 리턴 100 -Math.log (x); }실행 결과
유전자 알고리즘에 대해 생각합니다
나는 유전자 알고리즘에 대한 많은 소개를 읽었습니다. 위에서 언급 한 최적의 솔루션은 마지막 세대의 가장 많은 값입니다. 질문이 있습니다. 위의 모든 밴드 중 가장 많은 값, 즉 프로그램의 XY 값이 XY 값을 유전자 알고리즘의 최종 결과 값으로 사용할 수없는 이유는 무엇입니까?
완전한 코드
1. 염색체 클래스
/ ***@설명 : 유전자 염색체*/ 패키지 com.lulei.genetic.algorithm; java.util.arraylist 가져 오기; Java.util.list 가져 오기; 공개 클래스 염색체 {private boolean [] gene; // 유전자 서열 개인 이중 점수; // 해당 함수 점수 public double getScore () {return score; } public void setScore (이중 점수) {this.score = score; } / *** @param size* 무작위로 생성 된 유전자 서열* / public 염색체 (int size) {if (size <= 0) {return; } initGenesize (크기); for (int i = 0; i <size; i ++) {gene [i] = math.random ()> = 0.5; }} / *** 새로운 유전자 생성* / publichromosome () {} / *** @param c* @return* @description : 클로닝 유전자* / public 정적 염색체 클론 (최종 염색체 c) {if (c == null || c.gene == null) {return null; } 염색체 카피 = 새로운 염색체 (); copy.initgenesize (c.gene.length); for (int i = 0; i <c.gene.length; i ++) {copy.gene [i] = c.gene [i]; } 반환 사본; } / *** @param size* @description : 유전자 길이 초기화* / private void initgenesize (int size) {if (size <= 0) {return; } gene = 새로운 부울 [크기]; } /** * @param c1 * @param c2 * @description : 다음 세대를 생성하기위한 유전자 생성 * /public static list <Chromosome> 유전자 (염색체 p1, 염색체 p2) {if (p1 == null || p2 == null) {// 다음 세대가 비어 있고 NULL NULL을 생성하지 않는 경우; } if (p1.gene == null || p2.gene == null) {// 유전자 서열이없고 차세대 리턴 NULL을 생성하지 않는 염색체 중 하나가 있습니다. } if (p1.gene.length! = p2.gene.length) {// 염색체 유전자 서열의 길이는 차세대 리턴 널을 생성하지 않습니다. } 염색체 C1 = 클론 (P1); 염색체 C2 = 클론 (P2); // 크로스 스웨이 위치 생성 무작위로 int size = c1.gene.length; int a = ((int) (math.random () * size) % 크기; int b = ((int) (math.random () * size)) % 크기; int min = a> b? B : A; int max = a> b? A : B; // (int i = min; i <= max; i ++) {boolean t = c1.gene [i]; c1.gene [i] = c2.gene [i]; c2.gene [i] = t; } list <Chromosome> list = new arraylist <Chromosome> (); list.add (c1); list.add (c2); 반환 목록; } /*** @param num* @description : 변동은 유전자 num* /public void mutation (int num)의 Num 위치에서 발생합니다. {// 돌연변이 int size = gene.length; for (int i = 0; i <num; i ++) {// 돌연변이 위치 검색 int at at = ((int) (math.random () * size)) % 크기; // 돌연변이 후의 값 부울 부울 =! gene [at]; 유전자 [at] = bool; }} / *** @return* @description : 유전자를 해당 숫자로 변환* / public int getnum () {if (gene == null) {return 0; } int num = 0; for (부울 부울 : 유전자) {num << = 1; if (bool) {num += 1; }} return num; }} 2. GeneticalGorithm 클래스
/ ** *@description : */ package com.lulei.genetic.algorithm; java.util.arraylist 가져 오기; Java.util.list 가져 오기; 공개 초록 클래스 GeneticalGorithm {private list <Chromosome> 집단 = 새로운 Arraylist <Chromosome> (); Private Int Popsize = 100; // 대중적인 번호 Private int genesize; // 최대 유전자 길이 Private int maxiternum = 500; // 최대 반복 횟수 개인 double mutationrate = 0.01; // 유전자 돌연변이 확률 private int maxmatutionnum = 3; // 최대 변형 비동기 길이 개인 int 생성 = 1; Private Double BestScore; // Best Score Private Private Double OrmentScore; // 최악의 점수 Private Double Totalscore; // Total Score Private Double Averagescore; // 평균 점수 개인 Double X; // 역사적 모집단에서 최고의 X 값을 기록하십시오 프리 개인 이중 Y; // 역사적 인구에서 가장 좋은 y 가치를 기록하십시오 Private int genei; // XY가 위치한 대수는 공개 geneticalgorithm (int genesize) {this.genesize = genesize; } public void caculte () {// 인구 생성 초기화 = 1; init (); while (generation <maxiternum) {// 인기있는 유전자 진화 (); 인쇄(); 세대 ++; }} / *** @description : 출력 결과* / private void print () { System.out.println("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- System.out.println (최악의 체력은 다음과 같습니다. @description : int i = 0; i ++) {chorraylist <Chromosome> (); Private Void Evolve () {Childpopulation <cromosome> ()는 다음 세대의 인구를 생성합니다 염색체 (p1, p2) {childs chro : childs (childs}}}; Cacultecore ()} * @Description : 룰렛 방법은 다음 세대를 상속받을 수있는 염색체를 선택합니다. chro.getScore (return indercore); (Chromosome chro) {setchromosomescore (Chro); 최악의 범위는 chro.getScore ()} chro.getScore (); mutation () {for (염색체 chro : 집단) {if (math.random () <mutationrate) {// 유전자 돌연변이는 int mutationnum = (int)가 발생합니다. setchromosomescore (Chromosome chro) {chro = chro.setscore (x); * @description : x y = f (x)를 기준으로 Y 값을 계산합니다 genesize; BestScore} public getworstscore () {return gettotalscore () {return getaveragescore () {return averagescore; 3. GeneticalGorithMtest 클래스
/ ** *@description : */ package com.lulei.genetic.algorithm; Public Class GeneticalGorithmtest는 GeneticalGorithm {public static final int num = 1 << 24; public geneticalgorithmtest () {super (24); } @override public double changex (염색체 chro) {// todo 자동 생성 메소드 스터브 리턴 ((1.0 * chro.getnum () / num) * 100) + 6; } @Override public double caculatey (double x) {// todo 자동 생성 메소드 스터브 리턴 100 -Math.log (x); } public static void main (string [] args) {geneticalGorithMtest test = new GeneticalGorithMtest (); test.caculte (); }}위의 것은 Java 유전자 알고리즘에 대한 자세한 소개입니다. 모든 사람이 Java 유전자 알고리즘을 배우는 것이 도움이되기를 바랍니다.