[PYTHON] Animer les bases de la planification dynamique et des problèmes de sac à dos

Problème de sac à dos illimité

Un algorithme qui résout le problème du sac à dos sans limite sur le nombre de pièces par programmation dynamique

def knapsack02(x, W, V):
    for i in range(len(W)):
        for j in range(x + 1):
            if j < W[i]:
                dp_table[i + 1][j] = dp_table[i][j]
            else:
                dp_table[i + 1][j] = max(dp_table[i][j], dp_table[i + 1][j - W[i]] + V[i])
            movie.append(draw02(dp_table, i, j))
    return dp_table[len(W)][x]

Dessin d'animation

def draw02(dp_table, i, j):
    image = []
    if i == 0 and j == 0:
        im_text = plt.text(0, weight_limit * 1.1, "Start!", size=20)
        image.append(im_text)
    elif i == len(V) - 1 and j == weight_limit:
        im_text = plt.text(0, weight_limit * 1.1, "Finish!", size=20)
        image.append(im_text)
    elif i >= 0:
        im_text = plt.text(0, weight_limit * 1.1,
                           "Item " + str(i) + ": (V,W)=(" + str(V[i]) + ", " +  str(W[i]) + ")" , size=20)
        image.append(im_text)

    
    for w in range(weight_limit + 1):
        if j == w:
            w_lmt = plt.plot(-1, w, markersize=16, marker="$" + str(w) + "$", c="black")
        else:
            w_lmt = plt.plot(-1, w, markersize=12, marker="$" + str(w) + "$", c="gray")
        image += w_lmt        
        
    for v in range(len(V) + 1):
        if v < len(V):
            if i == v:
                item_vw = plt.plot(v + 1, -1, markersize=22, marker="$" + str(V[v]) + "," + str(W[v]) + "$", c="black")
                image += item_vw
                item_id = plt.plot(v + 1, -2, markersize=16, marker="$" + str(v) + "$", c="black")
                image += item_id
            else:
                item_vw = plt.plot(v + 1, -1, markersize=20, marker="$" + str(V[v]) + "," + str(W[v]) + "$", c="gray")
                image += item_vw
                item_id = plt.plot(v + 1, -2, markersize=12, marker="$" + str(v) + "$", c="gray")
                image += item_id
        else:
            vw = plt.plot(0, -1, markersize=20, marker="$V,W$", c="gray")
            image += vw
            
        for w in range(weight_limit + 1):
            if v == i and w == j:
                color="black"
            elif v == i + 1 and w == j:
                color="red"
            elif dp_table[v][w] == 0:
                color="lightgray"
            else:
                color="blue"
            square = plt.plot(v, w, markersize=40, marker="s", c="lightblue", alpha=0.5)
            image += square
            numeral = plt.plot(v, w, markersize=20, marker="$" + str(dp_table[v][w]) + "$", c=color)
            image += numeral
    image.append(plt.ylabel("Weight limit j", size=20))
    image.append(plt.xlabel("Items i", size=20))
    return image

Exemple d'exécution 1

import matplotlib.pyplot as plt
import matplotlib.animation as animation
from IPython.display import HTML

movie = []
weight_limit =  9
W =  [5, 2, 1]
V =  [9, 5, 2]
n =  len(W)
fig = plt.figure(figsize=(10, 10))
dp_table = [[0 for _ in range(weight_limit + 1)] for _ in range(len(W) + 1)]
movie.append(draw02(dp_table, -1, -1))
knapsack02(weight_limit, W, V)
ani = animation.ArtistAnimation(fig, movie, interval=1000, repeat_delay=1000)
ani.save("knapsack02-1.gif", writer='pillow')
HTML(ani.to_jshtml()) 

knapsack02-1.gif

Exemple d'exécution 2

import matplotlib.pyplot as plt
import matplotlib.animation as animation
from IPython.display import HTML

movie = []
weight_limit =  8
W =  [5, 6, 2, 1, 3]
V =  [8, 9, 5, 1, 7]
n =  len(W)
fig = plt.figure(figsize=(10, 10))
dp_table = [[0 for _ in range(weight_limit + 1)] for _ in range(len(W) + 1)]
movie.append(draw02(dp_table, -1, -1))
knapsack02(weight_limit, W, V)
ani = animation.ArtistAnimation(fig, movie, interval=1000, repeat_delay=1000)
ani.save("knapsack02-2.gif", writer='pillow')
HTML(ani.to_jshtml()) 

knapsack02-2.gif

Correspondance de chaîne

