1 '''module evolutionary_algorithm
2 - implements a evolutionary Optimization concept
3 - main function can be called either from console or from GUI(recommended)
4 - saves solution files in standard folder for data
5
6 @author: Tobias Heimpold
7 '''
8 import math, os, random
9 from dsc_suite.tools.toolpaths import FOLDER_FOR_DATA
10 from time import strftime, time
11 import numpy
12
14 '''generate_evolution_data
15 parameter:
16 - functions: dictionary with functions from datastructure
17 essential keys:
18 - "randomSolution" : returns a random representation
19 - "changeSolution" : returns a function to change the given
20 representation
21 - "costEvaluation" : returns the calculated costs for the
22 given representation
23 - "recombineSolutions" : returns list of new representations created
24 from the two given representations
25
26 - parameters : dictionary with algorithm parameters
27 essential keys:
28 - "parents" : number of parent individuals each generation
29 - "children" : number of children individuals each generation
30 - "generations" : number of generated generations
31
32 - file_info: dictionary with information about the file names of the data files
33 essential keys:
34 - "trial_name" : name of trial given in GUI
35 - "file_name_list" : additional information included in file name (can be empty string)
36
37 - time_check: boolean
38 True: estimates runtime with reduced samples
39 False: full calculation with saving data to files
40 '''
41
42 if time_check:
43 generations = parameters["generations"]
44 parameters["generations"] = 1
45 import psyco
46 psyco.full()
47
48 start = time()
49 calculated_rep = []
50 rep_costs = []
51
52 def compare_costs(rep_a, rep_b):
53 try:
54 cost_a = rep_costs[calculated_rep.index(rep_a)]
55 except ValueError:
56 calculated_rep.append(rep_a)
57 cost_a = functions["costEvaluation"](rep_a)
58 rep_costs.append(cost_a)
59 try:
60 cost_b = rep_costs[calculated_rep.index(rep_b)]
61 except ValueError:
62 calculated_rep.append(rep_b)
63 cost_b = functions["costEvaluation"](rep_b)
64 rep_costs.append(cost_b)
65
66
67 if cost_a > cost_b:
68 return 1
69 elif cost_a == cost_b:
70 return 0
71 else:
72 return -1
73
74 parents = []
75
76 for i in range(0,parameters["parents"],1):
77 parents.append(functions["randomSolution"]())
78 j = 0
79 cost_data = []
80 costs = functions["costEvaluation"](parents[0])
81 for cost in costs:
82 cost_data.append([])
83 cost_data.append([])
84
85 while j < parameters["generations"]:
86
87 calculated_rep = []
88 rep_costs = []
89
90 for rep in parents:
91 costs = functions["costEvaluation"](rep)
92 for cost in costs:
93 index = costs.index(cost)
94 cost_data[index].append(cost)
95 cost_data[len(cost_data)-1].append(j)
96
97 children = []
98
99 for i in range(0,len(parents)-1,1):
100 for k in range(i+1,len(parents),1):
101
102 new_children = functions["recombineSolutions"](parents[i], parents[k])
103
104 while parameters["children"] > len(new_children):
105 rand = random.random()
106 index = int(rand*len(new_children))
107 new_children.append( functions["changeSolution"]()(new_children[index]))
108
109 for num in range(0,parameters["children"],1):
110 rand = random.random()
111 index = int(rand*len(new_children))
112 children.append(new_children.pop(index))
113
114 for i in range(0,int(len(children)*0.05),1):
115 rand = random.random()
116 index = int(rand*len(new_children))
117 children[index] = functions["changeSolution"]()(children[index])
118
119 children.sort(compare_costs)
120
121
122 amount_of_best = int(round(0.6*parameters["parents"],0))
123 amount_of_middle= int(round(0.3*parameters["parents"],0))
124 amount_of_worse= int(round(0.1*parameters["parents"],0))
125
126 parents = children[:amount_of_best]
127 temp = children[int(len(children)/2):int(len(children)/2+amount_of_middle)]
128 parents += temp
129 temp = children[int(len(children)-amount_of_worse):]
130 parents += temp
131 j += 1
132
133
134 end = time()
135 psyco.stop()
136
137
138 runtime = end-start
139
140 if time_check:
141 parameters["generations"] = generations
142 return runtime*generations
143
144 trial_name = file_info["trial_name"]
145 file_name_list = file_info["file_name_list"]
146 path = '/' + trial_name + '/Evolutionary Algorithm/'
147 if not os.path.exists(FOLDER_FOR_DATA + path):
148 os.makedirs(FOLDER_FOR_DATA + path)
149 filename_list = []
150 for list in cost_data:
151 file_name_begin = file_name_list[cost_data.index(list)]
152 i = 1
153 filename = file_name_begin + ' %02i P%i C%i G%i.npy' % (i, parameters["parents"], parameters["children"], parameters["generations"])
154 while os.path.exists(FOLDER_FOR_DATA + path + filename):
155 i += 1
156 print i
157 filename = file_name_begin + ' %02i P%i C%i G%i.npy' % (i, parameters["parents"], parameters["children"], parameters["generations"])
158 filename_list.append(path + filename)
159 if not time_check:
160 numpy.save(FOLDER_FOR_DATA + path + filename, numpy.float64(list))
161
162 return filename_list
163