質問するログイン新規登録
最適化

最適化とはメソッドやデザインの最適な処理方法を選択することです。パフォーマンスの向上を目指す為に行われます。プログラミングにおける最適化は、アルゴリズムのスピードアップや、要求されるリソースを減らすことなどを指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

数値計算

数値計算は、数学的アルゴリズムや計算手法(行列演算、微分方程式の数値解法など)に関する投稿です。

数学

数学は、プログラミングに関連する数学的な知識(線形代数、統計、確率、アルゴリズムの理論背景など)に関する投稿に使われます。競技プログラミングや機械学習、データ分析の基礎としても需要が高い分野です。

Q&A

0回答

201閲覧

C++ 実行結果が想定通りにならない

kai5426

総合スコア0

最適化

最適化とはメソッドやデザインの最適な処理方法を選択することです。パフォーマンスの向上を目指す為に行われます。プログラミングにおける最適化は、アルゴリズムのスピードアップや、要求されるリソースを減らすことなどを指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

数値計算

数値計算は、数学的アルゴリズムや計算手法(行列演算、微分方程式の数値解法など)に関する投稿です。

数学

数学は、プログラミングに関連する数学的な知識(線形代数、統計、確率、アルゴリズムの理論背景など)に関する投稿に使われます。競技プログラミングや機械学習、データ分析の基礎としても需要が高い分野です。

0グッド

2クリップ

投稿2025/09/22 06:37

0

2

実現したいこと

次に示す内容を実装したい。

