|
3 | 3 | from math import comb |
4 | 4 | from pymoo.core.problem import ElementwiseProblem |
5 | 5 | from pymoo.core.variable import Integer |
| 6 | +import pandas as pd |
| 7 | +from pymoo.operators.sampling.rnd import IntegerRandomSampling |
| 8 | +from pymoo.operators.mutation.pm import PolynomialMutation |
| 9 | +from pymoo.operators.crossover.hux import HalfUniformCrossover |
| 10 | +from pymoo.algorithms.soo.nonconvex.ga import GA |
| 11 | +from pymoo.optimize import minimize |
| 12 | +from pymoo.operators.repair.rounding import RoundingRepair |
| 13 | + |
| 14 | +def process_n(n, cntry_names, sng_ann_losses, principal_sng_dic, n_opt_rep=100): |
| 15 | + """ |
| 16 | + Runs risk concentration minimization for a given number of pools using a genetic algorithm, |
| 17 | + processes the optimization results, and generates convergence plots. |
| 18 | + Parameters |
| 19 | + ---------- |
| 20 | + n : int |
| 21 | + Number of pools to optimize. |
| 22 | + cntry_names : list of str |
| 23 | + List of country names corresponding to the columns in the loss data. |
| 24 | + sng_ann_losses : pandas.DataFrame |
| 25 | + Dataframe of annual loss data for each country. |
| 26 | + principal_sng_dic : dict |
| 27 | + Principal values for each country. |
| 28 | + n_opt_rep : int, optional |
| 29 | + Number of optimization repetitions for seed analysis (default is 100). |
| 30 | + Returns |
| 31 | + ------- |
| 32 | + country_allocation : pandas.DataFrame |
| 33 | + DataFrame containing a optimal country allocation for the minimum concentration solution. |
| 34 | + algorithm_result: pymoo.core.result.Result |
| 35 | + Result object from the optimization containing details of the optimization process. |
| 36 | + """ |
| 37 | + opt_rep = range(0,n_opt_rep,1) |
| 38 | + df_losses = pd.DataFrame(sng_ann_losses) |
| 39 | + |
| 40 | + ### TRANSFROM PRINCIPAL VALUES TO LIST ### |
| 41 | + principal_sng = principal_sng_dic.set_index('Key').loc[cntry_names, 'Value'].tolist() |
| 42 | + |
| 43 | + ### CALCULATE ALPHA FOR RISK CONCENTRATION OPTIMIZATION ### |
| 44 | + RT = len(df_losses[cntry_names[0]]) |
| 45 | + alpha = 1-1/RT |
| 46 | + |
| 47 | + bools = df_losses >= np.quantile(df_losses, alpha, axis=0) |
| 48 | + |
| 49 | + risk_concentration = 1.0 |
| 50 | + # Loop through repetitions for seed analysis |
| 51 | + for index in opt_rep: |
| 52 | + # Define Problem and Algorithm (same as inside the loop) |
| 53 | + problem = PoolOptimizationFixedNumber(principal_sng, df_losses, bools, alpha, n, calc_pool_conc) |
| 54 | + algorithm = GA( |
| 55 | + pop_size=2000, |
| 56 | + sampling=IntegerRandomSampling(), |
| 57 | + crossover=HalfUniformCrossover(), |
| 58 | + mutation=PolynomialMutation(repair=RoundingRepair()), |
| 59 | + eliminate_duplicates=True, |
| 60 | + ) |
| 61 | + |
| 62 | + # Solve the problem |
| 63 | + res_reg = minimize(problem, algorithm, verbose=False, save_history=True) |
| 64 | + |
| 65 | + # Process results (same code as inside the loop) |
| 66 | + x = res_reg.X |
| 67 | + risk_concentration_new = res_reg.F |
| 68 | + if risk_concentration_new is not None and risk_concentration is not None and risk_concentration_new < risk_concentration: |
| 69 | + algorithm_result = res_reg |
| 70 | + risk_concentration = risk_concentration_new |
| 71 | + sorted_unique = sorted(set(x)) |
| 72 | + rank_dict = {value: rank + 1 for rank, value in enumerate(sorted_unique)} |
| 73 | + x = [rank_dict[value] for value in x] |
| 74 | + |
| 75 | + # Add to dump dataframe |
| 76 | + country_allocation = pd.DataFrame(columns=[cntry_names, 'min_conc']) |
| 77 | + country_allocation = pd.DataFrame([x], columns=cntry_names) |
| 78 | + country_allocation['min_conc'] = pd.DataFrame([res_reg.F], columns=['min_conc']) |
| 79 | + |
| 80 | + return country_allocation, algorithm_result |
| 81 | + |
| 82 | + |
| 83 | + |
| 84 | + |
6 | 85 |
|
7 | 86 | def calc_pool_conc(x, data_arr, bools, alpha): |
8 | 87 | """Calculate diversification of a given pool. Used to |
|
0 commit comments