samedi 3 juin 2023

How can I improve my Python code for getting the least likely positions in a 5x5 array using probability weights?

I'm working on code that deals with probabilities. The error occurs on line 95. Here is the code in python

import numpy as np
from collections import Counter
from sklearn.linear_model import LogisticRegression

# Criar matriz 5x5
matriz = np.zeros((5, 5))

# Adicionar o histórico das últimas 10 jogadas
historico = [(1, 4, 4, 3), (0, 3, 1, 3), (3, 0, 4, 4), (2, 0, 2, 3), (0, 1, 3, 0), (3, 3, 4, 2), (0, 1, 2, 0), (3, 3, 2, 2), (3, 1, 4, 3)]

# Excluir a primeira posição se o histórico tiver mais de 10 jogadas
if len(historico) > 10:
    historico = historico[1:]

for jogada in historico:
    x, y, x2, y2 = jogada
    if x >= 1 and x <= 5 and y >= 1 and y <= 5:
        matriz[x - 1, y - 1] = 1

# Definir parâmetros
prob_min = 0.04  # Probabilidade mínima de 4.0%
prob_max = 0.056  # Probabilidade máxima de 5.6%
num_options = 10
max_excluded_positions = 8
min_adjacent_bombs = 2

# Criar matriz de probabilidades
probabilidades = np.zeros((5, 5))

# Contar a repetição das posições e das somas das posições
posicoes_repetidas = Counter(historico)
somas_repetidas = Counter([sum(posicao) for posicao in historico])

# Atualizar as probabilidades com base no histórico e nas repetições
for linha in range(5):
    for coluna in range(5):
        posicao = (linha+1, coluna+1)
        soma = linha+1 + coluna+1

        # Atribuir peso proporcional à repetição da posição e das somas
        peso_posicao = posicoes_repetidas[posicao]  # Peso proporcional à repetição da posição
        peso_soma = somas_repetidas[soma]  # Peso proporcional à repetição da soma da posição

        # Verificar se a posição ocorreu mais de duas vezes no espaço amostral de dez jogadas
        if posicoes_repetidas[posicao] > 2:
            peso_posicao = 0  # Zerar o peso da repetição para evitar que ocorra mais de duas vezes

        # Atribuir probabilidade com base nos pesos e nas condições
        if matriz[linha, coluna] == 1:
            probabilidade = prob_max  # Probabilidade alta para posições que já tiveram bombas
        elif linha >= 1 and linha <= 3 and coluna >= 1 and coluna <= 3 and np.sum(matriz[linha-1:linha+2, coluna-1:coluna+2]) > 0:
            probabilidade = prob_max  # Probabilidade alta para posições adjacentes a posições que já tiveram bombas
        elif linha % 2 == 0 and coluna % 2 == 0:
            probabilidade = prob_max - peso_posicao * prob_min - peso_soma * prob_min  # Probabilidade média para posições pares
        else:
            probabilidade = prob_max - peso_posicao * prob_min + peso_soma * prob_min  # Probabilidade média para posições ímpares

        probabilidades[linha, coluna] = probabilidade

# Obter as coordenadas das posições disponíveis
posicoes_disponiveis = np.argwhere(matriz == 0)

# Verificar se há jogadas disponíveis suficientes
num_posicoes_disponiveis = len(posicoes_disponiveis)

if num_posicoes_disponiveis < num_options:
    print("Não há jogadas disponíveis suficientes de acordo com as restrições atuais.")
else:
    # Criar rótulos para as classes
    rótulos = np.zeros(num_posicoes_disponiveis)
    rótulos_adjacentes = np.ones(num_posicoes_disponiveis)

    # Ajustar o modelo de regressão logística para classificação
    regression = LogisticRegression(solver='liblinear', random_state=42, multi_class='auto')

    # Juntar as posições e rótulos
    dados = np.concatenate((posicoes_disponiveis, posicoes_disponiveis))
    rótulos_completos = np.concatenate((rótulos, rótulos_adjacentes))

    regression.fit(dados, rótulos_completos)  # Ajustar o modelo com os dados completos

    # Prever as probabilidades para todas as posições disponíveis
    probabilidades_previstas = regression.predict_proba(posicoes_disponiveis)[:, 1]

    # Ordenar as jogadas disponíveis com base nas probabilidades previstas
    jogadas_ordenadas = [(*coordenada, prob) for prob, coordenada in sorted(zip(probabilidades_previstas, posicoes_disponiveis), key=lambda x: x[0])]

    # Substituir a lista de jogadas adversárias pelo histórico
jogadas_adversario = historico

# Ajustar as probabilidades com base nas jogadas adversárias
for jogada_adv in jogadas_adversario:
    x_adv, y_adv, _, _ = jogada_adv
    for i in range(len(jogadas_ordenadas)):
        x1, y1, _, _ = jogadas_ordenadas[i]
        distancia = np.linalg.norm(np.array([x_adv, y_adv]) - np.array([x1, y1]))
        if distancia <= min_adjacent_bombs:
            x2, y2, prob = jogadas_ordenadas[i]
            jogadas_ordenadas[i] = (x1, y1, x2, y2, prob_min * (min_adjacent_bombs + 1 - distancia))



# Selecionar as próximas jogadas com menor probabilidade de haver bombas
coordenadas_jogadas = [(x1 + 1, y1 + 1, x2 + 1, y2 + 1) for (x1, y1, x2, y2, _) in jogadas_ordenadas[:num_options]]

# Imprimir a matriz
print("Matriz:")
print(matriz)

# Imprimir as próximas jogadas
print("Próximas jogadas com menor probabilidade de haver bombas:")
print(coordenadas_jogadas)


ValueError                                Traceback (most recent call last)
<ipython-input-40-38fbf6639a05> in <cell line: 92>()
     93     x_adv, y_adv, _, _ = jogada_adv
     94     for i in range(len(jogadas_ordenadas)):
---> 95         x1, y1, _, _ = jogadas_ordenadas[i]
     96         distancia = np.linalg.norm(np.array([x_adv, y_adv]) - np.array([x1, y1]))
     97         if distancia <= min_adjacent_bombs:

ValueError: not enough values to unpack (expected 4, got 3) 

The error is that the values ​​that the code returns are different from those that were placed. I need the code to return a list with 10 coordinates in the format (x1,y2,x2,y2) where the lowest probabilities of having been chosen by the computer are shown




Aucun commentaire:

Enregistrer un commentaire