2017-07-05 2 views
0

DEAPライブラリを使用してカスタム関数を最小化することによって多目的最適化を実行しようとしています。私はいくつかの目標(ターゲット)を最小限に抑えたときにはまともな結果を得ていますが、3または4を超えると、収束しません。通常は、最初の目的を0に最小化し、他の目的は周囲を跳ね返ります(最小化しない)。DEAPを使用した多目的関数の最小化

sci-kitライブラリを使用していくつかのシミュレーションデータを記述するメタモデル(リッジ回帰)を作成しました。そのため、私のモデルは係数と切片(私のコードに含まれています)に基づいています。新しい予測は、均等に変化する約150の入力に基づいています。

3つのターゲットを最小化する年のオプションと、8つのターゲットを最小化する月のオプションがあります。

私はかなり大きいので私のコードを要点として含めました。 HEREを見つけてください。

質問: 誰でも理由が最小化されていない残りの目的のためかもしれないものの任意のアイデアを持っていますか?私は、選択、突然変異、およびクロスオーバーのプロセスで遊んでみましたが、まだ運はありません。それとも、モデルそのものに関連する可能性がありますか?私もフィットネスのために異なる体重を試しましたが、何らかの理由でそれは違いを生じさせないようです。年間目​​標のため

結果:毎月の目標のために enter image description here

結果: enter image description here

答えて

1

ちょうど私自身の質問に答えます。

私は評価中に正しい種類の値を返さなかったようです。代わりに、目標や予測の間の差の絶対値の差異のRMSEに変更

はトリックでした:あなたは私に私が苦労してきた正確に同じ問題の解決策を

def EvaluateObjective(individual): 
    prediction = calculate(individual, for_sensitivity) 
    prediction = [int(i) for i in prediction] 

    # diff = [] 
    # for y in range(len(targets)): 
    #  output = math.sqrt((targets[y] - prediction[y]) ** 2) 
    #  #output = abs(targets[y] - prediction[y]) 
    #  diff.append(output) 

    rmse = np.sqrt((sum((i - j)**2 for i, j in zip(prediction, targets))/len(targets))) 

    return (rmse,) 

enter image description here

0

ましたと。ニースの方法は、少しトリック私のプログラムの仕事を作った!

私は、重み=( - 1.0、-1.0、1.0)のように2つ以上の重みを使用しようとしたdeapユーザーがたくさんいるはずです。

I 3つのパラメータの簡単な例を掲載します(最小2つのパラメータ、最大1つのパラメータ)

  • 例では、最大、最大量の条件で、できるだけ多くのアイテムをロードする方法」についてです

    1. 重量合計を最小化:

    2. 条件サイズ」。

    3. サイズの合計を最小化します。
    4. 合計の値を最大にします。
from numpy import array 
import numpy 
import random 
from deap import base, creator, tools, algorithms 

### Multi-objective Optimization Problem ### 

IND_INIT_SIZE = 5 

MAX_WEIGHT = 2000 # kg 
MAX_SIZE = 1500 # m**3 


# Create the item dictionary: 

r = array([[213, 508, 22], # 1st arg : weight/2nd arg : size/3rd arg : value 
     [594, 354, 50], 
     [275, 787, 43], 
     [652, 218, 46], 
     [728, 183, 43], 
     [856, 308, 33], 
     [727, 482, 45], 
     [762, 683, 26], 
     [707, 450, 19], 
     [909, 309, 45], 
     [979, 247, 42], 
     [259, 705, 42], 
     [260, 543, 14], 
     [899, 825, 17], 
     [446, 360, 35], 
     [491, 818, 47], 
     [647, 404, 17], 
     [604, 623, 32], 
     [900, 840, 45], 
     [374, 127, 33]]) 


NBR_ITEMS = r.shape[0] 

items = {} 
# Create random items and store them in the items' dictionary. 
for i in range(NBR_ITEMS): 
    items[i] = (r[i][0] , r[i][1] , r[i][2]) 


creator.create("Fitness", base.Fitness, weights=(-1.0, 1.0)) # Note here <- I used only two weights! (at first, I tried weights=(-1.0 , -1.0, 1.0)) but it crashes. With deap, you cannot do such a thing. 

creator.create("Individual", set, fitness=creator.Fitness) 

toolbox = base.Toolbox() 

# Attribute generator 
toolbox.register("attr_item", random.randrange, NBR_ITEMS) 

# Structure initializers 
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_item, n=IND_INIT_SIZE) # 
toolbox.register("population", tools.initRepeat, list, toolbox.individual) 


def evaluation(individual): 
    weight = 0.0 
    size =0.0 
    value = 0.0 

    # Maximize or Minimize Conditions 
    for item in individual: 
     weight += items[item][0] # It must be minimized. 
     size += items[item][1] # It must be minimized. 
     value += items[item][2] # It must be maximized. 

    # Limit Conditions 
    if weight > MAX_WEIGHT or size > MAX_SIZE: 
     return 10000, 0 

    if value == 0: 
     value = 0.0000001 

    MinFitess_score = weight + size # NOTE : Minimize weight, size 
    MaxFitenss_score = value # NOTE : Maximize weight, size 

    return MinFitess_score , MaxFitenss_score, 



def cxSet(ind1, ind2): 
    """Apply a crossover operation on input sets. The first child is the 
    intersection of the two sets, the second child is the difference of the 
    two sets. 
    """ 
    temp = set(ind1) # Used in order to keep type 
    ind1 &= ind2 # Intersection (inplace) 
    ind2 ^= temp # Symmetric Difference (inplace) 
    return ind1, ind2 


def mutSet(individual): 
    """Mutation that pops or add an element.""" 
    if random.random() < 0.5: 
     if len(individual) > 0: # We cannot pop from an empty set 
      individual.remove(random.choice(sorted(tuple(individual)))) 
    else: 
     individual.add(random.randrange(NBR_ITEMS)) 
    return individual, # NOTE comma(,) , if there's no comma, an error occurs. 



toolbox.register("mate", cxSet) 
toolbox.register("mutate", mutSet) 
toolbox.register("select", tools.selNSGA2) # NSGA-2 applies to multi-objective problems such as knapsack problem 
toolbox.register("evaluate", evaluation) 


def main(): 
    ngen = 300 # a number of generation < adjustable value > 

    pop = toolbox.population(n= 300) 
    hof = tools.ParetoFront() # a ParetoFront may be used to retrieve the best non dominated individuals of the evolution 
    stats = tools.Statistics(lambda ind: ind.fitness.values) 
    stats.register("avg", numpy.mean, axis=0) 
    stats.register("std", numpy.std, axis=0) 
    stats.register("min", numpy.min, axis=0) 
    stats.register("max", numpy.max, axis=0) 

    algorithms.eaSimple(pop, toolbox, 0.7, 0.2, ngen=ngen, stats=stats, halloffame=hof, verbose=True) 

    return hof, pop 


if __name__ == "__main__": 
    hof, pop = main() 

    print(hof) # non-dominated individuals' list # the fittest value is placed on the most right side. 

理想的な結果:

  1. 個体({1、2、19、4})または
  2. 個体({1、2、19、3 })

合計スコアはかなり似ています。結果の1つが表示されます。

+0

私の場合、スコアを「MinFitess_score = weight + size」と「MaxFitenss_score = value」に分けて、GAを「weights =( - 1.0 、1.0) " –

関連する問題