使用遗传算法利用Phython编写控制混凝土流动性、凝结时间、和强度多目标优化的程序可以在指定流动性凝结时间强度一定的情况下得出适于进行3D打印的最优配合比
以下是可能的Python程序实现:
首先,需要定义混凝土的配合比,这可以作为一个类来定义,包括混凝土的各种特性,如水灰比、砂率、粗骨料率、掺合料种类和用量等。
import random
class ConcreteMix: def init(self, w_c_ratio, sand_ratio, coarse_ratio, admixture_type, admixture_amount): self.w_c_ratio = w_c_ratio self.sand_ratio = sand_ratio self.coarse_ratio = coarse_ratio self.admixture_type = admixture_type self.admixture_amount = admixture_amount self.properties = {}
def set_properties(self, properties):
self.properties = properties
def __str__(self):
return "Water-cement ratio: %.2f, Sand ratio: %.2f, Coarse ratio: %.2f, Admixture type: %s, Admixture amount: %.2f" % (self.w_c_ratio, self.sand_ratio, self.coarse_ratio, self.admixture_type, self.admixture_amount)
接下来,需要定义目标函数,即优化的目标,包括混凝土的流动性、凝结时间和强度。这些目标函数需要在相应的范围内进行归一化,以便于计算适应度。
class Objective: def init(self, target_slump, target_setting_time, target_strength): self.target_slump = target_slump self.target_setting_time = target_setting_time self.target_strength = target_strength
def evaluate(self, mix):
sl_diff = abs(mix.properties["slump"] - self.target_slump)
st_diff = abs(mix.properties["setting_time"] - self.target_setting_time)
st_diff = st_diff / self.target_setting_time
str_diff = abs(mix.properties["strength"] - self.target_strength)
str_diff = str_diff / self.target_strength
return 1 / (1 + sl_diff + st_diff + str_diff)
然后,需要定义遗传算法的主程序。遗传算法包括选择、交叉和变异三个步骤,这些步骤需要在每一代中进行迭代,直到达到指定的停止条件。
class GeneticAlgorithm: def init(self, population_size, crossover_rate, mutation_rate, elitism_rate, max_generation): self.population_size = population_size self.crossover_rate = crossover_rate self.mutation_rate = mutation_rate self.elitism_rate = elitism_rate self.max_generation = max_generation self.population = []
def initialize_population(self, mix_class, objective_class):
for i in range(self.population_size):
w_c_ratio = random.uniform(0.3, 0.5)
sand_ratio = random.uniform(0.3, 0.5)
coarse_ratio = random.uniform(0.2, 0.4)
admixture_type = random.choice(["Superplasticizer", "Air-entraining agent", "Set retarder"])
admixture_amount = random.uniform(0, 1)
mix = mix_class(w_c_ratio, sand_ratio, coarse_ratio, admixture_type, admixture_amount)
properties = {"slump": random.uniform(50, 100), "setting_time": random.uniform(1, 6), "strength": random.uniform(20, 60)}
mix.set_properties(properties)
objective_value = objective_class.evaluate(mix)
self.population.append((mix, objective_value))
def select(self):
total_fitness = sum([p[1] for p in self.population])
selected = []
for i in range(self.elitism_rate):
selected.append(max(self.population, key=lambda p: p[1]))
for i in range(self.population_size - self.elitism_rate):
r = random.uniform(0, total_fitness)
acc = 0
for p in self.population:
acc += p[1]
if acc > r:
selected.append(p)
break
return selected
def crossover(self, parents):
offsprings = []
for i in range(self.population_size - self.elitism_rate):
parent1 = random.choice(parents)
parent2 = random.choice(parents)
if random.uniform(0, 1) < self.crossover_rate:
w_c_ratio = parent1[0].w_c_ratio if random.uniform(0, 1) < 0.5 else parent2[0].w_c_ratio
sand_ratio = parent1[0].sand_ratio if random.uniform(0, 1) < 0.5 else parent2[0].sand_ratio
coarse_ratio = parent1[0].coarse_ratio if random.uniform(0, 1) < 0.5 else parent2[0].coarse_ratio
admixture_type = parent1[0].admixture_type if random.uniform(0, 1) < 0.5 else parent2[0].admixture_type
admixture_amount = parent1[0].admixture_amount if random.uniform(0, 1) < 0.5 else parent2[0].admixture_amount
mix = ConcreteMix(w_c_ratio, sand_ratio, coarse_ratio, admixture_type, admixture_amount)
properties = {}
for key in ["slump", "setting_time", "strength"]:
properties[key] = parent1[0].properties[key] if random.uniform(0, 1) < 0.5 else parent2[0].properties[key]
mix.set_properties(properties)
objective_value = Objective.evaluate(mix)
offsprings.append((mix, objective_value))
return offsprings
def mutate(self, offsprings):
for offspring in offsprings:
if random.uniform(0, 1) < self.mutation_rate:
offspring[0].w_c_ratio += random.uniform(-0.05, 0.05)
offspring[0].sand_ratio += random.uniform(-0.05, 0.05)
offspring[0].coarse_ratio += random.uniform(-0.05, 0.05)
offspring[0].admixture_amount += random.uniform(-0.1, 0.1)
for key in ["slump", "setting_time", "strength"]:
offspring[0].properties[key] += random.uniform(-5, 5)
offspring[1] = Objective.evaluate(offspring[0])
def evolve(self, mix_class, objective_class):
self.initialize_population(mix_class, objective_class)
for i in range(self.max_generation):
parents = self.select()
offsprings = self.crossover(parents)
self.mutate(offsprings)
self.population = parents + offsprings
self.population.sort(key=lambda p: p[1], reverse=True)
print("Generation %d: Objective = %.3f" % (i + 1, self.population[0][1]))
return self.population[0][0]
最后,可以使用遗传算法进行优化:
target_slump = 70 target_setting_time = 3 target_strength = 40
ga = GeneticAlgorithm(population_size=100, crossover_rate=0.8, mutation_rate=0.1, elitism_rate=5, max_generation=50) best_mix = ga.evolve(ConcreteMix, Objective(target_slump, target_setting_time, target_strength))
print("Best mix: ", best_mix)
原文地址: https://www.cveoy.top/t/topic/bSt6 著作权归作者所有。请勿转载和采集!