Análise de cinco algoritmos principais

algoritmo ganancioso

O algoritmo ganancioso pode obter a solução ótima local do problema, mas pode não ser capaz de obter a solução ótima global.Ao mesmo tempo, a qualidade da solução ótima depende da escolha da estratégia gananciosa. A característica é que é simples e pode obter uma solução ótima local. Assim como o método de espancamento de cachorro, com o mesmo conjunto de métodos de bastão, o nível de Hong Qigong e Lu Youjiao é muito diferente, então também é um algoritmo ganancioso, e diferentes estratégias gananciosas levarão a resultados muito diferentes

def buildItem():
    names=['A','B','C','D','E','F','G']
    vals = [35,30,6,50,40,10,25]
    weights=[10,40,30,50,35,40,30]
    Items=[]
    for i in range(len(names)):
        Items.append(Item(names[i],vals[i],weights[i]))
    return Items

def testGreedy(items,constraint,keyFunction):
    taken,val=greedy(items,constraint,keyFunction)
    print 'Total value of items taken = ', val
    for item in taken:
        print ' ', item


def testGreedys(maxWeight = 150):
    items = buildItem()

    print 'Use greedy by value to fill knapsack of size', maxWeight 
    testGreedy(items, maxWeight, value)

    print '\n Use greedy by weight to fill knapsack of size', maxWeight
    testGreedy(items, maxWeight, weightInverse)

    print '\n Use greedy by density to fill knapsack of size', maxWeight
    testGreedy(items, maxWeight, density)

Método exaustivo

O método exaustivo, também conhecido como prova de classificação, prova de análise de classificação, indução completa ou método de violência, é um método de prova matemática, que divide as proposições a serem provadas em um conjunto de situações finitas ou situações equivalentes, e então de acordo com cada uma. método direto de prova para testar se a proposição é verdadeira ou não . A prova do método exaustivo inclui duas etapas: Provar que a classificação é completa, ou seja, que cada caso a ser provado atende às condições de (pelo menos) uma classe de casos; Provar cada classe de casos separadamente.

def exhaustive_search(target, candidates):
    results = []
    for candidate in candidates:
        if candidate == target:
            results.append(candidate)
    return results

# 示例调用
target = 5
candidates = [1, 2, 3, 4, 5, 6, 7]
results = exhaustive_search(target, candidates)
print(results)

Algoritmo de programação dinâmica

O algoritmo de programação dinâmica consiste em dividir um problema em subproblemas até que os subproblemas possam ser resolvidos diretamente.

(muitas vezes dividindo subproblemas obtendo uma relação funcional recursiva)

Em seguida, salve as respostas das subperguntas para reduzir a contagem dupla.

Por fim, de acordo com a resposta da subquestão , é um método para deduzir de baixo para cima a solução do problema original.

Os mais comuns são a sequência de Fibonacci e passos de salto de sapos .

def knapsack(weights, values, capacity):
    n = len(weights)
    dp = [[0] * (capacity + 1) for _ in range(n+1)]
    
    for i in range(1, n+1):
        for j in range(1, capacity+1):
            if weights[i-1] <= j:
                dp[i][j] = max(dp[i-1][j], values[i-1] + dp[i-1][j-weights[i-1]])
            else:
                dp[i][j] = dp[i-1][j]

    chosen_items = []
    w = capacity
    for i in range(n, 0, -1):
        if dp[i][w] != dp[i-1][w]:
            chosen_items.append(i-1)
            w -= weights[i-1]

    return dp[n][capacity], chosen_items

# 示例调用
weights = [2, 3, 4, 5]
values = [3, 4, 5, 6]
capacity = 5
max_value, chosen_items = knapsack(weights, values, capacity)
print("Max Value:", max_value)
print("Chosen Items:", chosen_items)

Algoritmo ganancioso

Algoritmo ganancioso (algoritmo ganancioso, também conhecido como algoritmo ganancioso) significa que, ao resolver um problema, sempre faça a melhor escolha no momento . Ou seja, sem considerar a otimalidade geral, o algoritmo obtém uma solução ótima local em certo sentido. O algoritmo ganancioso não pode obter a solução ideal geral para todos os problemas, a chave é a escolha da estratégia gananciosa.

