Explicação sobre aleatoriedade – Jogo do Ultimato
O Jogo do Ultimato e o seu derivado, o Jogo do Ditador, são dois experimentos clássicos da teoria dos jogos e da economia comportamental que revelam importantes facetas da natureza humana. Ambos os jogos envolvem a divisão de uma quantia em dinheiro entre dois participantes, mas com uma diferença crucial em suas regras, o que leva a resultados e interpretações distintas sobre o que motiva as decisões das pessoas.
O Jogo do Ultimato
No Jogo do Ultimato, dois jogadores, que não se conhecem, têm a tarefa de dividir uma soma de dinheiro. O primeiro jogador, o “Proponente”, recebe a quantia e deve propor uma divisão ao segundo jogador, o “Receptor”. O Receptor, por sua vez, tem duas opções: aceitar a oferta, e nesse caso o dinheiro é dividido conforme a proposta, ou recusá-la, situação em que ambos os jogadores não recebem nada.
A lógica da teoria da escolha racional sugere que o Proponente, buscando maximizar seu próprio ganho, deveria oferecer a menor quantia possível acima de zero (por exemplo, se tiver 10 reais, dar 1 real para o Receptor e ficar com outros 9 reais). O Receptor, agindo de forma puramente racional, deveria aceitar qualquer oferta, por menor que seja, pois qualquer valor é melhor do que zero.
Contudo, os resultados experimentais consistentemente desafiam essa previsão. Na prática, Proponentes geralmente oferecem divisões mais equitativas, frequentemente entre 40% e 50% do total. Ofertas muito baixas, abaixo de 20% a 30%, são frequentemente rejeitadas pelos Receptores.
Essa discrepância evidencia que a tomada de decisão humana não é guiada apenas pelo interesse próprio. Fatores como o senso de justiça e o medo da punição (a rejeição da oferta) desempenham um papel crucial. Os Receptores preferem sair sem nada a aceitar uma oferta que consideram injusta, punindo assim o comportamento egoísta do Proponente. Por sua vez, os Proponentes, antecipando essa possível retaliação, tendem a fazer ofertas mais generosas.
O Jogo do Ditador
O Jogo do Ditador é uma variação simplificada do Jogo do Ultimato. A principal diferença é a eliminação do poder de veto do segundo jogador. No Jogo do Ditador, o primeiro jogador, agora chamado de “Ditador”, decide como dividir a quantia de dinheiro, e o segundo jogador, o “Receptor”, não tem outra opção a não ser aceitar a divisão proposta.
O jogo do ditador não será aproveitado nessa exemplificação, ficando aqui descrita apenas por curiosidade.
Proposta de simulação do jogo do ultimato
Para a simulação, a escolha racional será substituída por uma probabilidade de aceitar a oferta. Se o Proponente oferecer uma divisão de 50%-50%, o Receptor irá sempre aceitar a oferta. Se o Proponente oferecer uma divisão de 100%-0%, o Receptor irá sempre rejeitar a oferta – convenhamos que não faz sentido no jogo o Proponente ofertar essa divisão. As relações intermediárias terão a probabilidade proporcionais no intervalo. Por exemplo, se o Proponente oferecer uma divisão de 60%-40%, o Receptor terá uma probabilidade de 80% em aceitar a oferta.
Para a simulação, vamos considerar que o Proponente tem R$ 100,00 para distribuir. Ele irá sortear uma proposta de valor no intervalo entre 1% e 50% do valor (deixar para o Receptor um valor entre R$ 1,00 e R$ 50,00). O Receptor terá uma probabilidade de 2 vezes a porcentagem oferecida para aceitar a oferta.
Será mostrado ao final a quantidade de ofertas aceitas e recusadas e os valores acumulados do Proponente e do Receptor.
import random
def simular_jogo_do_ultimato(num_simulacoes=1000):
"""
Argumentos:
num_simulacoes (int): O número de vezes que a simulação será executada.
Retorna:
dict: Um dicionário contendo os resultados da simulação.
"""
# Contadores para os resultados
ofertas_aceitas = 0
ofertas_recusadas = 0
total_proponente = 0.0
total_receptor = 0.0
valor_total_ofertado = 100.0
print(f"--- Simulação do Jogo do Ultimato ({num_simulacoes} rodadas) ---\n")
# Loop principal da simulação
for i in range(num_simulacoes):
# 1. Proponente sorteia uma oferta entre R$ 1,00 e R$ 50,00
oferta_proponente = random.randint(1, 50)
# 2. Calcular a probabilidade de aceitação do Receptor
# A probabilidade é 2x a porcentagem oferecida.
# Ex: oferta de R$25 (25%) -> prob = 2 * 0.25 = 0.50 (50%)
percentual_ofertado = oferta_proponente / valor_total_ofertado
probabilidade_aceitacao = 2 * percentual_ofertado
# 3. Receptor decide se aceita ou não a oferta
# Sorteia um número entre 0 e 1. Se for menor ou igual à probabilidade, ele aceita.
if random.random() <= probabilidade_aceitacao:
# Oferta ACEITA
ofertas_aceitas += 1
ganho_proponente = valor_total_ofertado - oferta_proponente
ganho_receptor = oferta_proponente
total_proponente += ganho_proponente
total_receptor += ganho_receptor
else:
# Oferta RECUSADA
ofertas_recusadas += 1
# Ambos não ganham nada nesta rodada
ganho_proponente = 0
ganho_receptor = 0
# --- Cálculo dos resultados finais ---
# Taxas de aceitação e recusa
taxa_aceitacao = (ofertas_aceitas / num_simulacoes) * 100
taxa_recusa = (ofertas_recusadas / num_simulacoes) * 100
# Ganhos médios por rodada
ganho_medio_proponente = total_proponente / num_simulacoes
ganho_medio_receptor = total_receptor / num_simulacoes
# Ganhos médios por rodada bem-sucedida (quando a oferta é aceita)
ganho_medio_proponente_sucesso = total_proponente / ofertas_aceitas if ofertas_aceitas > 0 else 0
ganho_medio_receptor_sucesso = total_receptor / ofertas_aceitas if ofertas_aceitas > 0 else 0
# Monta o dicionário de resultados
resultados = {
"Total de Simulações": num_simulacoes,
"Ofertas Aceitas": ofertas_aceitas,
"Ofertas Recusadas": ofertas_recusadas,
"Taxa de Aceitação (%)": f"{taxa_aceitacao:.2f}%",
"Taxa de Recusa (%)": f"{taxa_recusa:.2f}%",
"Ganho Total do Proponente": f"R$ {total_proponente:.2f}",
"Ganho Total do Receptor": f"R$ {total_receptor:.2f}",
"Ganho Médio por Rodada (Proponente)": f"R$ {ganho_medio_proponente:.2f}",
"Ganho Médio por Rodada (Receptor)": f"R$ {ganho_medio_receptor:.2f}",
"Ganho Médio por Oferta Aceita (Proponente)": f"R$ {ganho_medio_proponente_sucesso:.2f}",
"Ganho Médio por Oferta Aceita (Receptor)": f"R$ {ganho_medio_receptor_sucesso:.2f}",
}
return resultados
# Executa a simulação e imprime os resultados
if __name__ == "__main__":
resultados_finais = simular_jogo_do_ultimato(1000)
for chave, valor in resultados_finais.items():
print(f"{chave}: {valor}")
Um exemplo da execução do código é mostrado abaixo. A taxa de recusa deve ficar em torno de 50%, o que fará que em torno de R$ 50.000,00 dos R$ 100.000,00 sejam “embolsados” pelos participantes (algo em torno de R$ 35.000,00 para o Proponente e R$ 15.000,00 para o Receptor).
Total de Simulações: 1000
Ofertas Aceitas: 526
Ofertas Recusadas: 474
Taxa de Aceitação (%): 52.60%
Taxa de Recusa (%): 47.40%
Ganho Total do Proponente: R$ 35295.00
Ganho Total do Receptor: R$ 17305.00
Ganho Médio por Rodada (Proponente): R$ 35.30
Ganho Médio por Rodada (Receptor): R$ 17.30
Ganho Médio por Oferta Aceita (Proponente): R$ 67.10
Ganho Médio por Oferta Aceita (Receptor): R$ 32.90
Experimente agora melhor a distribuição de valores para o Receptor, ou seja, oferecer mais dinheiro para o Receptor. Aumentar o valor dado ao Receptor parece irá diminuir o total arrecadado pelo Proponente. Veja o que acontecer se em veze de propor a divisão entre 1% e 50%, a proporção for entre 25% e 50% (é preciso ajustar a linha 23 para o novo intervalo de valores).
Trago a seguir a versão do código em linguagem C.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
// --- Configuração da Simulação ---
const int NUM_SIMULACOES = 1000;
const double VALOR_TOTAL_OFERTADO = 100.0;
// --- Contadores e Totais ---
int ofertas_aceitas = 0;
int ofertas_recusadas = 0;
double total_proponente = 0.0;
double total_receptor = 0.0;
// --- Inicialização do Gerador de Números Aleatórios ---
// A função 'srand' inicializa o gerador de números aleatórios com uma "semente".
// Usar 'time(NULL)' como semente garante que a sequência de números aleatórios
// seja diferente a cada execução do programa. Isso só precisa ser feito uma vez.
srand(time(NULL));
printf("--- Iniciando Simulacao do Jogo do Ultimato (%d rodadas) ---\n\n", NUM_SIMULACOES);
// --- Loop Principal da Simulação ---
for (int i = 0; i < NUM_SIMULACOES; i++) {
// 1. Proponente sorteia uma oferta entre 1 e 50
// rand() % 50 gera um número de 0 a 49. Somamos 1 para obter o intervalo 1-50.
int oferta_proponente = (rand() % 50) + 1;
// 2. Calcular a probabilidade de aceitação do Receptor
double percentual_ofertado = (double)oferta_proponente / VALOR_TOTAL_OFERTADO;
double probabilidade_aceitacao = 2.0 * percentual_ofertado;
// 3. Receptor decide se aceita ou não a oferta
// Geramos um número aleatório de ponto flutuante entre 0.0 e 1.0
double decisao_aleatoria = (double)rand() / RAND_MAX;
if (decisao_aleatoria <= probabilidade_aceitacao) {
// Oferta ACEITA
ofertas_aceitas++;
total_proponente += VALOR_TOTAL_OFERTADO - oferta_proponente;
total_receptor += oferta_proponente;
} else {
// Oferta RECUSADA
ofertas_recusadas++;
// Ambos não ganham nada nesta rodada
}
}
// --- Cálculo e Exibição dos Resultados Finais ---
// Taxas de aceitação e recusa
double taxa_aceitacao = ((double)ofertas_aceitas / NUM_SIMULACOES) * 100.0;
double taxa_recusa = ((double)ofertas_recusadas / NUM_SIMULACOES) * 100.0;
// Ganhos médios por rodada
double ganho_medio_proponente = total_proponente / NUM_SIMULACOES;
double ganho_medio_receptor = total_receptor / NUM_SIMULACOES;
// Ganhos médios por rodada bem-sucedida (quando a oferta é aceita)
double ganho_medio_proponente_sucesso = (ofertas_aceitas > 0) ? total_proponente / ofertas_aceitas : 0;
double ganho_medio_receptor_sucesso = (ofertas_aceitas > 0) ? total_receptor / ofertas_aceitas : 0;
printf("--- Resultados Finais ---\n");
printf("Total de Simulacoes: %d\n", NUM_SIMULACOES);
printf("Ofertas Aceitas: %d\n", ofertas_aceitas);
printf("Ofertas Recusadas: %d\n", ofertas_recusadas);
printf("Taxa de Aceitacao: %.2f%%\n", taxa_aceitacao); // %% para imprimir o caractere '%'
printf("Taxa de Recusa: %.2f%%\n", taxa_recusa);
printf("----------------------------------------\n");
printf("Ganho Total do Proponente: R$ %.2f\n", total_proponente);
printf("Ganho Total do Receptor: R$ %.2f\n", total_receptor);
printf("----------------------------------------\n");
printf("Ganho Medio por Rodada (Proponente): R$ %.2f\n", ganho_medio_proponente);
printf("Ganho Medio por Rodada (Receptor): R$ %.2f\n", ganho_medio_receptor);
printf("Ganho Medio por Oferta Aceita (Proponente): R$ %.2f\n", ganho_medio_proponente_sucesso);
printf("Ganho Medio por Oferta Aceita (Receptor): R$ %.2f\n", ganho_medio_receptor_sucesso);
printf("\n--- Fim da Simulacao ---\n");
return 0; // Indica que o programa terminou com sucesso
}