基于遺傳算法的多目標優(yōu)化進行0-1規(guī)劃
第一次寫博客不知道從哪里下手, 之所以想開始博客寫作一方面是想記錄自己寫過的代碼,另一方面也分享一下自己在編程的時候遇到的問題,也希望可以幫助到各位。
1、題目背景
之所以做基于遺傳算法的多目標優(yōu)化進行0-1規(guī)劃,是因為在做數(shù)學建模2021年C題的時候遇到了一個規(guī)劃題,題目詳情可以在數(shù)學建模官方網站下載參考。本篇博客主要還是講解下算法的主要框架,在進行多目標優(yōu)化求解的時候可以使用多種算法,如遺傳算法(Genetic Algorithms)、粒子群算法(Particle Swarm Optimization)、差分進化算法(Differential Evolution)、NSGA-II(Non-Dominated Sorting Genetic Algorithm II)、SPEA2(Strength Pareto Evolutionary Algorithm 2),在這里我使用的是遺傳算法,在使用python進行優(yōu)化求解的時候也可以使用不同的庫,如DEAP、PyGMO、GAFT,但更推薦使用DEAP,相對來說使用DEAP庫來構建遺傳算法結果更為清晰,支持遺傳算法、進化策略和遺傳規(guī)劃等算法,提供了許多功能,例如多種選擇和交叉算子、多種進化算法的實現(xiàn)、可視化工具等。
2、算法框架
總的來說,使用DEAP進行遺傳算法的搭建主要包括一下幾個部分:目標函數(shù)、約束函數(shù)、個體生成函數(shù)、交叉函數(shù)、評估函數(shù)、注冊遺傳算法和進行遺傳迭代求最優(yōu)解。使用DEAP進行遺傳算法的搭建,需要首先定義目標函數(shù)和約束函數(shù),這些函數(shù)形成了遺傳算法的基礎。然后需要定義個體生成函數(shù)和交叉函數(shù),用于生成新的個體和產生下一代個體。還需要定義評估函數(shù),以計算個體的適應度,并將這些函數(shù)注冊到遺傳算法框架中。在注冊完函數(shù)之后,可以開始進行遺傳算法迭代,通過選擇、交叉和變異操作來生成新的個體,并使用評估函數(shù)計算其適應度。迭代過程將持續(xù),直到達到預定的停止條件或者最大迭代次數(shù)為止。
除了上述基本步驟外,使用DEAP進行遺傳算法的搭建還需要注意一些問題,例如選擇合適的選擇算子、交叉算子和變異算子,確定種群大小和迭代次數(shù),以及如何處理復雜的多目標問題等等。此外,還可以使用DEAP提供的統(tǒng)計工具和可視化工具來分析和優(yōu)化遺傳算法的性能。
2.1目標函數(shù)的定義
遺傳算法的目標是優(yōu)化某個目標函數(shù),因此需要定義目標函數(shù),這個目標函數(shù)需要與優(yōu)化問題相匹配。例如,如果要優(yōu)化一個數(shù)學公式,則目標函數(shù)應該是該公式的輸出結果。具體的目標函數(shù)可以根據(jù)具體的問題去定義,目標函數(shù)可以定義一個或多個,通常情況下是雙目標和三目標。目標函數(shù)需要一個individual的數(shù)組,也可以說individual數(shù)組就是我們進行優(yōu)化的對象,以下是我在優(yōu)化的時候定義的其中一個目標函數(shù):
# Objective functions
def objective1(individual):
individual = np.array(individual)
x_a = individual[:128].reshape(16, 8, order='C')
x_b = individual[128:240].reshape(14, 8, order='C')
x_c = individual[240:].reshape(20, 8, order='C')
# 計算這三個矩陣中1的數(shù)目
count_a = np.sum(x_a)
count_b = np.sum(x_b)
count_c = np.sum(x_c)
return count_a + count_b + count_c`
其中individual是大小為400的一維個體數(shù)組,其中是進行0-1規(guī)劃的數(shù)據(jù),在這里對一維數(shù)組拆分成了三個二維矩陣(也可以不拆分),并計算三個矩陣中1的個數(shù),個體矩陣中1的個數(shù)和作為優(yōu)化的其中一個目標。在我的代碼中一共定義了三個目標函數(shù),這里僅給出一個作為示例。
2.2約束函數(shù)的定義
如果問題有約束條件,需要定義約束函數(shù),以確保生成的個體滿足這些約束條件。例如,如果問題要求所有個體的某些變量之和等于一個特定值或者在某個區(qū)間,則需要定義一個約束函數(shù)來確保每個個體滿足這個條件。與目標函數(shù)的定義類似,約束函數(shù)的定義也需要一個individual數(shù)組,在進行同一次遺傳迭代的時候,多個目標函數(shù)和約束函數(shù)所傳入的individual數(shù)組數(shù)據(jù)都是一致的,這樣才可以達到既滿足約束不斷趨近目標函數(shù)的目標值。在我的代碼中一共定義了三個約束條件,以下是我在優(yōu)化的時候定義的其中一個約束函數(shù):
def constraint1(individual):
individual = np.array(individual)
x_a = individual[:128].reshape(16, 8, order='C')
x_b = individual[128:240].reshape(14, 8, order='C')
x_c = individual[240:].reshape(20, 8, order='C')
row_a_sums = x_a.sum(axis=1)
row_b_sums = x_b.sum(axis=1)
row_c_sums = x_c.sum(axis=1)
# 約束條件3 每個供應商只用一個轉運商
constraint3 = 0
for i in range(len(row_a_sums)):
if row_a_sums[i] < 0 or row_a_sums[i] > 1:
constraint3 += 1
for i in range(len(row_b_sums)):
if row_b_sums[i] < 0 or row_b_sums[i] > 1:
constraint3 += 1
for i in range(len(row_c_sums)):
if row_c_sums[i] < 0 or row_c_sums[i] > 1:
constraint3 += 1
return constraint3 <=0
在這個約束函數(shù)中,對一維數(shù)組individual拆分成了三個二維矩陣,并計算三個矩陣中每行元素的和,確保每個二維數(shù)組每行的和是0或1(即確保每個二維數(shù)組每行最多只有一個1),如果滿足條件返回一個TRUE,不滿足返回FALSE,返回的值不一定是Boolean值,可以是其他類型,只要在后續(xù)判斷的時候符合邏輯即可。
2.3個體生成函數(shù)的定義
前面講到individual個體數(shù)組就是我們進行優(yōu)化的對象,那么對于individual數(shù)組的生成也有多種方法。定義一個函數(shù)來生成初始種群中的個體,這個函數(shù)應該生成符合問題要求的隨機個體。例如,如果要優(yōu)化一個數(shù)學公式,則可以隨機生成符合預定范圍的變量,并將這些變量組合成一個個體。定義個體生成函數(shù)通常有兩種方式,一種是直接使用DEAP 庫中的 initRepeat 方法生成一個個體,另外一種是自定義一個個體生成函數(shù),確保生成的個體達到想要的結果。以下是兩種方法的示例:
(1)使用DEAP 庫中的 initRepeat 方法
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, n=2)
這行代碼使用 DEAP 庫中的 initRepeat 方法生成一個個體,其中 creator.Individual 指定了個體的類別, toolbox.attr_float 指定了個體的屬性生成函數(shù), n=2 指定了個體的屬性數(shù)量。creator.Individual 是一個由 list 類型派生出來的類,它的實例是一個由屬性組成的列表。toolbox.attr_float 指定了一個屬性生成函數(shù),用于生成一個隨機的實數(shù),其范圍為 [-1, 1]。n=2 指定了個體的屬性數(shù)量為 2,因此每個個體由兩個隨機實數(shù)構成。
使用 initRepeat 方法可以方便地生成一定數(shù)量的相同類型的個體,而不需要手動編寫循環(huán)來生成每個個體。在遺傳算法中,通常會使用 initRepeat 方法生成一個初始種群,然后使用選擇、交叉和變異算子生成新的后代個體,并將其合并到當前種群中進行下一輪迭代。最終,遺傳算法會返回一個最優(yōu)個體,其屬性值代表了問題的最優(yōu)解。
(2)使用自定義個體生成函數(shù):
def initIndividual():
individual = np.zeros(400, dtype=int)
for i in range(50):
row_start = i * 8
if np.random.uniform() < 0.7:
j = np.random.choice(8)
row_start += j
individual[row_start] = int(1)
# 創(chuàng)建個體對象
ind = creator.Individual(individual)
return ind
在自定義的個體生成函數(shù)中,使用 NumPy 庫中的 zeros 方法創(chuàng)建一個大小為 400 的整型數(shù)組,然后使用循環(huán)隨機地將其中的一些元素設置為 1。
循環(huán)中的 i 變量用于迭代所有的行,其中每行包含 8 個元素。row_start 變量用于計算當前行的起始下標,即 i*8。隨后,使用 np.random.uniform() 方法生成一個隨機實數(shù),如果小于 0.7,則在當前行內隨機選擇一個元素,將其設置為 1。這里使用 np.random.choice(8) 方法從 0 到 7 中隨機選擇一個整數(shù),表示當前行內的某個位置。也就是每行最多只有一個1,雖然我在約束中限制了每行只有一個1,但為了加快優(yōu)化算法的收斂速度,在生成個體的時候對個體數(shù)組也進行了構造和設計。
最后,將生成的二進制串個體轉換為 DEAP 庫中的 creator.Individual 類型,并返回該個體對象。在 DEAP 的遺傳算法中,可以使用該函數(shù)作為個體生成函數(shù),生成一個由二進制串個體組成的初始種群。一定主要自定義的個體生成函數(shù)的返回值要是creator中的Individual類型。
此外,還需要將自定義個體生成函數(shù)注冊到遺傳算法中去,使用以下代碼進行注冊。
# Structure initializers
toolbox.register("individual", tools.initIterate, creator.Individual, initIndividual)
toolbox.register("population", tools.initRepeat, list, initIndividual)
使用了 DEAP 庫中的 initIterate 和 initRepeat 方法來注冊個體生成函數(shù)和種群生成函數(shù)。
2.4交叉函數(shù)的定義
定義一個函數(shù)來實現(xiàn)個體之間的交叉操作,以產生新的個體。例如,可以隨機選擇兩個個體,然后從它們的基因中隨機選擇一些片段進行交換,以產生新的個體。交叉函數(shù)的定義方式與個體生成函數(shù)的定義方式相似,可以使用DEAP 庫中提供的交叉方法,也可以使用自定義的交叉方法然后注冊到遺傳算法中。以下是兩種方法的示例:
(1)使用DEAP 庫中提供的交叉方法
toolbox.register("mate", tools.cxTwoPoint)
這行代碼使用 DEAP 庫中的 cxTwoPoint 方法注冊了一個兩點交叉算子,該算子用于對兩個個體進行交叉操作。
在遺傳算法中,交叉是將兩個個體的某些部分進行組合,生成新的個體的過程。兩點交叉算子是其中一種常用的交叉算子,它首先隨機選擇兩個交叉點,然后將這兩個交叉點之間的部分進行交換。除了兩點交叉,DEAP 庫中還提供了其他的交叉方法,可以自行查閱。
(2)使用自定義的交叉方法
def swap_crossover(child1, child2):
# 對 child1 和 child2 進行基因對換
child1[:], child2[:] = child2[:], child1[:]
由于我在代碼中做的是0-1規(guī)劃,如果使用DEAP 庫中的 cxTwoPoint 方法或者其他交叉方法,在后續(xù)遺傳迭代生成的個體中不能保證個體元素是0或1(即可能產生0-1的浮點數(shù)或者其他非范圍的數(shù)),不符合0-1規(guī)劃的條件,所以在這里我自定義的交叉函數(shù)是只對子個體進行對換操作,而不改變個體的元素。
# 注冊基因對換交叉方法
toolbox.register("mate", swap_crossover)
在自定義的交叉函數(shù)定義完成之后,還必須將其注冊到遺傳算法中。
2.5評估函數(shù)的定義
既然對于一個優(yōu)化算法來說,有了優(yōu)化目標,就需要對優(yōu)化的目標進行評定,所以需要定義一個函數(shù)來評估每個個體的適應度,以確定它們在下一代中的選擇概率。例如,可以將每個個體的目標函數(shù)值作為適應度,以便更好地選擇適合的個體。
def evaluate(individual):
if not constraint1(individual) or not constraint2(individual) or not constraint3(individual):
return float('inf'), float('inf'), float('inf') # Return infinite values for violated constraints
objective1_val = objective1(individual)
objective2_val = objective2(individual)
objective3_val = objective3(individual)
# Return the objectives as a tuple
return objective1_val, objective2_val, objective3_val
這段代碼實現(xiàn)了一個個體評價函數(shù) evaluate,用于計算個體在多目標優(yōu)化問題中的適應度值。具體來說,該函數(shù)接受一個個體作為輸入,然后計算該個體在問題的三個目標函數(shù)上的取值,并將三個目標函數(shù)的值作為一個元組返回。
在計算目標函數(shù)值之前,該函數(shù)首先對個體進行約束檢查。具體來說,該函數(shù)使用了三個約束函數(shù) constraint1、constraint2 和 constraint3,對個體是否符合問題的約束進行檢查。如果個體不符合約束條件,則將三個目標函數(shù)的值全部設為無窮大,表示該個體不可行。
如果個體符合約束條件,則計算其在三個目標函數(shù)上的取值,并將三個目標函數(shù)的值作為一個元組返回。具體來說,該函數(shù)使用了三個目標函數(shù) objective1、objective2 和 objective3,分別計算個體在問題的三個目標函數(shù)上的取值。最終,該函數(shù)將三個目標函數(shù)的值作為一個元組返回,表示該個體在多目標優(yōu)化問題中的適應度值。
2.6注冊遺傳算法
在目標函數(shù)、約束函數(shù)、個體生成函數(shù)、交叉函數(shù)、評估函數(shù)等各個子模塊都定義完畢之后就可以構建遺傳算法了,通常來說遺傳算法的注冊需要包括以下內容。
# Create FitnessMulti object as fitness object and define weights
creator.create("FitnessMulti", base.Fitness, weights=(-1, -0.1, -0.5))
# Create Individual object as an individual in the population and specify fitness
creator.create("Individual", list, fitness=creator.FitnessMulti)
toolbox = base.Toolbox()
# Attribute generator
toolbox.register("attribute", random.uniform, 0, 1) # Assuming continuous variables between 0 and 1
# Structure initializers
toolbox.register("individual", tools.initIterate, creator.Individual, initIndividual)
toolbox.register("population", tools.initRepeat, list, initIndividual)
toolbox.register("evaluate", evaluate)
# Constraints
penalty_value = 10 # Adjust penalty value based on the problem
toolbox.decorate("evaluate", tools.DeltaPenalty(constraint1, penalty_value))
toolbox.decorate("evaluate", tools.DeltaPenalty(constraint2, penalty_value))
toolbox.decorate("evaluate", tools.DeltaPenalty(constraint3, penalty_value))
# Genetic operators
# 注冊基因對換交叉方法
toolbox.register("mate", swap_crossover)
toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=1, indpb=0.1) # Adjust parameters if needed
toolbox.register("select", tools.selNSGA2)
creator.create(“FitnessMulti”, base.Fitness, weights=(-1, -0.1, -0.5)) 權重的負號表示該目標函數(shù)是一個最小化目標函數(shù)。在多目標優(yōu)化問題中,通常會定義多個目標函數(shù),每個目標函數(shù)都有一個權重系數(shù),用于平衡不同目標之間的重要性。權重系數(shù)的正負號決定了該目標函數(shù)是最小化目標函數(shù)還是最大化目標函數(shù)。在這里,creator.create(“FitnessMulti”, base.Fitness, weights=(-1, -0.1, -0.5)) 定義了三個目標函數(shù)的權重,分別為 -1、-0.1 和 -0.5。這里的負號表示這三個目標函數(shù)都是最小化目標函數(shù),即目標函數(shù)值越小,個體的適應度越高。
creator.create(“Individual”, list, fitness=creator.FitnessMulti) 使用 creator.create 方法定義了一個名為 Individual 的新類別,該類別繼承自 Python 中的 list 類,并將 FitnessMulti 類別作為其適應度值。
toolbox = base.Toolbox() 代碼使用 base.Toolbox() 方法創(chuàng)建了一個工具箱對象 toolbox,用于注冊個體的屬性生成、初始化方法、評價函數(shù)、約束條件、遺傳算子等操作。具體來說,該段代碼使用 toolbox.register 方法注冊了屬性生成器、個體初始化器、種群初始化器、評價函數(shù)、約束條件、基因對換交叉方法、高斯變異方法和選擇方法等操作。
toolbox.register(“attribute”, random.uniform, 0, 1) 注冊了一個屬性生成器,用于生成個體的屬性值。該生成器使用 random.uniform 方法,以均勻分布隨機生成一個在 [0, 10] 區(qū)間內的實數(shù)作為個體屬性值。
toolbox.register(“individual”, tools.initIterate, creator.Individual, initIndividual) 注冊了一個個體初始化器,該初始化器使用 tools.initIterate 方法,以 initIndividual 函數(shù)作為迭代器,逐個生成個體的屬性值,并將 creator.Individual 類別作為個體類型。
**toolbox.register(“population”, tools.initRepeat, list, initIndividual) ** 注冊了一個種群初始化器,該初始化器使用 tools.initRepeat 方法,以 initIndividual 函數(shù)作為個體初始化器,逐個生成種群中的個體,并將 list 類作為種群類型。
toolbox.register(“evaluate”, evaluate) 注冊了一個評價函數(shù),用于計算個體在多目標優(yōu)化問題中的適應度值。
toolbox.decorate(“evaluate”, tools.DeltaPenalty(constraint1, penalty_value)) 注冊了三個約束條件,用于限制可行解的解空間。penalty_value 表示約束條件不滿足時所施加的懲罰值,在使用 tools.DeltaPenalty 這種約束處理器時,當個體不滿足約束條件時,會將其適應度值懲罰為原來的值加上懲罰值。penalty_value 的設置可以影響到優(yōu)化算法的收斂性和結果,通常需要根據(jù)具體問題的特點進行調整。
toolbox.register(“mate”, swap_crossover) 定義了一個交叉算子,用于將兩個個體進行基因對換操作。
toolbox.register(“mutate”, tools.mutGaussian, mu=0, sigma=1, indpb=0.1) 定義了一個變異算子,用于對個體的某些決策變量進行高斯變異操作。
toolbox.register(“select”, tools.selNSGA2) 定義了一個選擇算子,用于根據(jù)多目標優(yōu)化問題的特點,選擇多個非支配解作為下一代種群的父代。
經過以上的各個部分的定義和遺傳算法的注冊之后,使用遺傳算法的多目標優(yōu)化進行0-1規(guī)劃的優(yōu)化算法就搭建完成,接下來就可以使用遺傳迭代進行最優(yōu)解的求解。
2.7遺傳迭代求最優(yōu)解
使用注冊的遺傳算法函數(shù),開始進行迭代,直到找到滿足停止條件的最優(yōu)解或者達到要求的最大迭代次數(shù)為止。
population_size = 200
num_generations = 100
crossover_probability = 0.5 # Adjust probability if needed
mutation_probability = 0.2 # Adjust probability if needed
# Generate initial population
initial_population = toolbox.population(n=population_size)
# Copy the initial population to the main population
population = initial_population[:]
for individual in population:
fitness_values = evaluate(individual)
individual.fitness.values = fitness_values
# Evolution loop
for generation in range(num_generations):
# Evaluate population fitness values
fitnesses = toolbox.map(evaluate, population)
for individual, fitness in zip(population, fitnesses):
individual.fitness.values = fitness
# Select next generation individuals
offspring = toolbox.select(population, len(population))
# Clone selected individuals
offspring = list(map(toolbox.clone, offspring))
# Apply crossover and mutation
for child1, child2 in zip(offspring[::2], offspring[1::2]):
if random.random() < crossover_probability:
toolbox.mate(child1, child2)
del child1.fitness.values
del child2.fitness.values
for i in range(len(offspring)):
if random.random() < mutation_probability:
offspring[i] = initIndividual()
del offspring[i].fitness.values
# Replace worst individuals with the elite individuals from the previous generation
elite_size = 10 # Number of elite individuals to preserve
# 根據(jù)適應度值對當前種群進行排序
population.sort(key=lambda x: x.fitness.values)
# 將精英個體替換掉最差的個體
offspring[-elite_size:] = population[:elite_size]
# 使用后代更新當前種群
population[:] = offspring
# Output the best individual and its fitness in each generation
best_individual = tools.selBest(population, k=1)[0]
best_fitness = best_individual.fitness.values
print(f"Generation {generation + 1} - Best Fitness: {best_fitness}")
# Output the final optimization result
best_individual = tools.selBest(population, k=1)[0]
best_fitness = best_individual.fitness.values
print(f"Best Fitness: {best_fitness}")
best_individual = np.array(best_individual)
print(f"Best Individual: {best_individual}")
這段代碼實現(xiàn)了一個基本的遺傳算法,用于求解多目標優(yōu)化問題。主要步驟包括種群初始化、評價、選擇、交叉、變異、精英策略等。主要代碼可以分為以下幾個流程:
(1)定義種群大小、迭代次數(shù)、交叉概率和變異概率等參數(shù)
population_size = 200
num_generations = 100
crossover_probability = 0.5 # Adjust probability if needed
mutation_probability = 0.2 # Adjust probability if needed
(2)生成初始種群,并計算每個個體的適應度值
initial_population = toolbox.population(n=population_size)
population = initial_population[:]
for individual in population:
fitness_values = evaluate(individual)
individual.fitness.values = fitness_values
(3)進入迭代循環(huán)
每次循環(huán)對當前種群進行選擇、交叉和變異操作,生成下一代種群。
for generation in range(num_generations):
# Evaluate population fitness values
fitnesses = toolbox.map(evaluate, population)
for individual, fitness in zip(population, fitnesses):
individual.fitness.values = fitness
# Select next generation individuals
offspring = toolbox.select(population, len(population))
# Clone selected individuals
offspring = list(map(toolbox.clone, offspring))
# Apply crossover and mutation
for child1, child2 in zip(offspring[::2], offspring[1::2]):
if random.random() < crossover_probability:
toolbox.mate(child1, child2)
del child1.fitness.values
del child2.fitness.values
for i in range(len(offspring)):
if random.random() < mutation_probability:
offspring[i] = initIndividual()
del offspring[i].fitness.values
# Replace worst individuals with the elite individuals from the previous generation
elite_size = 10 # Number of elite individuals to preserve
population.sort(key=lambda x: x.fitness.values)
offspring[-elite_size:] = population[:elite_size]
population[:] = offspring
# Output the best individual and its fitness in each generation
best_individual = tools.selBest(population, k=1)[0]
best_fitness = best_individual.fitness.values
print(f"Generation {generation + 1} - Best Fitness: {best_fitness}")
在每一代迭代中,首先使用 toolbox.map 方法對當前種群進行評價,計算每個個體的適應度值。然后,使用 toolbox.select 方法選擇下一代個體。接下來,使用 toolbox.clone 方法對選擇的個體進行克隆,以便進行后續(xù)的交叉和變異操作。接著,對每對相鄰的個體(稱為父代)進行交叉操作,如果隨機數(shù)小于交叉概率,則進行交叉操作,并刪除子代的適應度值。然后,對每個個體進行變異操作,如果隨機數(shù)小于變異概率,則將其替換為一個新的隨機個體,并刪除其適應度值。接著,使用精英策略,將上一代的精英個體替換掉下一代中適應度最差的個體,以保留優(yōu)秀的個體。最后,使用選擇方法選出當前種群中的最優(yōu)個體,并輸出其適應度值。
(4)輸出最終的最優(yōu)個體和適應度值
輸出每一代中最優(yōu)個體的適應度值,并在迭代結束后輸出最終的最優(yōu)個體和適應度值。
best_individual = tools.selBest(population, k=1)[0]
best_fitness = best_individual.fitness.values
print(f"Best Fitness: {best_fitness}")
best_individual = np.array(best_individual)
print(f"Best Individual: {best_individual}")
在迭代過程中,每一代的最優(yōu)個體的適應度值都被輸出。在迭代結束后,使用 tools.selBest 方法選出當前種群中的最優(yōu)個體,并輸出其適應度值和基因序列(這里使用 numpy 庫將個體對象轉換為數(shù)組)。
3、具體實例
3.1 2021年數(shù)學建模國賽C題第二問
參考問題 1,該企業(yè)應至少選擇多少家供應商供應原材料才可能滿足生產的需求?
針對這些供應商,為該企業(yè)制定未來 24 周每周最經濟的原材料訂購方案,并據(jù)此制定
損耗最少的轉運方案。試對訂購方案和轉運方案的實施效果進行分析。
3.2 數(shù)據(jù)格式
max_A_values.xlsx、max_B_values.xlsx、max_C_values.xlsx中數(shù)據(jù)為排名前50的供應商中在未來24周可以分別提供A、B、C材料的供應量,max_data.xlsx中是排名前50的供應商中在未來24周可以分別提供材料的供應量,即沒有區(qū)分材料種類,是max_A_values.xlsx、max_B_values.xlsx、max_C_values.xlsx的拼接,max_A_values.xlsx、max_B_values.xlsx、max_C_values.xlsx和max_data.xlsx數(shù)據(jù)格式均一致,如下表所示。文章來源:http://www.zghlxwxcb.cn/news/detail-722634.html
供應商ID | 第1周供貨量最大值 | 第2周供貨量最大值 | …… | 第24周供貨量最大值 |
---|---|---|---|---|
S229 | $2378 | $1863 | …… | $1200 |
…… | …… | …… | …… | …… |
S275 | $647 | $733 | …… | $863 |
3.3 實例代碼
限于比賽還沒結束,就先暫時不給了,有需要的可以評論區(qū)留言或者+q聯(lián)系。文章來源地址http://www.zghlxwxcb.cn/news/detail-722634.html
到了這里,關于基于遺傳算法的多目標優(yōu)化進行0-1規(guī)劃的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!