def make_change(coins, amount):
    coins.sort(reverse=True)  # 将硬币面额按降序排列
    change = []
    
    for coin in coins:
        while amount >= coin:
            change.append(coin)
            amount -= coin
    
    if amount != 0:
        return "无法找零"
    
    return change

# 示例调用
coins = [1, 5, 10, 25]
amount = 36
change = make_change(coins, amount)
print("找零方案:", change)

Retrocesso

O método de retrocesso é um método de busca seletiva, também conhecido como método heurístico. Este método encontra todas as soluções que satisfazem a condição .

Primeiro, procure avançar de acordo com as condições ideais e tente atingir a meta.

Quando uma determinada etapa é explorada, verifica-se que a escolha original não é a ideal ou o objetivo não pode ser alcançado , então dê um passo para trás e escolha novamente.

Essa técnica de voltar e mudar de estrada se não funcionar é chamada de método de retrocesso, e o ponto de um determinado estado que satisfaz a condição de retrocesso é chamado de "ponto de retrocesso".

O método de retrocesso geralmente pesquisa o espaço de solução em profundidade (DFS) e usa funções de poda para evitar pesquisas inválidas durante o processo de pesquisa .

É um pouco exaustivo e a exaustão também pode ser considerada uma tentação, mas o método de retrocesso é uma exaustão mais inteligente.

Problema comum das oito rainhas , divisão da string do palíndromo

def backtrack(nums, path, result):
    if len(path) == len(nums):
        result.append(path[:])
        return
    
    for num in nums:
        if num not in path:
            path.append(num)
            backtrack(nums, path, result)
            path.pop()

# 示例调用
nums = [1, 2, 3]
result = []
backtrack(nums, [], result)
print("全排列结果:", result)

ramo e limite

A chamada ramificação consiste em usar o método de largura (BFS) para pesquisar sequencialmente todas as ramificações do nó atual, ou seja, todos os nós adjacentes.

Os nós que não atendem às condições são descartados e os nós restantes são adicionados à tabela de nós ativos.

Em seguida, escolha um nó da tabela (escolha estratégica) como o próximo nó,

A busca continua até que a solução desejada seja encontrada ou a lista de slipnodes esteja vazia.

O objetivo da solução do método branch andbound é encontrar uma solução que satisfaça as condições o mais rápido possível, ou encontrar a solução ótima entre as soluções que satisfaçam as condições .

Os mais comuns são o problema da mochila 01 , problema do caixeiro viajante

class Item:
    def __init__(self, weight, value):
        self.weight = weight
        self.value = value

def knapsack(items, capacity):
    items.sort(key=lambda x: x.value / x.weight, reverse=True)
    
    n = len(items)
    max_value = 0
    curr_weight = 0
    curr_value = 0
    best_solution = []
    stack = [(0, curr_weight, curr_value, [])]
    
    while stack:
        i, curr_weight, curr_value, chosen_items = stack.pop()
        
        if i >= n or curr_weight == capacity:
            if curr_value > max_value:
                max_value = curr_value
                best_solution = chosen_items
            continue
        
        item = items[i]
        
        if curr_weight + item.weight <= capacity:
            stack.append((i+1, curr_weight+item.weight, curr_value+item.value, chosen_items+[item]))
        
        upper_bound = curr_value + (capacity - curr_weight) * (item.value / item.weight)
        if upper_bound > max_value:
            stack.append((i+1, curr_weight, curr_value, chosen_items))
    
    return max_value, best_solution

# 示例调用
items = [Item(2, 3), Item(3, 4), Item(4, 5), Item(5, 6)]
capacity = 5
max_value, best_solution = knapsack(items, capacity)
print("最大价值:", max_value)
print("最佳解决方案:", [(item.weight, item.value) for item in best_solution])

Acho que você gosta

Origin blog.csdn.net/NOguang/article/details/131905234
Recomendado
Clasificación