def stringmatch(s, t):
    movie.append(draw_s(dp_table, -1, -1))
    for i in range(len(s)):
        for j in range(len(t)):
            if s[i] == t[j]:
                dp_table[i + 1][j + 1] = dp_table[i][j] + 1
            else:
                dp_table[i + 1][j + 1] = max(dp_table[i][j + 1], dp_table[i + 1][j])
            movie.append(draw_s(dp_table, i, j))
    return dp_table[len(s)][len(t)]

Dessin d'animation

def draw_s(dp_table, i, j):
    image = []
    
    for w in range(len(t)):
        if j == w:
            w_lmt = plt.plot(-1, w + 1, markersize=16, marker="$" + t[w] + "$", c="black")
        else:
            w_lmt = plt.plot(-1, w + 1, markersize=12, marker="$" + t[w] + "$", c="gray")
        image += w_lmt        
        
    for v in range(len(s) + 1):
        if v < len(s):
            if i == v:
                item_vw = plt.plot(v + 1, -1, markersize=22, marker="$" + s[v]  + "$", c="black")
                image += item_vw
            else:
                item_vw = plt.plot(v + 1, -1, markersize=20, marker="$" + s[v] + "$", c="gray")
                image += item_vw
            
        for w in range(len(t) + 1):
            if v >= 1 and w >= 1 and s[v - 1] == t[w - 1]:
                color = "orange"
            else:
                color = "lightblue"
            square = plt.plot(v, w, markersize=40, marker="s", c=color, alpha=0.5)
            image += square
            if v == i and w == j:
                color="black"
            elif v == i and w == j + 1:
                color="black"
            elif v == i + 1 and w == j:
                color="black"
            elif v == i + 1 and w == j + 1:
                color="red"
            elif dp_table[v][w] == 0:
                color="lightgray"
            else:
                color="blue"
            numeral = plt.plot(v, w, markersize=20, marker="$" + str(dp_table[v][w]) + "$", c=color)
            image += numeral

    return image

Exemple d'exécution 1

s = "PENCILS"
t = "PENGUINS"
fig = plt.figure(figsize=(10, 10))
movie = []
dp_table = [[0 for _ in range(len(t) + 1)] for _ in range(len(s) + 1)]
stringmatch(s, t)
ani = animation.ArtistAnimation(fig, movie, interval=500, repeat_delay=1000)
ani.save("knapsack_s-1.gif", writer='pillow') 
HTML(ani.to_jshtml()) 

knapsack_s-1.gif

0-1 problème de sac à dos

def knapsack01(i, j):
    movie.append(draw01(dp_table, i, j))
    if dp_table[i][j] >= 0:
        return dp_table[i][j]
    if j == 0:
        ret = 0
    elif i == n:
        ret = 0
    else:
        dp_table[i ][j] = -2
        if W[i] > j:
            ret = knapsack01(i + 1, j)
        else:
            ret = max(knapsack01(i + 1, j), knapsack01(i + 1, j - W[i]) + V[i])

    dp_table[i][j] = ret
    movie.append(draw01(dp_table, i, j))
    return ret

Dessin d'animation

def draw01(dp_table, i, j):
    image = []
    if i > 0:
        if W[i - 1] <= j:
            arrow = " <= "
        else:
            arrow = " > "
        im_text = plt.text(0, weight_limit * 1.2,
                           "Item " + str(i) + ": (V,W)=(" + str(V[i - 1]) + ", " +  str(W[i - 1]) + ")" , size=20)
        image.append(im_text)
    else:
        if dp_table[i][j] == -1:
            im_text = plt.text(0, weight_limit * 1.2, "Start!", size=20)
            image.append(im_text)
        else:
            im_text = plt.text(0, weight_limit * 1.2, "Finish!", size=20)
            image.append(im_text)
    
    for w in range(weight_limit + 1):
        if j == w:
            w_lmt = plt.plot(-1, w, markersize=16, marker="$" + str(w) + "$", c="black")
        else:
            w_lmt = plt.plot(-1, w, markersize=12, marker="$" + str(w) + "$", c="gray")
        image += w_lmt        
        
    for v in range(len(V) + 1):
        if v < len(V):
            if i == v + 1:
                item_vw = plt.plot(v + 1, -1, markersize=22, marker="$" + str(V[v]) + "," + str(W[v]) + "$", c="black")
                image += item_vw
                item_id = plt.plot(v + 1, -2, markersize=16, marker="$" + str(v) + "$", c="black")
                image += item_id
            else:
                item_vw = plt.plot(v + 1, -1, markersize=20, marker="$" + str(V[v]) + "," + str(W[v]) + "$", c="gray")
                image += item_vw
                item_id = plt.plot(v + 1, -2, markersize=12, marker="$" + str(v) + "$", c="gray")
                image += item_id
        else:
            vw = plt.plot(0, -1, markersize=20, marker="$V,W$", c="gray")
            image += vw
            
        for w in range(weight_limit + 1):
            if v == i and w == j:
                color="red"
            elif dp_table[v][w] == -1:
                color="lightgray"
            else:
                color="blue"
            square = plt.plot(v, w, markersize=50, marker="s", c="lightblue", alpha=0.5)
            image += square
            numeral = plt.plot(v, w, markersize=20, marker="$" + str(dp_table[v][w]) + "$", c=color)
            image += numeral
    image.append(plt.ylabel("Weight limit j", size=20))
    image.append(plt.xlabel("Items i", size=20))
    return image