[適応的実数値交叉AREXの提案と評価](https://www.jstage.jst.go.jp/article/tjsai/24/6/24_6_446/_pdf

発生している問題・分からないこと

実行結果として、0.00000に収束することを想定しているが、現在、0.2程度に収束してしまう。収束までは正常に数値が改善されていくため、原因がわからない。

エラーメッセージ

error

1エラーメッセージはありません

該当のソースコード

C++

1#include <cstdio> 2#include <cstdlib> 3#include <climits> 4#include <cfloat> 5#include <iostream> 6#include <fstream> 7#include <cmath> 8#include <unistd.h> 9#include <sys/time.h> 10#include <cassert> 11#include <algorithm> 12#include <random> 13 14#define dimension 20 15#define population_size 100 16#define ncalcs 2000 17#define sigmanum sqrt(1.0 / dimension) 18#define number_child_times 4 19#define maxvalue 5.0 20#define PI 3.141592 21#define c_alpha (1.0 / (5.0 * dimension)) 22using namespace std; 23 24random_device rd; 25mt19937 mt(rd()); 26uniform_real_distribution<double> dist(-maxvalue, maxvalue); 27uniform_real_distribution<double> distone(0.0, 1.0); 28normal_distribution<double> distn(0.0,sigmanum); 29 30typedef struct{ 31 vector<double> edge = vector<double>(dimension); 32 double fitness; 33 34} Indiv; 35 36vector<int> randomparent(const int pop){ //pop個、ランダムに親選択 37 vector<int> number(population_size); 38 vector<int> parent(pop); 39 //第1, 2の親の選択 40 for(int i = 0; i < population_size; ++i){ 41 number[i] = i; 42 } 43 shuffle(number.begin(), number.end(), mt); 44 for(int i = 0; i < pop; ++i){ 45 parent[i] = number[i]; 46 } 47 return parent; 48} 49 50double evaluate(const Indiv& indiv){ 51 double sum = 0; 52 //sphere 53 for(int i = 0 ; i < dimension; ++i){ 54 sum += pow(indiv.edge[i], 2); 55 } 56 return sum; 57} 58 59vector<double> middle(const vector<Indiv>& group){ 60 vector<double> m(dimension, 0.0); 61 for(int i = 0; i < dimension; ++i){ 62 for(int j = 0; j < dimension+1; ++j){ 63 m[i] += group[j].edge[i]; 64 } 65 m[i] /= dimension+1.0; 66 } 67 return m; 68} 69 70double update_alpha(double abefore, const vector<Indiv>& upchild){ 71 //更新前のα=abefore, 交叉中心ベクトルmiddle, 上位子個体upchild 72 73 //上位子個体の平均 74 vector<double> mid(dimension, 0.0); 75 mid = middle(upchild); 76 77 //ε イプシロン 78 vector<vector<double>> epsilon(dimension+1, vector<double>(dimension)); 79 for(int i = 0; i < dimension+1; ++i){ 80 for(int j = 0; j < dimension; ++j){ 81 epsilon[i][j] = upchild[i].edge[j] - mid[j]; 82 } 83 } 84 85 //Lcdp, Lavg 86 double sigma1 = 0.0; 87 double sigma2 = 0.0; 88 for (int i = 0; i < dimension+1; ++i){ 89 double term = 0.0; 90 for(int j = 0; j < dimension; ++j){ 91 term += upchild[i].edge[j] / (dimension + 1.0); 92 } 93 sigma1 += pow(term, 2); 94 sigma2 += term; 95 } 96 sigma2 = pow(sigma2, 2) / (dimension + 1.0); 97 double L_cdp = (pow(abefore, 2) * dimension) * (sigma1 - sigma2); 98 double L_avg = pow(abefore, 2) * dimension * (dimension + 1.0); 99 double updatedalpha = abefore * sqrt((1.0 - c_alpha) + (c_alpha * (L_cdp / L_avg))); 100 101 // //αを更新 102 // double updatedalpha = abefore * sqrt((1 - c_alpha) + c_alpha * (L_cdp / L_avg)); 103 //printf("L_cdp = %lf, L_avg = %lf, alpha = %lf\n", L_cdp, L_avg, updatedalpha); 104 if (updatedalpha < 1.0){ 105 updatedalpha = 1.0; 106 } 107 if (updatedalpha > 2.0){ 108 updatedalpha = 1.0; 109 } 110 return updatedalpha; 111} 112 113vector<Indiv> arex(const vector<Indiv>& parent, double alpha, const vector<double>& middle){ 114 //生成子個体 115 vector<Indiv> children(number_child_times*(dimension+1)); 116 vector<Indiv> sortpa = parent; 117 //親個体を昇順ソート 118 sort(sortpa.begin(), sortpa.end(), [](const Indiv& a, const Indiv& b){ 119 return a.fitness < b.fitness; 120 }); 121 //加重平均 122 vector<double> center(dimension, 0.0); 123 double sumone; 124 for(int i = 0; i < dimension; ++i){ 125 sumone = 0; 126 for(int j = 0; j < dimension+1; ++j){ 127 center[i] += sortpa[j].edge[i] * (2.0 * (dimension+2.0-(j+1)) / ((dimension+1.0) * (dimension+2.0))); 128 sumone += (2.0 * (dimension+2.0-(j+1)) / ((dimension+1.0) * (dimension+2.0))); 129 } 130 //printf("1 = %lf\n", sumone); 131 } 132 //子個体生成 133 for(int k = 0; k < number_child_times * (dimension+1); ++k){ 134 for(int i = 0; i < dimension+1; ++i){ 135 Indiv c; 136 double epsilon = distn(mt) * (-2.0); 137 //double epsilon = distn(mt) *(-2.0) * cos(2 * PI * distone(mt)); 138 for(int j = 0; j < dimension; ++j){ 139 double diff = parent[i].edge[j] - middle[j]; 140 c.edge[j] = center[j] + alpha * epsilon * diff; 141 c.edge[j] = max(-maxvalue, min(maxvalue, c.edge[j])); 142 } 143 c.fitness = evaluate(c); 144 children[k] = c; 145 } 146 } 147 return children; 148} 149 150//JGGモデル 151vector<Indiv> JGG(const vector<Indiv>& children){ 152 vector<Indiv> selectchild(number_child_times*(dimension+1)); 153 for(int i = 0; i < number_child_times*(dimension+1); ++i){ 154 selectchild[i] = children[i]; 155 } 156 157 //並び替えておく 158 sort(selectchild.begin(), selectchild.end(), [](const Indiv& a, const Indiv& b){ 159 return a.fitness < b.fitness; 160 }); 161 vector<Indiv> upperchild(dimension+1); 162 for(int i = 0; i < dimension+1; ++i){ 163 upperchild[i] = selectchild[i]; 164 } 165 return upperchild; 166} 167 168int main(){ 169 clock_t start = clock(); 170 // vector<Indiv> population(population_size); 171 //初期化 172 vector<Indiv> population(population_size); 173 for (int i = 0; i < population_size; ++i){ 174 for(int j = 0; j < dimension; ++j){ 175 population[i].edge[j] = dist(mt); 176 population[i].fitness = evaluate(population[i]); 177 } 178 } 179 printf("世代数 : 最良値 : 平均値\n"); 180 double alpha = 1; 181 182 // FILE *fp; 183 // fp = fopen("allchild.csv", "w"); 184 for(long i=0;i<ncalcs;i++){ 185 //double best_fitness = population[0].fitness; 186 double sum_fitness = 0.0; 187 double best_fitness = population[0].fitness; 188 189 //最良値と平均値 190 for(int j = 0; j < population_size; ++j){ 191 if(population[j].fitness < best_fitness){ 192 best_fitness = population[j].fitness; 193 } 194 sum_fitness += population[j].fitness; 195 } 196 197 long idx = static_cast<long>(ncalcs / 2000.0); 198 if (i % idx == 0){ 199 printf("%d\t%lf\t%lf\n", i, best_fitness, sum_fitness / population_size); 200 } 201 //推移表示 202 // for(int j = 0; j <= 50; ++j){ 203 // long idx = static_cast<long>(j * ncalcs / 5000.0); 204 // if (i == idx){ 205 // printf("%d\t%lf\t%lf\n", i, best_fitness, sum_fitness / population_size); 206 // //fprintf(fp, "%lf, %lf\n", best_fitness, sum_fitness / population_size); 207 208 // } 209 // } 210 211 //親選択 212 vector<int> parentc = randomparent(dimension+1); //選択された親個体のインデックス 213 vector<Indiv> parents(dimension+1); //選択された親個体 214 vector<Indiv> upper(dimension+1); //生成子個体の上位, 上位順 215 216 //親群parent 作成 dimension+1個の個体 217 for(int j = 0; j < dimension+1; ++j){ 218 parents[j] = population[parentc[j]]; 219 } 220 221 //選択された親個体の平均 222 vector<double> midpa(dimension); 223 midpa = middle(parents); 224 225 //交叉 226 vector<Indiv> child(number_child_times*dimension); 227 child = arex(parents, alpha, midpa); 228 229 //printf("child.edge[0] = %lf\n", child[0].edge[0]); 230 231 //選択 232 upper = JGG(child); 233 234 //α更新 235 alpha = update_alpha(alpha, upper); 236 // if(i == 50){ 237 // printf("選択した親個体たち = "); 238 // for(int k = 0; k < dimension+1; ++k){ 239 // printf("%lf, ", population[parentc[k]].fitness); 240 // } 241 // printf("\n代入する数値たち = "); 242 // for(int k = 0; k < dimension+1; ++k){ 243 // printf("%lf, ", parents[k].fitness); 244 // } 245 // printf("\n生成個体の一部 = "); 246 // for(int k = 0; k < dimension*number_child_times; ++k){ 247 // printf("%lf ", child[k].fitness); 248 // } 249 // printf("\n"); 250 // } 251 252 //代入 253 for(int j = 0; j < dimension+1; ++j){ 254 population[parentc[j]] = upper[j]; 255 } 256 } 257 // fclose(fp); 258 clock_t end = clock(); 259 double duration = static_cast<double>(end - start) / CLOCKS_PER_SEC; 260 printf("time : %lf\n", duration); 261}

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

交叉AREXや世代交代モデル、計算方法について調べて、都度コードを変更したが、改善されなかった。

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問