Exemple d'exécution 1

import matplotlib.pyplot as plt
import matplotlib.animation as animation
from IPython.display import HTML

movie = []
weight_limit  =  3
W =  [5, 2, 3, 2, 1]
V =  [9, 5, 6, 3, 2]
n =  len(W)
fig = plt.figure(figsize=(14, 7))
dp_table = [[-1 for _ in range(weight_limit + 1)] for _ in range(len(W) + 1)]
movie.append(draw01(dp_table, -1, -1))
knapsack01(0, weight_limit)
ani = animation.ArtistAnimation(fig, movie, interval=2000, repeat_delay=1000)
ani.save("knapsack01-1.gif", writer='pillow') 
HTML(ani.to_jshtml()) 

knapsack01-1.gif

Exemple d'exécution 2

import random
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from IPython.display import HTML

movie = []
weight_limit =  5
W =  [2, 4, 5, 1, 3, 6, 2]
V =  [2, 1, 5, 1, 5, 9, 1]
n =  len(W)
fig = plt.figure(figsize=(14, 8))
dp_table = [[-1 for _ in range(weight_limit + 1)] for _ in range(len(W) + 1)]
movie.append(draw01(dp_table, -1, -1))
knapsack01(0, weight_limit)
ani = animation.ArtistAnimation(fig, movie, interval=2000, repeat_delay=1000)
ani.save("knapsack01-2.gif", writer='pillow')
HTML(ani.to_jshtml()) 

knapsack01-2.gif

Recommended Posts

Animer les bases de la planification dynamique et des problèmes de sac à dos
Illustration des résultats du problème du sac à dos
Résoudre les problèmes de sac à dos à l'aide de pyomo et glpk
La popularité des langages de programmation
L'histoire de Python et l'histoire de NaN
Revue des bases de Python (FizzBuzz)
Résolvez le problème du sac à dos Python avec la méthode de branche et liée
Résolution des problèmes de sac à dos avec les outils OR de Google - Pratiquer les bases des problèmes d'optimisation combinée
À propos de la liste de base des bases de Python
Apprenez les bases de Python ① Débutants élémentaires
Résolvez avec Python [100 questions passées que les débutants et les intermédiaires devraient résoudre] (039 --045 Méthode de planification dynamique: variante Knapsack DP)
Apprenez à nouveau les bases de Theano
Ceci et celui de la notation d'inclusion.
[Python3] Comprendre les bases de Beautiful Soup
Revoir le concept et la terminologie de la régression
Principes de base pour exécuter NoxPlayer en Python
[Linux] Découvrez les bases des commandes shell
[Python3] Comprendre les bases des opérations sur les fichiers
Apprenez en implémentant avec Scipy Les bases de la régression logistique et du perceptron multicouche
À propos du comportement de copy, deepcopy et numpy.copy
Résumé des différences entre PHP et Python
Compréhension complète des concepts de Bellmanford et Dyxtra
J'ai résolu le problème le plus profond d'Hiroshi Yuki.
La réponse de "1/2" est différente entre python2 et 3
Organiser la signification des méthodes, des classes et des objets
Animation de transition du langage de programmation le plus populaire (#programming language #popular)
Changer la couleur des erreurs et avertissements Fabric
Comparez la vitesse d'ajout et de carte Python
[Python] Chapitre 02-01 Bases des programmes Python (opérations et variables)
[Chez Coder] Résoudre le problème de la dichotomie
Confirmation des bases du concours professionnel ~ pgcd et lcm ~
Description générale des notificateurs CPUFreq core et CPUFreq
J'ai lu et implémenté les variantes de UKR
Prise en compte des forces et faiblesses de Python
Les parties sympas et regrettables de Cloud Datalab
Résolvez le problème du sac à dos Python avec l'algorithme glouton