Add pipeline_example project

This commit is contained in:
DotNaos 2025-04-17 07:07:13 +02:00
parent 3fe787e5f3
commit e505364b47
14 changed files with 5897 additions and 0 deletions

224
Code/pipeline-example/.gitignore vendored Normal file
View File

@ -0,0 +1,224 @@
# Created by https://www.toptal.com/developers/gitignore/api/python,linux,macos
# Edit at https://www.toptal.com/developers/gitignore?templates=python,linux,macos
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### macOS Patch ###
# iCloud generated files
*.icloud
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
### Python Patch ###
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
poetry.toml
# ruff
.ruff_cache/
# LSP config files
pyrightconfig.json
# End of https://www.toptal.com/developers/gitignore/api/python,linux,macos

View File

@ -0,0 +1 @@
3.13

View File

@ -0,0 +1,4 @@
{
"python-envs.defaultEnvManager": "ms-python.python:system",
"python-envs.pythonProjects": []
}

View File

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,618 @@
import os
import re
import json
from typing import List, Dict, Tuple, Union, Optional, Any, Literal
# Add datetime import for timestamped folders
from datetime import datetime
# Add Gemini imports
from google import genai
from google.genai import types
import dotenv # Load environment variables from .env file
import plotly.graph_objects as go
import pandas as pd
from sklearn.manifold import TSNE
# Add imports for Clustering and Similarity Search
from sklearn.cluster import KMeans
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np # Ensure numpy is imported if not already done earlier
from sentence_transformers import SentenceTransformer
# --- Stage 1: PDF Processing ---
from pypdf import PdfReader
# Load environment variables from .env file
dotenv.load_dotenv()
def extract_text_from_pdf(pdf_path: str) -> str:
"""Extracts text content from a PDF file."""
print(f"Processing PDF: {pdf_path}")
if not os.path.exists(pdf_path):
raise FileNotFoundError(f"PDF file not found: {pdf_path}")
try:
reader = PdfReader(pdf_path)
text = ""
for page_num, page in enumerate(reader.pages):
page_text = page.extract_text()
if page_text:
# Basic cleaning: replace multiple newlines/spaces
cleaned_text = re.sub(r"\s+", " ", page_text).strip()
text += cleaned_text + "\n" # Add newline between pages
print(f" Extracted text from page {page_num + 1}")
print(f"Finished extracting text. Total length: {len(text)} characters.")
return text
except Exception as e:
print(f"Error reading PDF {pdf_path}: {e}")
raise
# --- Stage 2: Text Chunking ---
def chunk_text(text: str, chunk_size: int = 500, chunk_overlap: int = 50) -> List[str]:
"""Splits text into overlapping chunks."""
print(f"Chunking text (size={chunk_size}, overlap={chunk_overlap})...")
if not text:
return []
chunks = []
start = 0
while start < len(text):
end = start + chunk_size
chunk = text[start:end]
chunks.append(chunk)
start += chunk_size - chunk_overlap # Move start forward for overlap
# Ensure we don't go past the end if overlap is large
if start >= len(text) - chunk_overlap and start < len(text):
# Add the last remaining part if it wasn't fully covered
final_chunk = text[start:]
if final_chunk and (
not chunks or chunks[-1] != final_chunk
): # Avoid duplicates
chunks.append(final_chunk)
break # Exit loop after handling the end
print(f"Generated {len(chunks)} chunks.")
return chunks
# --- Stage 3: Embedding Generation ---
# Load a relatively small but effective model
# This will download the model the first time it's run
embedding_model = SentenceTransformer("all-MiniLM-L6-v2")
print("Embedding model loaded.")
def generate_embeddings(chunks: List[str]) -> Tuple[List[str], List[List[float]]]:
"""Generates vector embeddings (as lists of floats) for a list of text chunks."""
if not chunks:
return [], []
print(f"Generating embeddings for {len(chunks)} chunks...")
# The model's encode function returns numpy arrays directly
embeddings = embedding_model.encode(chunks, show_progress_bar=True)
print(f"Generated embeddings of shape: {embeddings.shape}")
# Convert numpy array rows to list for easier simulation downstream
embeddings_list: List[List[float]] = [emb.tolist() for emb in embeddings]
return chunks, embeddings_list
# --- Stage 4: Simulate Supabase/pgvector Storage & Retrieval ---
# This simulates storing data, including converting vectors to pgvector's string format
# and then fetching it back, parsing the string.
# In-memory "database"
mock_db: List[Dict[str, Any]] = []
def simulate_pgvector_storage(chunks: List[str], embeddings: List[List[float]]):
"""Simulates storing chunks and embeddings in a DB like Supabase."""
print("Simulating storage...")
global mock_db
mock_db = [] # Clear previous data
for i, (chunk, embedding) in enumerate(zip(chunks, embeddings)):
# Simulate pgvector string format "[0.1,0.2,...]"
embedding_str = json.dumps(embedding)
mock_db.append(
{
"id": i,
"content": chunk,
"embedding_str": embedding_str, # Store as string
}
)
print(f"Simulated storing {len(mock_db)} items.")
def parse_pgvector_string(vector_string: str) -> List[float]:
"""Parses the string representation from pgvector into a list of floats."""
try:
return json.loads(vector_string)
except (json.JSONDecodeError, TypeError) as e:
print(f"Error parsing vector string '{vector_string[:50]}...': {e}")
return [] # Return empty list on error
def simulate_fetch_from_db() -> Tuple[List[str], List[List[float]]]:
"""Simulates fetching data and parsing vector strings."""
print("Simulating fetching data from DB...")
fetched_chunks = []
fetched_embeddings = []
for item in mock_db:
content = item.get("content")
embedding_str = item.get("embedding_str")
if content and embedding_str:
parsed_embedding = parse_pgvector_string(embedding_str)
if parsed_embedding: # Only add if parsing was successful
fetched_chunks.append(content)
fetched_embeddings.append(parsed_embedding)
else:
print(
f"Warning: Failed to parse embedding for item id {item.get('id')}"
)
print(f"Simulated fetching {len(fetched_chunks)} items with valid embeddings.")
return fetched_chunks, fetched_embeddings
# --- Stage 5: Dimensionality Reduction (t-SNE) ---
def apply_tsne(
embeddings: Union[np.ndarray, List[List[float]]],
n_components: int = 2,
perplexity: float = 30.0, # Adjust based on number of samples
learning_rate: Union[float, Literal["auto"]] = "auto",
n_iter: int = 1000,
random_state: int = 42,
verbose: int = 1,
) -> np.ndarray:
"""Applies t-SNE to reduce the dimensionality of vector embeddings."""
print("\nApplying t-SNE...")
if isinstance(embeddings, list):
embeddings_np = np.array(embeddings, dtype=np.float32)
elif isinstance(embeddings, np.ndarray):
embeddings_np = embeddings.astype(np.float32)
else:
raise TypeError("Embeddings must be a NumPy array or a list of lists.")
if embeddings_np.ndim != 2:
raise ValueError(
f"Input embeddings must be 2D, got shape {embeddings_np.shape}"
)
n_samples = embeddings_np.shape[0]
if n_samples == 0:
print("Warning: No embeddings to process with t-SNE.")
return np.empty((0, n_components))
# Adjust perplexity if it's too high for the number of samples
effective_perplexity = min(perplexity, max(1.0, n_samples - 1.0))
if effective_perplexity != perplexity:
print(
f"Warning: Perplexity adjusted from {perplexity} to {effective_perplexity} due to low sample count ({n_samples})."
)
tsne = TSNE(
n_components=n_components,
perplexity=effective_perplexity,
learning_rate=learning_rate,
n_iter=n_iter,
init="pca", # Often more stable
random_state=random_state,
verbose=verbose,
)
reduced_embeddings = tsne.fit_transform(embeddings_np)
print(f"t-SNE finished. Output shape: {reduced_embeddings.shape}")
return reduced_embeddings
# --- Stage 6: Visualization (using Plotly) ---
def plot_embeddings_interactive(
reduced_embeddings: np.ndarray,
texts: List[str],
):
"""Creates an interactive 3D Plotly scatter plot and displays it."""
if reduced_embeddings.shape[0] != len(texts):
raise ValueError("Number of embeddings and texts must match.")
if reduced_embeddings.shape[1] != 3: # Expect 3 dimensions now
raise ValueError("Reduced embeddings must be 3D for this plot.")
if reduced_embeddings.shape[0] == 0:
print("No data to plot.")
return
print("\nGenerating interactive 3D plot...")
df = pd.DataFrame(
{
"x": reduced_embeddings[:, 0],
"y": reduced_embeddings[:, 1],
"z": reduced_embeddings[:, 2], # Add z coordinate
"text": texts,
}
)
# Create hover text (limit length for readability)
hover_texts = [t[:200] + "..." if len(t) > 200 else t for t in df["text"]]
fig = go.Figure(
data=go.Scatter3d( # Use Scatter3d
x=df["x"],
y=df["y"],
z=df["z"], # Add z data
mode="markers",
marker=dict(
size=5, # Adjust marker size for 3D if needed
# color=df['z'], # Example: color by z-coordinate
# colorscale='Viridis',
# showscale=True
),
text=hover_texts, # Text shown on hover
hoverinfo="text", # Display only the hover text
)
)
fig.update_layout(
title="3D t-SNE Visualization of Text Chunk Embeddings",
scene=dict( # Use scene for 3D layout
xaxis_title="t-SNE Dimension 1",
yaxis_title="t-SNE Dimension 2",
zaxis_title="t-SNE Dimension 3", # Add z-axis label
),
hovermode="closest",
margin=dict(r=0, b=0, l=0, t=40), # Adjust margins if needed
)
# fig.write_html(output_filename) # Remove HTML saving
fig.show() # Display the plot in an interactive window
print("Plot window opened.")
# --- Gemini API Helper ---
def call_gemini_api(
prompt_text: str, model_name: str = "gemini-1.5-flash"
) -> Optional[str]:
"""Calls the Gemini API with the provided text and returns the generated content."""
try:
# Get the API key from environment variables
api_key = os.environ.get("GEMINI_API_KEY")
if not api_key:
print("Error: GEMINI_API_KEY environment variable not set.")
raise ValueError("Missing GEMINI_API_KEY")
# Initialize the client directly with the API key
# This aligns with the README example
client = genai.Client(api_key=api_key)
# Prepare the content for the API call
# The SDK handles converting the string prompt to the correct Content structure
contents = prompt_text
# Set up the generation configuration object
generation_config_obj = types.GenerateContentConfig(
temperature=0.7,
response_mime_type="text/plain", # Keep as plain text, formatting instructions are in the prompt
)
# Safety settings removed as per user request in previous step implicitly
# Generate content using the client's models.generate_content method
# Pass the generation config object to the 'config' parameter
response = client.models.generate_content(
model=model_name,
contents=contents,
config=generation_config_obj, # Corrected parameter name
# safety_settings removed
)
# Check for valid response and return text
if response and response.text:
return response.text.strip()
elif response.prompt_feedback and response.prompt_feedback.block_reason:
print(
f"Warning: Gemini API call blocked. Reason: {response.prompt_feedback.block_reason}"
)
return None
else:
# Check if the response has a 'parts' attribute (runtime check) but avoid statictype errors
if response and hasattr(response, "parts"):
parts_attr = getattr(response, "parts") # type: ignore[attr-defined]
print(
f"Warning: Gemini API response has parts but no direct text attribute. Parts: {parts_attr}"
)
try:
# Join text from all parts that expose a 'text' attribute
return " ".join(
part.text for part in parts_attr if hasattr(part, "text")
).strip()
except Exception as part_error:
print(f"Error extracting text from parts: {part_error}")
return None # Fallback if parts structure is unexpected
else:
print(
f"Warning: Gemini API response format unexpected or empty: {response}"
)
return None
except ValueError as ve: # Catch missing API key specifically
if "Missing GEMINI_API_KEY" in str(ve):
print(
"Error: GEMINI_API_KEY environment variable not set."
) # Ensure message is printed
raise ve # Re-raise to stop execution
else:
print(f"An unexpected value error occurred during Gemini API call: {ve}")
return None
except Exception as e:
print(f"Error calling Gemini API: {e}")
# Consider importing and catching specific google.api_core.exceptions if needed
# from google.api_core import exceptions as google_exceptions
# except google_exceptions.PermissionDenied: ...
return None
# --- Stage 7: Clustering and Markdown Generation ---
def generate_clustered_markdown(
reduced_embeddings: np.ndarray,
texts: List[str],
output_filename: str, # Now expects the full path including subdirectory
n_clusters: int = 5,
):
"""Performs K-Means clustering, uses Gemini for topics and rewriting (Markdown/LaTeX), and saves to Markdown."""
print("\n--- Clustering Texts and Generating Markdown with Gemini Rewriting ---")
# ... (clustering setup and KMeans prediction remain the same) ...
kmeans = KMeans(
n_clusters=n_clusters, random_state=42, n_init=10
) # n_init suppresses warning
cluster_labels = kmeans.fit_predict(reduced_embeddings)
# Group texts by cluster
clustered_texts: Dict[int, List[str]] = {i: [] for i in range(n_clusters)}
for text, label in zip(texts, cluster_labels):
clustered_texts[label].append(text)
# Build Markdown content
markdown_content = "# Clustered and Rewritten Text Document\n\n"
markdown_content += "This document groups text chunks based on semantic similarity. Topics and rewritten text (formatted in Markdown with LaTeX for equations) are generated by the Gemini API.\n\n"
for i in range(n_clusters):
cluster_topic = f"Cluster {i+1}" # Default topic
rewritten_content = "(Failed to generate rewritten text for this cluster.)" # Default content on failure
if clustered_texts[i]:
# ... (Combine chunks and limit context size as before) ...
combined_text = "\n\n---CHUNK SEPARATOR---\n\n".join(clustered_texts[i])
context_limit = (
15000 # Adjust based on model context window and typical chunk size
)
if len(combined_text) > context_limit:
print(
f"Warning: Combined text for cluster {i+1} exceeds {context_limit} chars, truncating for API call."
)
combined_text = combined_text[:context_limit] + "..."
# 1. Ask Gemini for a topic
# ... (Topic generation prompt and call remain the same) ...
topic_prompt = f"Analyze the following text excerpts separated by '---CHUNK SEPARATOR---'. Provide only a concise topic title (3-5 words maximum) that captures the main theme. Do not add any explanation or introductory text.\n\nText Excerpts:\n{combined_text}"
print(f" Generating topic for Cluster {i+1}...")
generated_topic = call_gemini_api(topic_prompt)
if generated_topic:
cluster_topic = (
generated_topic.replace('"', "").replace("Topic:", "").strip()
)
else:
print(f" Failed to generate topic for Cluster {i+1}.")
# 2. Ask Gemini to rewrite the text with Markdown and LaTeX formatting
# Updated prompt with formatting instructions
rewrite_prompt = f"""Rewrite and reorder the following text chunks, separated by '---CHUNK SEPARATOR---', into a single, coherent, and grammatically correct text.
Preserve all the original information and meaning, but improve the flow and readability.
Format the entire output as Markdown.
Use LaTeX delimiters for all mathematical equations: '$' for inline equations (e.g., $E=mc^2$) and '$$' for multiline equations (e.g., $$a^2 + b^2 = c^2$$).
Do not add any commentary, introduction, or conclusion beyond the rewritten text itself.
The output Language should be German besides technical terms.
You do not have to include citations for people or works mentioned in the text, unless they are essential to the meaning of the text.
Text Chunks:
{combined_text}"""
print(f" Rewriting text for Cluster {i+1}...")
generated_rewrite = call_gemini_api(rewrite_prompt)
if generated_rewrite:
rewritten_content = generated_rewrite
else:
print(
f" Failed to rewrite text for Cluster {i+1}. Using original chunks."
)
# Fallback to original chunks if rewrite fails
rewritten_content = (
"**Original Chunks (Rewrite Failed):**\n\n"
+ "\n\n---\n\n".join(clustered_texts[i])
)
# Add to Markdown
markdown_content += f"## {cluster_topic}\n\n"
markdown_content += (
f"{rewritten_content}\n\n" # Add the rewritten content (or fallback)
)
# Add a separator between clusters in the markdown file
if i < n_clusters - 1:
markdown_content += "\n---\n\n"
# Write to Markdown file
try:
# Ensure the directory exists before writing (handled in main)
with open(output_filename, "w", encoding="utf-8") as f:
f.write(markdown_content)
print(f"Clustered and rewritten text saved to: {output_filename}")
except IOError as e:
print(f"Error writing Markdown file {output_filename}: {e}")
print("\n--- End of Markdown Generation ---")
# --- Stage 8: Querying / Semantic Search ---
def find_similar_chunks(
query: str,
texts: List[str],
embeddings: np.ndarray, # Use original embeddings for similarity
model: SentenceTransformer,
top_n: int = 5,
) -> List[Tuple[str, float]]:
"""Finds text chunks most similar to the query."""
print(f"\nSearching for chunks similar to: '{query}'")
if embeddings.shape[0] == 0:
print("No embeddings available for search.")
return []
# Generate embedding for the query
query_embedding = model.encode([query]) # Pass query as a list
# Calculate cosine similarities
# embeddings should be 2D (n_samples, n_features)
# query_embedding should be 2D (1, n_features)
similarities = cosine_similarity(query_embedding, embeddings)[
0
] # Get the first row
# Get indices of top_n highest similarities
# If fewer results than top_n, take all available
num_results = min(top_n, len(similarities))
if num_results <= 0:
return []
# Use argsort to get indices of sorted similarities (descending)
sorted_indices = np.argsort(similarities)[::-1]
top_indices = sorted_indices[:num_results]
# Prepare results
results = [(texts[i], float(similarities[i])) for i in top_indices]
print(f"Found {len(results)} relevant chunks.")
return results
# --- Main Execution ---
if __name__ == "__main__":
pdf_file = "in/example.pdf"
# Define base output directory
base_output_dir = "output"
# Create timestamp string
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
# Create unique subdirectory path
output_subdir = os.path.join(base_output_dir, timestamp)
# Define the final markdown output file path
markdown_output_file = os.path.join(output_subdir, "clustered_rewritten_gemini.md")
try:
# Create the output directories if they don't exist
os.makedirs(output_subdir, exist_ok=True)
print(f"Output will be saved in: {output_subdir}")
# 1. Extract Text
full_text = extract_text_from_pdf(pdf_file)
# 2. Chunk Text
text_chunks = chunk_text(full_text, chunk_size=400, chunk_overlap=40)
if not text_chunks:
print("No text chunks generated. Exiting.")
exit()
# 3. Generate Embeddings
original_chunks, embeddings_list = generate_embeddings(text_chunks)
# 4. Simulate Storage & Retrieval
simulate_pgvector_storage(original_chunks, embeddings_list)
fetched_chunks, fetched_embeddings_list = simulate_fetch_from_db()
if not fetched_embeddings_list:
print("No valid embeddings fetched. Cannot proceed. Exiting.")
exit()
# Convert fetched list back to NumPy array
original_embeddings_np = np.array(fetched_embeddings_list)
# 5. Apply t-SNE
num_chunks = len(fetched_chunks)
tsne_perplexity = min(30.0, max(5.0, num_chunks / 4.0))
reduced_embeddings_3d = apply_tsne(
original_embeddings_np,
n_components=3,
perplexity=tsne_perplexity,
random_state=42,
verbose=1,
)
# 6. Visualize
if reduced_embeddings_3d.shape[0] > 0:
plot_embeddings_interactive(reduced_embeddings_3d, fetched_chunks)
else:
print("No reduced embeddings generated for plotting.")
# 7. Cluster and Generate Markdown File using Gemini
if reduced_embeddings_3d.shape[0] > 0:
num_chunks = len(fetched_chunks)
num_clusters = min(8, max(2, num_chunks // 10))
generate_clustered_markdown( # Call updated function
reduced_embeddings_3d,
fetched_chunks,
markdown_output_file, # Pass the full dynamic path
n_clusters=num_clusters,
)
else:
print("No reduced embeddings available for clustering.")
# 8. Interactive Querying Loop
print("\n--- Interactive Query Mode ---")
print("Enter a search query (or type 'quit' to exit):")
while True:
user_query = input("> ")
if user_query.lower() == "quit":
break
if not user_query.strip():
continue
# Perform search using original embeddings
search_results = find_similar_chunks(
user_query,
fetched_chunks,
original_embeddings_np, # Use full embeddings for search
embedding_model,
top_n=3, # Show top 3 results
)
if search_results:
print("--- Top Results ---")
for i, (text, score) in enumerate(search_results):
print(f"[{i+1}] Score: {score:.4f}\n Text: {text[:300]}...\n")
else:
print("No relevant chunks found.")
except FileNotFoundError as e:
print(f"Error: {e}")
print("Please ensure 'example.pdf' exists in the same directory.")
except ImportError as e:
print(f"Import Error: {e}")
print("Please ensure all required libraries are installed:")
print(
"pip install pypdf sentence-transformers torch scikit-learn numpy plotly pandas google-generativeai"
)
print("You might need: pip install scikit-learn google-generativeai")
except ValueError as e: # Catch missing API key error from helper
if "Missing GEMINI_API_KEY" in str(e):
# Message already printed in helper function, maybe add exit instruction
print("Please set the GEMINI_API_KEY environment variable and try again.")
exit(1) # Exit if API key is missing
else:
print(f"An unexpected value error occurred: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
# import traceback
# traceback.print_exc()

View File

@ -0,0 +1,364 @@
# Clustered and Rewritten Text Document
This document groups text chunks based on semantic similarity. Topics and rewritten text (formatted in Markdown with LaTeX for equations) are generated by the Gemini API.
## Game Theory Basics
Non-Cooperative Games
Game Strategies
Prisoner's Dilemma
Zero-Sum Games
Conservative Strategies
Mixed Strategies
Checkpoints Summary
Group Decisions
Collective Choice
# Spieltheorie Zusammenfassung
R.-P. Mundani, ICS, HS 2024
Non-cooperative games are widely used in literature and applications. Players cannot make agreements before the game, and they have no agreements on joint actions that are optimal for the group. A second distinction is between simultaneous games, where all players make their choice once and for all (only one choice).
R.-P. Mundani, ICS, HS 2024
**Spielen in reinen Strategien:** A dominant strategy is defined as follows: For two strategies $a_i, a_i^ ∈ A_i$, strategy $a_i$ is weakly dominant over strategy $a_i^$ if $a_i$ is at least as good as $a_i^$ for all possible actions of the other players $a_j ∈ A_j≠i$, i.e., for all $a_j ∈ A_j≠i$. If the inequality holds strictly ($>$), then we speak of strong dominance. A player can achieve a higher payoff by deviating from this, i.e., if it holds for all $a_i ∈ A_i$ and $i ∈ N$. What does this mean for the prisoner's dilemma…?
R.-P. Mundani, ICS, HS 2024
**Spielen in reinen Strategien:** Nash equilibrium: For action profile (G, G)
| | S1 | S2 |
| :---- | :---- | :---- |
| **G** | (6, 6) | (0, 8) |
| **L** | (3, 3) | (8, 0) |
The dominant strategy for both players is G. HOWEVER: The equilibrium (G, G) is inefficient, since (L, L) would yield a better payoff.
R.-P. Mundani, ICS, HS 2024
**Weiteres Beispiel: Falke-und-Taube-Spiel:** Two competitors must decide between aggressive (Hawk) and non-aggressive (Dove) behavior.
R.-P. Mundani, ICS, HS 2024
**Zwei-Personen-Nullsummenspiele:** Introduction: Players try to maximize their profit (i.e., minimize the profit of the other). The sum is always zero for all players. 2PNS games are usually represented in normal form (or matrix form).
| | S21 | S22 |
| :---- | :---- | :---- |
| **S11** | (-1, 1) | (-5, 5) |
| **S12** | (1, -1) | (-3, 3) |
Matrix form: $u_2$ or $-u_1$
R.-P. Mundani, ICS, HS 2024
**Zwei-Personen-Nullsummenspiele:** Definition: Conservative Strategies. Observation: The best opponent strategy leads to one's own worst profit. Conservative strategy: Choose the best value from all unfavorable cases. Minimizer P1 (→ intersection of minimum and maximum). The idea remains the same: no player can improve themselves through a mutual change of strategy.
R.-P. Mundani, ICS, HS 2024
**Zwei-Personen-Nullsummenspiele:** Example: Battle of the Bismarck Sea (continuation). If the Americans check the correct route, the bombing can begin immediately (otherwise two days remain for the other route). On the northern route, the bombing must also be omitted for one day due to poor visibility. This results in the following 2PNS game (profit ≡ possible days for bombing).
| | N | S |
| :---- | :---- | :---- |
| **N** | (2, 2) | (1, 3) |
| **S** | (3, 1) | (0, 0) |
$i^* = N$ and $U^- = 2$; $j^* = N$ and $U^+ = 2$; Saddle point at (N, N).
R.-P. Mundani, HS 2024
**Spielen in gemischten Strategien:** Preliminary remarks: Pure strategies: A player commits (a priori) to a strategy. Disadvantage: Predictability by fellow players.
R.-P. Mundani, ICS, HS 2024
**Spielen in gemischten Strategien:** Finding the saddle point: Multiply the 2PNS game by probabilities $p$ and $q$. Solving the corresponding equation (often by linear programming).
R.-P. Mundani, ICS, HS 2024
| | S21 | S22 |
| :---- | :---- | :---- |
| **S11** | 3 | -1 |
| **S12** | 1 | 5 |
$p = 0.5$ and $q = 0.25$ (e.g., with gnuplot (http://www.gnuplot.info) via $> f(x,y) = -8*x*y + 2*x + ...$)
R.-P. Mundani, ICS, HS 2024
**Checkpoints:** What terms should be clear…? Games in pure strategies; Representation in normal form/bimatrix form; Dominant strategy; Nash equilibrium; Two-person zero-sum games; Higher penalties (fines) equally reduce the probability with which the tax inspector checks and with which tax evasion becomes attractive for Zanoma 
R.-P. Mundani, ICS, HS 2024
**Gruppenentscheidungen:** Decision: Preference $P_A$. Sought: Collective selection function $K$ for the preference of the totality $K: P_A = P_A × P_A ×× P_A → P_A$. Essential (non-trivial) conditions: The selection function $K$ must be total → for each possible combination of (personal) preferences from $P_A$ there must be an overall preference (i.e., a result). The result itself must again be a relation in $P_A$.
R.-P. Mundani, ICS, HS 2024
**Gruppenentscheidungen:** Decision procedure (continuation): Rank addition. Each individual preference $ρ_i$ defines a rank mapping. Idea: Determine the collective preference from the rank numbers of the respective individuals. Simplest method: Addition of rank numbers. For two elements $x, y$, $K_A(ρ_1, …, ρ_n)$ is relation $ρ$ with: The sum $Σr_i$ is not a rank mapping (see following example), but can easily be “corrected” so that $ρ ∈ P_A$ applies. The procedure has no obvious disadvantages.
R.-P. Mundani, ICS, HS 2024
**Gruppenentscheidungen:** Collective selection functions $P_A → P_A$ are also fulfilled by undesirable procedures. Two conditions that every “fair” procedure should fulfill: Pareto condition: The totality (of all individuals) can enforce any desired ranking for any choice options by unanimity tests. Independence of irrelevant alternatives: Ranking between two choice options is determined by preference $ρ_d$; the result is independent of the other $ρ_i$ with $i ≠ d$. The result is also a mapping $P_A → P_A$, but neither “fair” nor “democratic”. Better procedures are needed that “reasonably” collectively combine individual preferences.
---
## Game Theory Basics
Two-Person Zero-Sum Games
Bismarck Sea Battle
Mixed Strategies Game
Group Decisions
Preference Relations
Decision Procedures
Arrow's Impossibility Theorem
# Spieltheorie: Von Zwei-Personen-Nullsummenspielen zu Gruppenentscheidungen
Zwei-Personen-Nullsummenspiele (2PNS-Spiele) werden in Matrixform dargestellt, wobei Spieler 1 die Minimiererin (Zeilenspielerin) und Spieler 2 die Maximiererin (Spaltenspielerin) ist. Daher werden 2PNS-Spiele auch als MinMax-Spiele bezeichnet. Aufgrund ihrer speziellen Struktur nehmen Nash-Gleichgewichte die Form von Sattelpunkten an dem Schnittpunkt von Minimum und Maximum. Der Min-Max-Theorem besagt, dass ein Sattelpunkt genau dann existiert, wenn $U^- = a_{i*j*} = U^+$. Ein Beispiel hierfür ist die Schlacht in der Bismarcksee (2.4. März 1943), wo japanische Truppen von Rabaul nach Lae verlegt werden sollten, mit zwei möglichen Routen (regnerische Nordroute und sonnige Südroute), während die U.S. Air Force mit begrenzten Ressourcen entscheiden musste, welche Route zu bombardieren ist.
Möglichkeiten und Aktionen seien definiert als $A_1 = \{X, Y\}$ und $A_2 = \{X, Y\}$. Die Aktionsprofile sind $A = \{(X, X), (X, Y), (Y, X), (Y, Y)\}$. Eine Auszahlungsfunktion $u_{1,2}: A \to (1, 0, 0, 1)$ ist gegeben. Die Frage ist, wie sich das Spiel verändert, wenn die Auszahlungsfunktionen für Spieler 1: $u_1: A \to (1, 0, 0, 0)$ und Spieler 2: $u_2: A \to (0, 0, 0, 1)$ gelten. Im Kontext von Spielen in gemischten Strategien, beispielsweise bei der Steuerhinterziehung mit einer Schwelle von $s > 200$ Millionen CHF, kann es vorkommen, dass keine dominante Strategie oder kein Nash-Gleichgewicht in reinen Strategien existiert. In einem Beispiel ergibt sich $U^- = 2 = U^+$ aus $q$ in $S_{11}$ oder $S_{12}$ und $p$ in $S_{22}$.
Gruppenentscheidungen beschäftigen sich mit Relationen, die Beziehungen zwischen Elementen beschreiben (z.B. Rangfolgen, Präferenzen). Eine Relation $R$ auf Paaren $(x, y)$ von Elementen aus $A$ wird formal als $(x, y) \in R$ oder $xRy$ geschrieben. Präferenzen können durch Rangabbildungen definiert werden: $x \rho y \iff r(x) < r(y)$. Die Relation $\rho$ ist transitiv und asymmetrisch. Die Menge aller darstellbaren Relationen auf $A$ ist $P_A := \{\rho \subset A \times A: \rho \text{ erfüllt } x \rho y \iff r(x) < r(y) \text{ für eine Rangabbildung } r\}$. Eine Erweiterung der Relation durch alle Paare mit gleichem Rang ist $x \rho^* y \iff r(x) \le r(y)$. Die Relation $\rho^*$ ist transitiv und reflexiv, und es gilt $\rho \subset \rho^*$. $P_A^* := \{\rho^* \subset A \times A: \rho^* \text{ erfüllt } x \rho^* y \iff r(x) \le r(y) \text{ für eine Rangabbildung } r\}$. Beispiel: $A = \{x, y, z\}$, $r(x) = 1$, $r(y) = r(z) = 2$. Es gilt $x \rho y \iff \neg(y \rho^* x)$.
Entscheidungsverfahren für Gruppenentscheidungen umfassen Extrembeispiele wie den externen oder internen Diktator. Rangaddition ist ein weiteres Verfahren, aber es kann zu ungültigen Ergebnissen führen, wie z.B. $x \rho y$, $y \rho z$, und $z \rho x$, was aufgrund der Transitivität zu $x \rho x$ führt, was ungültig ist. Einstimmigkeit erfordert, dass alle Individuen dieselbe Präferenz teilen. Das Condorcet-Verfahren und Einstimmigkeit liefern für $|A| > 2 möglicherweise ungültige Ergebnisse. Nur ein interner Diktator erfüllt alle Bedingungen. Ein Verfahren sollte die Unabhängigkeit irrelevanter Alternativen erfüllen: die Rangfolge zwischen zwei Wahlmöglichkeiten sollte nicht durch Präferenzänderungen der Individuen bezüglich einer dritten Wahlmöglichkeit beeinflusst werden. Der Satz von Arrow zeigt, dass mit diesen Forderungen kein annähernd demokratisches Verfahren möglich ist.
---
## Game Theory Introduction
# Introduction to Computational Science (CDS-1012) HS 2024 Prof. Dr. rer. nat. habil. Ralf-Peter Mundani DAViS
R.-P. Mundani, ICS, HS 2024
**Introduction to Game Theory**
* Overview
* Modeling and Definitions
* Games in Pure Strategies
* Nash Equilibrium and Dominant Strategies
* Two-Person Zero-Sum Games
* Conservative Strategies
* Games in Mixed Strategies
* Calculation of Saddle Points
* Majority Decisions / Group Decisions (→ Part 2)
**Motivation from Stochastics: The Goat Problem (a.k.a. Monty-Hall Dilemma)**
* Game show: 3 doors two goats and one car
* Player chooses a door, the showmaster opens another door (goat)  Strategy: Change choice…?
* The other two cases (player chooses door B or C) are symmetrical
* In three cases (3/9) loss, in six cases (6/9) win  Change choice 
**Fundamentals**
* Definition: Game theory
* Subfield of mathematics ("Theory of strategic thinking")
* Modeling of decision situations
**Games in Pure Strategies**
* Prisoner's Dilemma (the best-known non-cooperative game in pure strategies)
* Background: Two prisoners are accused of having committed a crime together. Both prisoners are interrogated separately and cannot communicate. Due to a lack of concrete evidence, only part of the crime can be proven against both.
* Possible actions: Deny (L): low penalty (2 years); Confess (G): high penalty (5 years) or maximum penalty (8 years → witness protection program)
* Maximizing the payoff: Function $u_i$ models the gain in freedom (i.e., maximum penalty actual penalty)
**Prisoner's Dilemma (continuation)**
* Representation in normal form (also called bimatrix form for two players)
* Question: How do both players find the best strategy for themselves…?
$
\begin{array}{c|cc}
& G & L \\
\hline
G & (6, 6) & (8, 0) \\
L & (0, 8) & (3, 3) \\
\end{array}
$
$A_2 A_1 (u_1, u_2)$
**A Little Bit of Math **
* Nash Equilibrium
* An action profile is a Nash equilibrium if no player can improve their payoff by unilaterally changing their action.
* If strategy $a_i$ is better than strategy $a_i$ in all cases, then strong dominance is spoken of, i.e., strategy $a_i$ is strongly dominant over strategy $a_i$.
* Profiles of dominant strategies lead to Nash equilibria (converse not valid).
* Again the question: What does this mean for the prisoner's dilemma…?
**Strong Dominant Strategy**
* The strongly dominant strategy for both players is G.
**Exercise: Tax Evasion**
* Zanoma, a company, has not paid taxes on 200M CHF.
* If Zanoma is proven to have evaded taxes by a private tax auditor, the company must pay s million CHF (tax plus fines).
* The tax auditor receives 5% of the repayment as a bonus in case of success.
* The tax auditor has strategies audit (P; costs: 10M CHF) and no audit (KP; costs: 0).
* Zanoma has strategies tax evasion (S) and no tax evasion (KS).
* Questions: a) What does the depicted situation look like as a game in bimatrix form…? b) Are there dominant strategies and Nash equilibria for $s < 200$M CHF?
**Games in Pure Strategies**
* Sequential games
* There is a specific order in which player(s) are allowed to decide.
* In each step, players who are allowed to decide have complete or incomplete knowledge of the current status (i.e., previous decisions).
* The usual form of representation is extensive or as a tree.
**Conservative Strategies**
* Players choose strategies to minimize losses in the worst-case scenario.
* Minimizer P1: $U^- = \text{minimax}_{j} a_{ij}$
* For each strategy $i$: maximize over all columns $j$ (⇒ largest possible loss)
* Choose the minimum of all column maxima → conservative strategy $i^*$ (upper bound $U^-$)
* Maximizer P2: $U^+ = \text{max}_j \text{min}_i a_{ij}$
* For each strategy $j$: minimize over all rows $i$ (⇒ smallest possible gain)
* Choose the maximum of all row minima → conservative strategy $j^*$ (lower bound $U^+$)
* Mixed strategy games always have a saddle point.
**Games in Mixed Strategies**
* Introduction of probabilities
* Player P1: plays strategy $S_{11}$ with probability $p$ and strategy $S_{12}$ with $1 - p$.
* Player P2: plays strategy $S_{21}$ with probability $q$ and strategy $S_{22}$ with $1 - q$.
* For the case $n > 2$ strategies: probabilities $p_1, p_2, \dots, p_n$ for each strategy.
* Determining the saddle point
* Multiplying the 2PNS game
$
\begin{array}{cc}
p & 1-p \\
q & 1-q
\end{array}
$
**Tax Evasion (continuation)**
* From Zanoma's perspective: $(200 - s) \cdot q + 200 \cdot (1 - q) = 0 \cdot q + 0 \cdot (1 - q) \iff q = 200/s$
* From the tax auditor's perspective: $(0.05 \cdot s - 10) \cdot p - 10 \cdot (1 - p) = 0 \cdot p + 0 \cdot (1 - p) \iff p = 200/s$
* i.e., Nash equilibrium in mixed strategies, thus for $p = q$, i.e., for $(200/s, 200/s)$
* In other words: higher repayments (fines) reduce the probability of an audit.
**Group Decisions**
* Arrow's theorem
* Let $A$ with $|A| > 2$ be a set of choices.
* $K: P^A \to P^A$ is a collective choice function that satisfies the Pareto condition and independence of irrelevant alternatives.
* Then there is always a dictator, there is a $d \in I$: for all $(\rho_1, \dots, \rho_n) \in P^A$: for all $(x, y) \in A \times A$: $x \rho_d y \implies x \rho y$.
* BUT: The dictator is "generous" towards other groups.
---
## Game Theory Basics
Kooperative Spiele zeichnen sich dadurch aus, dass alle Spielerinnen und Spieler nach gemeinsamen Aktionen suchen, die optimal für die Gruppe sind. Spielerinnen und Spieler können vor dem Spiel Absprachen treffen. Im Gegensatz dazu stehen nicht-kooperative Spiele, bei denen jede Spielerin und jeder Spieler seine Auszahlung maximiert, indem er seine beste Strategie wählt basierend auf seinem Wissen über die Strategien der anderen. Vereinbarungen zwischen den Spielerinnen und Spielern gibt es in nicht-kooperativen Spielen nicht.
---
## Game Theory Strategies
Mixed Strategies
Group Decisions Ranking
Group Decision Preferences
Group Decision Methods
# Gruppenentscheidungen: Präferenzen und Entscheidungsverfahren
In Spielen können reine Strategien (z.B. Schere (100%), Stein (0%), Papier (0%)) zu vorhersehbaren Ergebnissen führen. Gemischte Strategien, bei denen ein Spieler zufällig zwischen Strategien entscheidet (z.B. Schere (25%), Stein (50%), Papier (25%)), werden durch eine Wahrscheinlichkeitsfunktion über reinen Strategien charakterisiert. Allerdings führen reine Strategien oft nicht zu Nash-Gleichgewichten. Das Min-Max-Theorem besagt, dass Zwei-Personen-Nullsummen-Spiele (2PNS-Spiele) in gemischten Strategien immer einen Sattelpunkt haben, im Gegensatz zu Spielen in reinen Strategien, die keinen Sattelpunkt besitzen (Beispiel: siehe Spielmatrix).
$$
\begin{array}{c|cc}
& S_{21} & S_{22} \\
\hline
S_{11} & 3 & -1 \\
S_{12} & -1 & 5
\end{array}
$$
$\min_i \max_j \to i^* = S_{11} \text{ und } U^+ = 3$; $\max_j \min_i \to j^* = S_{22} \text{ und } U^- = 1$
Rangabbildungen bieten eine Möglichkeit, Präferenzen zu visualisieren. Eine endliche Menge $A$ von Möglichkeiten (z.B. Kandidaten, Pläne) wird durch die Vergabe von Rangnummern $r(x)$ mit $x \in A$ bewertet. $r(x) < r(y)$ bedeutet, dass $x$ gegenüber $y$ bevorzugt wird. Zwei oder mehr Möglichkeiten können dieselbe Rangnummer erhalten. Eine Rangabbildung $r: A \to P$ ist eine surjektive Abbildung der Menge der Möglichkeiten $A$ auf eine Menge von Präferenzen $P = \{1, \dots, k\} \subset \mathbb{N}$. Beispiel: $A = \{x, y, z\}$, $r(x) = 1$, $r(y) = r(z) = 2$. Rangabbildungen eignen sich besonders für Visualisierungen (z.B. Fussballtabellen).
Präferenzen können durch Relationen beschrieben werden. Eine Relation $R$ auf einer Menge $A$ ist eine Teilmenge von $A \times A$. $xRy$ bedeutet, dass $x$ in Relation zu $y$ steht. Eigenschaften von Relationen: transitiv ($xRy \land yRz \implies xRz$), reflexiv ($xRx$ für alle $x \in A$), asymmetrisch ($xRy \land yRx$ gilt niemals gleichzeitig). Transitive und reflexive Relationen werden auch Quasiordnungen genannt. Eine strenge Präferenzrelation $\rho$ ist irreflexiv ($x \rho x$ gilt niemals) und asymmetrisch ($x \rho y \iff \neg(y \rho^* x)$).
Entscheidungsverfahren benötigen die Menge der Wähler $I = \{1, \dots, n\}$ und die persönlichen Präferenzen $P_A$ jedes Wählers. Ziel ist die kollektive Auswahlfunktion. Das Condorcet-Verfahren zählt im direkten Vergleich zweier Elemente $x, y \in A$, welche Präferenz häufiger auftritt. Für zwei Elemente $x, y$ gilt: $K(ρ_1, \dots, ρ_n)$ ist eine Relation $ρ$. Das Verfahren ist für beliebige $ρ$ durchführbar, aber die Relation $ρ$ ist im Fall von mehr als zwei Möglichkeiten nicht immer transitiv, d.h. $ρ$ ist keine zulässige Präferenzrelation aus $P_A$.
Bedingungen an Auswahlverfahren: Die Pareto-Bedingung (Einstimmigkeit) besagt, dass die kollektive Auswahlfunktion $K: P_A \to P_A$ die Pareto-Bedingung erfüllt, wenn für alle $ρ_i \in P_A$ gilt: Wenn alle Individuen $x$ vor $y$ bevorzugen, dann muss die kollektive Entscheidung auch $x$ vor $y$ bevorzugen. Die Unabhängigkeit von irrelevanten Alternativen fordert, dass die Platzierung einer dritten Möglichkeit den Vergleich zweier anderer Möglichkeiten nicht beeinflussen darf. Präferenzänderungen bei Individuen können zu unterschiedlichen kollektiven Entscheidungen führen. Beispiel: Zwei Individuen mit unterschiedlichen Präferenzen ($i=1$: $x < y < z$; $i=2$: $y < z < x$) führen zu unterschiedlichen Ergebnissen.
---
## Game Theory Basics
# Einführung in die Spieltheorie
**Grundlagen (Fortsetzung):** Entscheidungen können getroffen werden unter:
* **Gewissheit:** Alle Aktionen/Konsequenzen sind bekannt.
* **Risiko:** (Bestimmte) Wahrscheinlichkeiten von Aktionen/Konsequenzen sind bekannt.
* **Unsicherheit:** Keine Aktionen/Konsequenzen sind bekannt.
**Modellierung:**
* Menge von SpielerInnen $N = \{1, 2, \dots, n\}$
* Menge der Aktionen (auch als Strategie bezeichnet) $A_i$ von SpielerIn $i$ für alle $i \in N$
* Menge der Aktionsprofile (auch Strategieprofile) $A = \{(a_i)_{i \in N}, a_i \in A_i \text{ für alle } i \in N\}$
* Auszahlungsfunktion $u_i: A \to \mathbb{R}$ für SpielerIn $i$
**Beispiel:** Entscheidung zwischen zwei Möglichkeiten. Aktionen: $A_1 = \{X, Y\}$ und ...
**Nash-Gleichgewicht:** Ein Aktionsprofil bildet ein Nash-Gleichgewicht, wenn keine SpielerIn eine höhere Auszahlung erhalten kann, indem sie von ihrer Entscheidung (einseitig) abweicht, d.h. während alle anderen SpielerInnen auf ihren Entscheidungen beharren. Formal: Ein Aktionsprofil bildet genau dann ein Nash-Gleichgewicht, wenn keine der SpielerInnen durch Abweichung davon eine höhere Auszahlung erhält.
**Modellierung von Entscheidungssituationen (oftmals im sozialen Konflikt):** Idee: Erfolg hängt nicht nur von eigener, sondern auch von Entscheidungen anderer ab. Anwendungsgebiete: vor allem Wirtschaftswissenschaften und Ökonomie. Bekannte Vertreter: John von Neumann, John Forbes Nash. Unterscheidung zwischen:
* kooperativen / nicht-kooperativen Spielen
* simultanen / sequentiellen Spielen
**Spielen in reinen Strategien:** Übung: Steuerhinterziehung. Unternehmen Zanoma hat durch kreative Buchführung 200M CHF nicht versteuert.
**Spielen in reinen Strategien (Fortsetzung):** Falls $s < 200$ folgt damit $200 - s > 0 \to S$ ist strikt dominante Strategie. Falls $s < 200$ folgt damit $0.05 * s - 10 < 0 \to KP$ ist strikt dominante Strategie.
\begin{array}{c|cc}
& KP & S \\
\hline
K & (200, 0) & (200 - s, 0.05 * s - 10) \\
S & (0, 0) & (0, -10) \\
\end{array}
**Zwei-Personen-Nullsummenspiele:** Einführung. Idee: Gewinn einer SpielerIn ist Verlust der anderen (d.h. Summe ist immer 0). Alternative Berechnung (als reine Strategien) aus jeweiliger Sicht von SpielerIn P1 und P2.
$f(x, y) = -8xy + 2x + 4y + 1$
**Spielen in gemischten Strategien:** Sattelpunkt bei (0.5, 0.25); durch Einsetzen von $p$ in $S_{21}$ oder $S_{22}$ sowie $q$ in $S_{11}$ oder $S_{12}$ ergibt sich ...
\begin{array}{c|cc}
& S_{11} & S_{12} \\
\hline
S_{21} & 1-q & q \\
S_{22} & 3-1 & 1-p \\
\end{array}
$P_1(\min)$ $P_2(\max)$
**Zwei-Personen-Nullsummenspiele:** Darstellung in Matrixform. Konservative Strategien (MinimiererIn / MaximiererIn). Spiele in gemischten Strategien. Gleichgewichtspunkte / Sattelpunkt.
**Gruppenentscheidungen:** Problemstellung. Situation: verschiedene Möglichkeiten (Entscheidungsvarianten: Wahlen, Wettbewerbe, ...). Ziel: gemeinsame Bestimmung einer Rangfolge der Möglichkeiten. Beispiel: WählerInnen $\to$ KandidatInnen (Wahl), Publikum $\to$ TeilnehmerInnen (Wettbewerb). ABER: nicht alle werden mit der Rangfolge einverstanden sein (Stichwort: Unzufriedenheit). Axiomatischer Ansatz. Aufstellung von Eigenschaften und Prüfung, welche Entscheidungsverfahren sie erfüllen. Modellierung individueller Präferenzen und der Entscheidungsverfahren selbst.
**Gruppenentscheidungen (Fortsetzung):** Bedingungen an Auswahlverfahren. Unabhängigkeit von irrelevanten Alternativen. Beispiel: $I = \{1, 2\}$, $A = \{x, y, z\}$ mit Rangaddition KA als Auswahlverfahren. Als Gruppenentscheidung bzgl. $x$ und $y$ gilt $y \rho' x$, aber nicht $x \rho y$. Ergebnis ändert sich, obwohl kein Individuum die Präferenz im direkten Vergleich zwischen $x$ und $y$ ändert ($i = 1$ sieht $x < y$ und $i = 2$ sieht $y < x$).

View File

@ -0,0 +1,213 @@
# Clustered and Rewritten Text Document
This document groups text chunks based on semantic similarity. Topics and rewritten text (formatted in Markdown with LaTeX for equations) are generated by the Gemini API.
## Game Theory Basics
Nash Equilibrium
Dominant Strategies
Prisoner's Dilemma
Zero-Sum Games
Conservative Strategies
Mixed Strategies
Checkpoints Summary
Group Decisions
Collective Choice
# Spieltheorie: Zusammenfassung
Nicht-kooperative Spiele sind in der Literatur und Anwendung weit verbreitet. Spieler*innen können keine Absprachen vor dem Spiel treffen und haben keinerlei Vereinbarungen über gemeinsame Aktionen, die optimal für die Gruppe sind. Eine Unterscheidung ist die zwischen simultanen Spielen, bei denen alle Spieler*innen ihre Wahl ein für alle Mal treffen (nur ein Zug), und sequentiellen Spielen.
Spielen in reinen Strategien: Eine dominante Strategie ist mindestens so gut wie eine andere Strategie für alle möglichen Aktionen der anderen Spieler*innen. Gilt die Ungleichung im strengen Sinn ($>$), spricht man von starker Dominanz. Ein Nash-Gleichgewicht liegt vor, wenn kein Spieler durch eine einseitige Abweichung eine höhere Auszahlung erzielen kann, d.h. wenn für alle $a_i \in A_i$ und $i \in N$ gilt. Das Gefangenendilemma illustriert dies: Die dominante Strategie beider Spieler*innen ist G. ABER: Das Gleichgewicht (G, G) ist ineffizient, da (L, L) eine bessere Auszahlung ergeben würde. Ein weiteres Beispiel ist das Falke-und-Taube-Spiel.
$$
\begin{array}{c|cc}
& G & L \\
\hline
G & (6, 6) & (8, 0) \\
L & (0, 8) & (3, 3) \\
\end{array}
$$
Zwei-Personen-Nullsummenspiele: Spieler*innen versuchen, den Gewinn zu maximieren (d.h. den Gewinn der anderen zu minimieren); der Verlust des einen ist der Gewinn des anderen (d.h. die Summe ist immer Null). Die Darstellung erfolgt üblicherweise in Normalform (oder Matrixform). Konservative Strategien wählen den besten Wert aus allen ungünstigsten Fällen. Die beste gegnerische Strategie führt zum eigenen schlechtesten Gewinn. Der Sattelpunkt (Schnittpunkt von Minimum und Maximum) zeigt die optimale Strategie. Keine Spieler*in kann sich durch einen einseitigen Strategiewechsel verbessern.
$$
\begin{array}{c|cc}
& S_{21} & S_{22} \\
\hline
S_{11} & (-1, 1) & (-5, 5) \\
S_{12} & (1, -1) & (3, -3) \\
\end{array}
$$
Beispiel: Schlacht in der Bismarcksee. Falls die Amerikaner die richtige Route überprüfen, kann die Bombardierung sofort begonnen werden (andernfalls verbleiben zwei Tage für die andere Route). Auf der Nordroute muss die Bombardierung wegen schlechter Sicht einen Tag ausbleiben. Dies ergibt folgendes 2PNS-Spiel (Gewinn ≡ mögliche Tage für Bombardierung):
$$
\begin{array}{c|cc}
& N & S \\
\hline
N & (2, -2) & (1, -1) \\
S & (0, 0) & (2, -2) \\
\end{array}
$$
Spielen in gemischten Strategien: Reine Strategien sind vorhersehbar. Ein Sattelpunkt im 2PNS-Spiel wird durch Multiplikation mit Wahrscheinlichkeiten $p$ und $q$ und Lösung der zugehörigen Gleichung (oftmals durch lineare Programmierung) gefunden.
$$
\begin{array}{c|cc}
& S_{21} & S_{22} \\
\hline
S_{11} & 3 & -1 \\
S_{12} & 1 & 5 \\
\end{array}
$$
Checkpoints: Spiele in reinen Strategien, Darstellung in Normalform/Bimatrixform, dominante Strategie, Nash-Gleichgewicht, Zwei-Personen-Nullsummenspiele.
Gruppenentscheidungen: Gesucht ist eine kollektive Auswahlfunktion K für die Präferenz der Gesamtheit: $K: PA = PA \times PA \times \dots \times PA \to PA$. Eine Auswahlfunktion K muss total sein. Das Ergebnis muss eine Relation in PA sein. Rangaddition: Jede Individualpräferenz $\rho_i$ legt eine Rangabbildung fest. Die kollektive Präferenz wird aus den Rangnummern der jeweiligen Individuen bestimmt. Die Summe der Rangnummern ist keine Rangabbildung, kann aber korrigiert werden. Das Verfahren hat keine offensichtlichen Nachteile. Kollektive Auswahlfunktionen $PA \to PA$ werden auch von unerwünschten Verfahren erfüllt. Zwei Bedingungen für „gerechte“ Verfahren sind die Pareto-Bedingung und die Unabhängigkeit von irrelevanten Alternativen.
---
## Game Theory Basics
Two-Person Zero-Sum Games
Bismarck Sea Battle
Mixed Strategies Game
Group Decisions
Preference Relations
Decision Procedures
Arrow's Impossibility Theorem
# Spieltheorie und Gruppenentscheidungen
Zwei-Personen-Nullsummenspiele (2PNS-Spiele) werden auch als MinMax-Spiele bezeichnet. In Matrixform wird Spieler 1 zur Minimiererin (auch Zeilenspielerin genannt) und Spieler 2 zur Maximiererin (auch Spaltenspielerin genannt). Aufgrund der speziellen Struktur von 2PNS-Spielen nehmen Nash-Gleichgewichte die Form von Sattelpunkten an (Schnittpunkt von Minimum und Maximum). Der Sattelpunkt existiert genau dann, wenn $U^- = a_{i*j*} = U^+$. Ein Beispiel hierfür ist die Schlacht in der Bismarcksee (2.-4. März 1943). Japanische Truppen sollten von Rabaul nach Lae verlegt werden, wobei zwei mögliche Routen zur Verfügung standen: eine regnerische Nordroute und eine sonnige Südroute. Die US Air Force musste entscheiden, welche Route sie bombardiert, da nicht genügend Flugzeuge für beide Routen verfügbar waren.
Möglichkeiten und Aktionen seien $A_1 = \{X, Y\}$ und $A_2 = \{X, Y\}$. Die Aktionsprofile sind $A = \{(X, X), (X, Y), (Y, X), (Y, Y)\}$. Die Auszahlungsfunktion ist $u_{1,2}: A \to (1, 0, 0, 1)$. Wie verändert sich das Spiel, wenn folgende Auszahlungsfunktionen gelten? Spieler 1: $u_1: A \to (1, 0, 0, 0)$; Spieler 2: $u_2: A \to (0, 0, 0, 1)$. Spiele in gemischten Strategien werden betrachtet, wenn keine dominante Strategie oder kein Nash-Gleichgewicht in reinen Strategien existiert. Beispielsweise bei der Steuerhinterziehung mit $s > 200$ Millionen CHF.
Gruppenentscheidungen basieren auf der Beschreibung von Beziehungen (z.B. Rangfolgen, Präferenzen) zwischen Elementen. Dies wird als Relation $R$ auf Paaren $(x, y)$ von Elementen aus $A$ dargestellt, formal geschrieben als $(x, y) \in R$ oder abkürzend als $xRy$. Beispielsweise ist $R$ mit '$<$' (kleiner) und $xRy$ gleichbedeutend mit $x < y$. Präferenzrelationen werden durch Rangabbildungen definiert: $x \rho y \iff r(x) < r(y)$. Die Relation $\rho$ ist transitiv und asymmetrisch. Die Menge aller möglichen Relationen auf $A$ ist definiert als $P_A := \{\rho \subset A \times A: \rho \text{ erfüllt } x \rho y \iff r(x) < r(y) \text{ für eine Rangabbildung } r\}$. Eine Erweiterung der Relation durch alle Paare mit gleichem Rang ist $x \rho^* y \iff r(x) \le r(y)$. Die Relation $\rho^*$ ist transitiv und reflexiv. Es gilt $\rho \subset \rho^*$. Analog lässt sich $P_A^* := \{\rho^* \subset A \times A: \rho^* \text{ erfüllt } x \rho^* y \iff r(x) \le r(y) \text{ für eine Rangabbildung } r\}$ definieren. Beispiel: $A = \{x, y, z\}$, $r(x) = 1$, $r(y) = r(z) = 2$. Zwischen beiden Relationen gilt: $x \rho y \iff \neg(y \rho^* x)$.
Entscheidungsverfahren in Gruppen werden betrachtet. Extrembeispiel 1: externer Diktator. Das Ergebnis ist unabhängig von den individuellen Präferenzen. Extrembeispiel 2: interner Diktator. Die Präferenz eines Individuums bestimmt das Ergebnis. Rangaddition ist ein weiteres Verfahren. Beispiel: $I = \{1, 2\}$, $A = \{x, y, z\}$. Einstimmigkeit erfordert, dass alle Individuen dieselbe Präferenz teilen. Jedoch kann die Rangfolge zwischen zwei Wahlmöglichkeiten durch Präferenzänderungen der Individuen im Hinblick auf eine dritte Wahlmöglichkeit gekippt werden. Der Satz von Arrow besagt, dass mit diesen Forderungen kein annähernd demokratisches Verfahren mehr möglich ist. Bedingungen an Auswahlverfahren: die Rangfolge zwischen zwei Wahlmöglichkeiten soll keinen Einfluss auf das Ergebnis haben. Rangaddition ist somit als „gerechtes“ Verfahren ausgeschlossen. Condorcet-Verfahren und Einstimmigkeit liefern für $|A| > 2$ evtl. ungültige Ergebnisse. Nur ein interner Diktator erfüllt alle Bedingungen.
---
## Game Theory Introduction
# Einführung in die Spieltheorie (CDS-1012) HS 2024 Prof. Dr. rer. nat. habil. Ralf-Peter Mundani DAViS
R.-P. Mundani, ICS, HS 2024 Einleitung: Überblick, Einführung in die Spieltheorie, Modellierung und Definitionen, Spiele in reinen Strategien, Nash-Gleichgewicht und dominante Strategien, Zwei-Personen-Nullsummenspiele, konservative Strategien, Spiele in gemischten Strategien, Berechnung von Sattelpunkten, Mehrheitsbeschlüsse / Gruppenentscheidungen (→ Teil 2).
R.-P. Mundani, ICS, HS 2024 Motivation aus der Stochastik: Ziegenproblem (a.k.a. Monty-Hall-Dilemma). Spielshow: 3 Türen zwei Nieten (Ziege) und ein Gewinn (Auto). SpielerIn wählt Tür, ShowmasterIn öffnet andere Tür (Ziege)  Strategie: Wahl ändern…? Die anderen beiden Fälle (SpielerIn wählt Tür B oder C) sind symmetrisch. In drei Fällen (3/9) Verlust, in sechs Fällen (6/9) Gewinn  Wahl ändern  Quellen: depositphotos.com, jamara.com A B C A B C A B C ACB
R.-P. Mundani, ICS, HS 2024 Einführung in die Spieltheorie: Grundlagen, Definition: Spieltheorie, Teilgebiet der Mathematik („Theorie des strategischen Denkens“), Modellierung von Entscheidungssituationen. Spieler treffen ihre Wahl ein für alle Mal (nur ein Durchlauf) und gleichzeitig. Es gibt eine übliche Darstellung in Normalform (z.B. Gefangenendilemma). Sequentielle Spiele: Es gibt eine spezifische Ordnung, welche(r) SpielerIn wann entscheiden darf. In jedem Schritt haben SpielerInnen, die entscheiden dürfen, vollständiges oder unvollständiges Wissen über den aktuellen Status (d.h. frühere Entscheidungen). Die übliche Darstellungsform ist extensiv oder als Baum.
R.-P. Mundani, ICS, HS 2024 Spiele in reinen Strategien: Gefangenendilemma (das wohl bekannteste nicht-kooperative Spiel in reinen Strategien). Hintergrund: Zwei Gefangene werden beschuldigt, gemeinsam ein Verbrechen verübt zu haben. Beide Gefangenen werden getrennt vernommen und können nicht kommunizieren. Mangels konkreter Beweise kann beiden nur ein Teil der Tat nachgewiesen werden. Mögliche Aktionen: Leugnen (L): niedrige Strafe (2 Jahre). Gestehen (G): hohe Strafe (5 Jahre) oder Höchststrafe (8 Jahre Kronzeugenregel). Maximierung der Auszahlung. Funktion $u_i$ modelliert den Gewinn an Freiheit (also Höchststrafe tatsächlicher Strafe).
R.-P. Mundani, ICS, HS 2024 Spiele in reinen Strategien: Gefangenendilemma (Fortsetzung). Darstellung in Normalform (bei zwei SpielerInnen auch Bimatrixform genannt). Frage: Wie finden beide SpielerInnen die für sich beste Strategie…?
$$
\begin{array}{c|cc}
& G & L \\
\hline
G & (6, 6) & (8, 0) \\
L & (0, 8) & (3, 3) \\
\end{array}
$$
$A_2A_1(u_1,u_2)$
R.-P. Mundani, ICS, HS 2024 Spiele in reinen Strategien: Ein bisschen Mathematik . Nash-Gleichgewicht: Ein Aktionsprofil ist ein Nash-Gleichgewicht, wenn kein Spieler durch einseitige Änderung seiner Strategie seinen Nutzen verbessern kann. Wenn eine Strategie $a_i$ für alle Strategien $a_i$ eines Spielers einen höheren Nutzen liefert, dann wird von starker Dominanz gesprochen, d.h. Strategie $a_i$ ist stark dominant über Strategie $a_i$. Profile dominanter Strategien führen zu Nash-Gleichgewichten (Umkehrung nicht gültig). Nochmals Frage: Was bedeutet das für das Gefangenendilemma…?
R.-P. Mundani, ICS, HS 2024 Spiele in reinen Strategien: Ein bisschen Mathematik (Fortsetzung). Stark dominante Strategie beider SpielerInnen ist G.
R.-P. Mundani, ICS, HS 2024 Spiele in reinen Strategien: Übung: Steuerhinterziehung (Forts.). Kreative Buchführung 200M CHF nicht versteuert. Wird Zanoma durch privaten Steuerprüfer die Steuerhinterziehung nachgewiesen, so muss das Unternehmen eine Nachzahlung von $s$ Millionen CHF (Steuer plus Busse) leisten. Steuerprüfer bekommt im Erfolgsfall 5% der Nachzahlung als Prämie. Steuerprüfer hat Strategien Prüfung (P; Kosten: 10M CHF) und keine Prüfung (KP; Kosten: 0). Zanoma hat Strategien Steuerhinterziehung (S) und keine Steuerhinterziehung (KS). Fragen: a) Wie sieht die dargestellte Situation als Spiel in Bimatrixform aus…? b) Gibt es für $s<200$M CHF dominante Strategien und Nash-Gleichgewichte? Jede Ähnlichkeit mit real existierenden Unternehmen ist rein zufällig.
R.-P. Mundani, ICS, HS 2024 Spiele in reinen Strategien: Konservative Strategien. In ungünstigsten Fällen: MinimiererIn P1: $U^- = \min_i \max_j a_{ij}$. Für jede Strategie i: Maximiere über alle Spalten j ( größtmöglicher Verlust). Wähle Minimum aller Spaltenmaxima  konservative Strategie i* (Obergrenze $U^-$). MaximiererIn P2: $U^+ = \max_j \min_i a_{ij}$. Für jede Strategie j: Minimiere über alle Zeilen i ( kleinstmöglicher Gewinn). Wähle Maximum aller Zeilenminima  konservative Strategie j* (Untergrenze $U^+$). Minimieren des maximal möglichen Verlustes und Maximieren des minimal möglichen Gewinnes. Zwei-Personen-Nullsummenspiele haben immer einen Sattelpunkt.
R.-P. Mundani, ICS, HS 2024 Spiele in gemischten Strategien: Einführung von Wahrscheinlichkeiten. SpielerIn P1: Spielt mit Wahrscheinlichkeit $p$ Strategie $S_{11}$ und mit $1-p$ Strategie $S_{12}$. SpielerIn P2: Spielt mit Wahrscheinlichkeit $q$ Strategie $S_{21}$ und mit $1-q$ Strategie $S_{22}$. Für den Fall $n>2$ Strategien: Wahrscheinlichkeiten $p_1, p_2, \dots, p_n$ je Strategie mit $\sum_{i=1}^n p_i = 1$. Bestimmung des Sattelpunkts. Multiplizieren des 2PNS-Spiels mit $p$ und $q$.
R.-P. Mundani, ICS, HS 2024 Spiele in gemischten Strategien: Nochmal Aufgabe: Steuerhinterziehung (Fortsetzung). Aus Sicht von Zanoma: $(200-s) \cdot q + 200 \cdot (1-q) = 0 \cdot q + 0 \cdot (1-q) \iff q = 200/s$. Aus Sicht des Steuerprüfers: $(0.05 \cdot s - 10) \cdot p - 10 \cdot (1-p) = 0 \cdot p + 0 \cdot (1-p) \iff p = 200/s$. D.h. Nash-Gleichgewicht in gemischten Strategien somit für $p=q$, d.h. für $(200/s, 200/s)$. In anderen Worten: Höhere Nachzahlungen (Bussen) senken die Wahrscheinlichkeit, dass der Steuerprüfer eine Prüfung durchführt und die Wahrscheinlichkeit, dass Zanoma eine Steuerhinterziehung begeht.
R.-P. Mundani, ICS, HS 2024 Gruppenentscheidungen: Satz von Arrow. Mit $|A| > 2$ sei eine Menge von Auswahlmöglichkeiten. $K: P^A \to P^A$ sei kollektive Auswahlfunktion, die Pareto-Bedingung und Unabhängigkeit von irrelevanten Alternativen erfüllt. Dann existiert immer ein Diktator: Es gibt ein $d \in I$: Für alle $(\rho_1, \dots, \rho_n) \in P^A$: Für alle $(x, y) \in A \times A$: $x \rho_d y \implies x \rho y$. ABER: Diktator ist „großzügiger“ gegenüber anderen Gruppenmitgliedern.
---
## Game Theory Basics
Nicht-kooperative Spiele zeichnen sich dadurch aus, dass alle Spieler ihre Auszahlung maximieren, indem sie ihre beste Strategie wählen basierend auf ihrem Wissen oder ihren Erwartungen bezüglich der Strategien der anderen Spieler. Vereinbarungen zwischen den SpielerInnen bestehen nicht. Im Gegensatz dazu stehen kooperative Spiele, bei denen alle SpielerInnen nach gemeinsamen Aktionen suchen, die optimal für die Gruppe sind. Vor dem Spiel können Absprachen zwischen den SpielerInnen getroffen werden. Die Unterscheidung zwischen diesen beiden Spieltypen liegt also in der Möglichkeit und dem Vorhandensein von Absprachen und der Zielsetzung der SpielerInnen: individuelle Nutzenmaximierung versus kollektive Optimierung.
---
## Game Theory Strategies
Mixed Strategies Games
Group Decision Making
Ranking Preferences
Preference Relations
Collective Choice
Condorcet Voting
Decision Procedure Conditions
# Spieltheorie und Gruppenentscheidungen
Vorhersehbarkeit durch Mitspieler*innen ist ein wichtiger Aspekt. Ein Beispiel: Schere (100%), Stein (0%), Papier (0%). Gemischte Strategien, bei denen eine Spielerin zufällig zwischen Strategien entscheidet, werden hingegen durch eine Wahrscheinlichkeitsfunktion über reinen Strategien charakterisiert. Beispiel: Schere (25%), Stein (50%), Papier (25%). Reine Strategien führen jedoch häufig nicht zu Nash-Gleichgewichten. Nicht jedes Zwei-Personen-Nullsummenspiel (2PNS-Spiel) in reinen Strategien hat einen Sattelpunkt. Betrachten wir das Beispiel:
$$
\begin{array}{c|cc}
& S_{21} & S_{22} \\
\hline
S_{11} & 3 & -1 \\
S_{12} & -1 & 5 \\
\end{array}
$$
$\min_i \max_j \to i^* = S_{11}$ und $U^- = 3$, $\max_j \min_i \to j^* = S_{22}$ und $U^+ = 1$. Zwei-Personen-Nullsummenspiele in gemischten Strategien haben immer einen Sattelpunkt. Das Min-Max-Theorem wird erneut betrachtet.
Situationen mit unerwünschten Ergebnissen sind in der Regel nicht vermeidbar, dies gilt sowohl für die Wahl der Strategien und der Entscheidungsverfahren selbst.
Rangabbildungen werden verwendet, um Präferenzen zu repräsentieren. Die Situation: eine endliche Menge $A$ von Möglichkeiten (z.B. Kandidat*innen, Sänger*innen, Pläne, …). Präferenzen entstehen durch die Vergabe von Rangnummern $r(x)$ mit $x \in A$. Für zwei Möglichkeiten $x, y \in A$ bedeutet $r(x) < r(y)$, dass $x$ gegenüber $y$ bevorzugt wird. Zwei (oder mehr) Möglichkeiten können dieselbe Rangnummer erhalten. Eine Rangabbildung $r: A \to P$ ist eine surjektive Abbildung der Menge der Möglichkeiten $A$ auf eine Menge von Präferenzen $P = \{1, \dots, k\} \subset \mathbb{N}$. Beispiel:
$A = \{x, y, z\}$, $P = \{1, 2\}$; $r(x) = 1$, $r(y) = r(z) = 2$. Surjektivität: Jedes Element der Bildmenge hat (mindestens) ein zugehöriges Element in der Urbildmenge.
Eigenschaften von Relationen: transitiv: mit $xRy$ und $yRz$ folgt auch $xRz$ (z.B. aus $2 < 3$ und $3 < 4$ folgt $2 < 4$). Reflexiv: $xRx$ gilt für alle $x \in A$ (z.B. $2 \le 2$). Asymmetrisch: $xRy$ und $yRx$ gelten niemals gleichzeitig (z.B. $2 < 3$, aber nicht $3 < 2$). Transitive und reflexive Relationen werden auch Quasiordnungen genannt. Rangabbildungen eignen sich vor allem für Visualisierungen (z.B. Fußballtabellen).
$x \rho y \iff \neg(y \rho^* x)$.
Gruppenentscheidungen erfordern die Berücksichtigung der Präferenzen aller Wähler*innen. Die Menge der Wähler*innen $I = \{1, \dots, n\}$ besteht aus Individuen, die von 1 bis n durchnummeriert sind. Jede/r Wähler*in hat eine persönliche Präferenz $P_A$. Gesucht ist eine kollektive Auswahlfunktion.
Mehrheitsentscheidung (Condorcet-Verfahren): Im direkten Vergleich zweier Elemente $x, y \in A$ gibt es Individuen $\{i \in I: x \rho_i y\}$, die $x$ bevorzugen, Individuen $\{i \in I: y \rho_i x\}$, die $y$ bevorzugen, und Individuen, die bezüglich $x$ und $y$ indifferent sind. Das Condorcet-Verfahren zählt, wer mehr Vergleiche gewinnt. Für zwei Elemente $x, y$ gilt: $K(ρ_1, \dots, ρ_n)$ ist eine Relation $ρ$. Das Verfahren ist für beliebige $ρ$ durchführbar, aber die Relation $ρ$ ist im Fall von mehr als zwei Möglichkeiten nicht immer transitiv, d.h. $ρ$ ist keine zulässige Präferenzrelation aus $P_A$.
Beispiel: $I = \{1, 2, 3\}$, $A = \{x, y, z\}$. Es folgt $x \rho y$, $y \rho z$ und $z \rho x$. Aus der Transitivität würde man erwarten $x \rho z$, was aber nicht der Fall ist. Ein einziges Individuum, das $y$ mindestens so schätzt wie $x$ ($y \le x$), führt zu Problemen. In der Praxis liefert das Verfahren keine echten Präferenzen (außerdem: für $|A| > 2$, $ρ \notin P_A$). Beispiel: $i = 1$: $x < y < z$ und $i = 2$: $y < z < x \implies ρ$ enthält genau ein Paar $y \rho z \to ρ \notin P_A$.
Bedingungen an Auswahlverfahren: Pareto-Bedingung (Einstimmigkeit): Kollektive Auswahlfunktion $K: P_A \to P_A$ erfüllt die Pareto-Bedingung, wenn für alle $ρ_i \in P_A$ gilt: für alle $x, y \in A$, wenn $x \rho_i y$ für alle $i$, dann $x \rho y$. Somit scheidet der externe Diktator aus, alle anderen Verfahren erfüllen die Bedingung. Beispiel: Beide Individuen sehen $x, y$ vor $z$.
Unabhängigkeit von irrelevanten Alternativen: Die Platzierung einer dritten Möglichkeit $z$ soll keinen Einfluss auf die relative Platzierung von $x$ und $y$ haben. Eine Präferenzänderung bei einem Individuum kann die kollektive Präferenz beeinflussen, auch wenn die relative Ordnung zwischen $x$ und $y$ unverändert bleibt.
---
## Game Theory Basics
# Einführung in die Spieltheorie
Die Spieltheorie modelliert Entscheidungssituationen, oft im sozialen Konflikt. Der Erfolg hängt dabei nicht nur von den eigenen, sondern auch von den Entscheidungen anderer ab. Anwendungsgebiete finden sich vor allem in den Wirtschaftswissenschaften und der Ökonomie. Bekannte Vertreter sind John von Neumann und John Forbes Nash. Man unterscheidet zwischen kooperativen und nicht-kooperativen Spielen sowie simultanen und sequentiellen Spielen.
Entscheidungen können unter Gewissheit getroffen werden (alle Aktionen und Konsequenzen sind bekannt), unter Risiko (bestimmte Wahrscheinlichkeiten von Aktionen und Konsequenzen sind bekannt) oder unter Unsicherheit (keine Aktionen und Konsequenzen sind bekannt). Die Modellierung umfasst eine Menge von SpielerInnen $N = \{1, 2, \dots, n\}$, eine Menge der Aktionen (auch Strategien genannt) $A_i$ von SpielerIn $i$ für alle $i \in N$, und eine Menge der Aktionsprofile (auch Strategieprofile) $A = \{(a_i)_{i \in N}, a_i \in A_i \text{ für alle } i \in N\}$. Die Auszahlungsfunktion $u_i: A \to \mathbb{R}$ beschreibt die Auszahlung für SpielerIn $i$. Ein Beispiel: Die Entscheidung zwischen zwei Möglichkeiten mit Aktionen $A_1 = \{X, Y\}$ und ...
Ein Nash-Gleichgewicht liegt vor, wenn keine SpielerIn durch einseitige Abweichung von ihrer Entscheidung eine höhere Auszahlung erreichen kann, während alle anderen SpielerInnen bei ihren Entscheidungen bleiben. Formal: Ein Aktionsprofil bildet genau dann ein Nash-Gleichgewicht, wenn keine der SpielerInnen durch Abweichung davon eine höhere Auszahlung erhält.
Zwei-Personen-Nullsummenspiele zeichnen sich dadurch aus, dass der Gewinn einer SpielerIn dem Verlust der anderen entspricht (die Summe ist immer null). Sie werden oft in Matrixform dargestellt. Konservative Strategien führen zu MinimiererInnen oder MaximiererInnen. Spiele in gemischten Strategien ermöglichen die Betrachtung von Wahrscheinlichkeitsverteilungen über die reinen Strategien. Gleichgewichtspunkte oder Sattelpunkte sind dabei von Interesse. Ein Beispiel ist das Spiel "Chicken" (Hühner-Spiel), bei dem zwei SpielerInnen (z.B. mit Autos) auf einer Kollisionskurs aufeinander zufahren und durch (vorausschauendes) Verhalten entscheiden müssen. Die USA nutzten dieses Spiel für strategische Analysen während der Kuba-Krise. Das Spiel wird interessant, wenn die Kosten für den Kampf ($C$) die Kosten bzw. den Wert des Sieges ($V$) überschreiten, d.h. $C > V > 0$.
Eine Übung zur Steuerhinterziehung veranschaulicht dominante Strategien. Unternehmen Zanoma hat durch kreative Buchführung 200 Millionen CHF nicht versteuert. Falls $s < 200$, folgt $200 - s > 0$, somit ist S eine strikt dominante Strategie. Falls $s < 200$, folgt $0.05 * s - 10 < 0$, somit ist KP eine strikt dominante Strategie.
Spiele in gemischten Strategien können alternativ als reine Strategien aus der jeweiligen Sicht der SpielerInnen P1 und P2 berechnet werden. Ein Sattelpunkt kann beispielsweise bei (0.5, 0.25) liegen. Durch Einsetzen von $p$ in $S_{21}$ oder $S_{22}$ sowie $q$ in $S_{11}$ oder $S_{12}$ ergibt sich ... Eine alternative Darstellung über `f(x,y) = -8*x*y + 2*x + 4*y + 1` und `splot [0:1][0:1] f(x,y)` ist möglich.
Gruppenentscheidungen befassen sich mit der gemeinsamen Bestimmung einer Rangfolge von Möglichkeiten (z.B. Wahlen, Wettbewerbe). Nicht alle werden mit der Rangfolge einverstanden sein. Ein axiomatischer Ansatz stellt Eigenschaften auf und prüft, welche Entscheidungsverfahren diese erfüllen. Die Modellierung individueller Präferenzen und der Entscheidungsverfahren selbst ist essentiell. Bedingungen an Auswahlverfahren beinhalten die Unabhängigkeit von irrelevanten Alternativen. Ein Beispiel: $I = \{1, 2\}$, $A = \{x, y, z\}$ mit Rangaddition KA als Auswahlverfahren. Als Gruppenentscheidung bzgl. x und y gilt $y \rho' x$, aber nicht $x \rho y$. Das Ergebnis ändert sich, obwohl kein Individuum die Präferenz im direkten Vergleich zwischen x und y ändert (i=1 sieht x < y und i=2 ...).

View File

@ -0,0 +1,235 @@
# Clustered and Rewritten Text Document
This document groups text chunks based on semantic similarity. Topics and rewritten text (formatted in Markdown with LaTeX for equations) are generated by the Gemini API.
## Game Theory Basics
Nash Equilibrium
Dominant Strategies
Prisoner's Dilemma
Zero-Sum Games
Conservative Strategies
Mixed Strategies
Checkpoints Summary
Group Decisions
Collective Choice
# Spieltheorie: Eine Zusammenfassung
Nicht-kooperative Spiele sind in der Literatur und in Anwendungen weit verbreitet. Spieler können keine Absprachen vor dem Spiel treffen und haben keinerlei Vereinbarungen über gemeinsame Aktionen, die optimal für die Gruppe sind. Eine zweite Unterscheidung betrifft simultane Spiele, bei denen alle Spieler ihre Wahl ein für alle Mal treffen (nur ein Zug).
Spielen in reinen Strategien: Eine dominante Strategie $a_i$ ist mindestens so gut wie eine andere Strategie $a_i'$ für alle möglichen Aktionen der anderen Spieler $a_j \in A_j \neq i$, d.h. für alle $a_j \in A_j \neq i$ gilt $u_i(a_i, a_{-i}) \ge u_i(a_i', a_{-i})$. Gilt die Ungleichung im strengen Sinn ($>$), spricht man von starker Dominanz. Ein Nash-Gleichgewicht liegt vor, wenn kein Spieler durch eine einseitige Abweichung davon eine höhere Auszahlung erzielen kann. Das bedeutet, für alle $a_i \in A_i$ und $i \in N$ gilt: $u_i(a_i^*, a_{-i}^*) \ge u_i(a_i, a_{-i}^*)$. Was bedeutet das für das Gefangenendilemma…?
Weiteres Beispiel: Falke-und-Taube-Spiel. Zwei Wettkämpfer müssen sich zwischen aggressivem (Falke) und nicht-aggressivem (Taube) Verhalten entscheiden. Die dominante Strategie beider Spieler ist G. ABER: Gleichgewicht (G, G) ist ineffizient, da (L, L) eine bessere Auszahlung ergeben würde.
$$
\begin{array}{c|cc}
& G & L \\
\hline
G & (6, 6) & (8, 0) \\
L & (0, 8) & (3, 3) \\
\end{array}
$$
Zwei-Personen-Nullsummenspiele: Spieler versuchen, den Gewinn zu maximieren (d.h. den Gewinn des anderen zu minimieren); der Verlust des einen ist der Gewinn des anderen (d.h. die Summe ist immer Null). Die Darstellung von 2PNS-Spielen erfolgt üblicherweise in Normalform (oder Matrixform).
$$
\begin{array}{c|cc}
& S_{21} & S_{22} \\
\hline
S_{11} & (-1, 1) & (-5, 5) \\
S_{12} & (1, -1) & (3, -3) \\
\end{array}
$$
Konservative Strategien: Die beste gegnerische Strategie führt zum eigenen schlechtesten Gewinn. Eine konservative Strategie wählt den besten Wert aus allen ungünstigsten Fällen. Der Minimierer P1 sucht $\max_i \min_j u_{1ij}$, der Maximierer P2 sucht $\min_j \max_i u_{1ij}$ (Schnittpunkt von Minimum und Maximum). Die Idee bleibt gleich: Keine Spielerin kann sich durch einen einseitigen Strategiewechsel verbessern.
Beispiel: Schlacht in der Bismarcksee. Falls die Amerikaner die richtige Route überprüfen, kann die Bombardierung sofort begonnen werden (andernfalls verbleiben zwei Tage für die andere Route). Auf der Nordroute muss wegen schlechter Sicht die Bombardierung zudem einen Tag ausbleiben. Damit ergibt sich folgendes 2PNS-Spiel (Gewinn ≡ mögliche Tage für Bombardierung):
$$
\begin{array}{c|cc}
& N & S \\
\hline
N & (2, -2) & (1, -1) \\
S & (0, 0) & (2, -2) \\
\end{array}
$$
$\implies i^* = N$ und $U^- = 2 \implies j^* = N$ und $U^+ = 2 \implies$ Sattelpunkt bei (N, N).
Spielen in gemischten Strategien: Reine Strategien legen *a priori* eine Strategie fest. Nachteil: Vorhersehbarkeit durch Mitspieler. Im Fall eines Sattelpunkts wird das 2PNS-Spiel mit Wahrscheinlichkeiten $p$ und $q$ multipliziert. Die Lösung der zugehörigen Gleichung erfolgt oft durch lineare Programmierung.
$$
\begin{array}{c|cc}
& S_{21} & S_{22} \\
\hline
S_{11} & 1 & -5 \\
S_{12} & 3 & -1 \\
\end{array}
$$
$\implies$ Sattelpunkt der Funktion (graphisch) bei $p = 0.5$ und $q = 0.25$.
Checkpoints: Spiele in reinen Strategien, Darstellung in Normalform/Bimatrixform, dominante Strategie, Nash-Gleichgewicht, Zwei-Personen-Nullsummenspiele.
Gruppenentscheidungen: Gesucht ist eine kollektive Auswahlfunktion $K$ für die Präferenz der Gesamtheit: $K: PA = PA \times PA \times \dots \times PA \to PA$. Wesentliche Bedingungen: Die Auswahlfunktion $K$ muss total sein. Für jede mögliche Kombination von (persönlichen) Präferenzen aus $PA$ muss es eine Gesamtpräferenz (also ein Ergebnis) geben. Das Ergebnis selbst muss wieder eine Relation in $PA$ sein.
Entscheidungsverfahren (Fortsetzung): Rangaddition. Jede Individualpräferenz $\rho_i$ legt eine Rangabbildung fest. Die kollektive Präferenz wird aus den Rangnummern der jeweiligen Individuen bestimmt. Einfache Methode: Addition der Rangnummern. Für zwei Elemente x, y gilt: $K_A(\rho_1, \dots, \rho_n)$ ist Relation $\rho$ mit $\sum r_i$. Die Summe $\sum r_i$ ist keine Rangabbildung, kann aber leicht korrigiert werden, sodass $\rho \in PA$ gilt. Das Verfahren hat keine offensichtlichen Nachteile.
Kollektive Auswahlfunktionen $PA \to PA$ werden auch von unerwünschten Verfahren erfüllt. Zwei Bedingungen, die jedes „gerechte“ Verfahren erfüllen sollte: Pareto-Bedingung: Die Gesamtheit kann für beliebige Wahlmöglichkeiten durch Einstimmigkeit jede gewünschte Rangfolge erzwingen. Unabhängigkeit von irrelevanten Alternativen: Die Rangfolge zwischen zwei Wahlmöglichkeiten wird nur von den Präferenzen bezüglich dieser beiden Möglichkeiten bestimmt.
---
## Game Theory Basics
Two-Person Zero-Sum Games
Bismarck Sea Battle
Mixed Strategies Game
Group Decisions
Preferences & Relations
Decision Procedures
Arrow's Impossibility Theorem
# Spieltheorie: Eine Einführung
Zwei-Personen-Nullsummenspiele (2PNS-Spiele) werden auch als MinMax-Spiele bezeichnet. In Matrixform wird Spieler 1 zur Minimiererin (Zeilenspielerin) und Spieler 2 zur Maximiererin (Spaltenspielerin). Aufgrund der speziellen Struktur von 2PNS-Spielen nehmen Nash-Gleichgewichte die Form von Sattelpunkten an (Schnittpunkt von Minimum und Maximum). Der Min-Max-Theorem besagt: Ein Sattelpunkt existiert genau dann, wenn $U^- = a_{i^*j^*} = U^+$. Ein Beispiel hierfür ist die Schlacht in der Bismarcksee (2.-4. März 1943): Japanische Truppen sollen von Rabaul nach Lae verlegt werden, wobei zwei Routen zur Verfügung stehen: eine regnerische Nordroute und eine sonnige Südroute. Der japanische Konvoi ist unabhängig von der gewählten Route drei Tage unterwegs. Die U.S. Air Force möchte den Konvoi bombardieren, hat aber nicht genügend Flugzeuge, um beide Routen gleichzeitig zu überwachen. Die Amerikaner müssen eine Entscheidung treffen.
Möglichkeiten: Aktionen: $A_1 = \{X, Y\}$ und $A_2 = \{X, Y\}$. Aktionsprofile: $A = \{(X, X), (X, Y), (Y, X), (Y, Y)\}$. Auszahlungsfunktion: $u_{1,2}: A \to (1, 0, 0, 1)$. Wie verändert sich das Spiel, wenn folgende Auszahlungsfunktionen gelten? Spieler 1: $u_1: A \to (1, 0, 0, 0)$; Spieler 2: $u_2: A \to (0, 0, 0, 1)$.
Spielen in gemischten Strategien: Aufgabe: Steuerhinterziehung. Wie ändert sich die Situation für den Fall $s > 200$ Mio. CHF? Problem: Keine dominante Strategie / kein Nash-Gleichgewicht in reinen Strategien. Wenn $q$ in $S_{22}$ sowie $p$ in $S_{11}$ oder $S_{12}$ gilt, ergibt sich $U^- = 2 = U^+$.
Gruppenentscheidungen: Relationen beschreiben Beziehungen (z.B. Rangfolgen, Präferenzen) zwischen Elementen. Darstellung als Relation $R$ auf Paaren $(x, y)$ von Elementen aus $A$, formal geschrieben als $(x, y) \in R$ oder abkürzend als $xRy$. Beispiel: Mit $R$ ist $<$ (kleiner) und $xRy$ folgt $x < y$. Eigenschaften von Relationen...
Präferenzen: Rangabbildungen definieren eine Präferenzrelation: $x \rho y \iff r(x) < r(y)$. Relation $\rho$ ist transitiv und asymmetrisch. Die Menge aller (möglichen) darstellbaren Relationen auf $A$ ist definiert als $P_A := \{\rho \subset A \times A: \rho \text{ erfüllt } x \rho y \iff r(x) < r(y) \text{ für eine Rangabbildung } r\}$. Erweiterung der Relation durch alle Paare mit gleichem Rang: $x \rho^* y \iff r(x) \le r(y)$. Relation $\rho^*$ ist transitiv und reflexiv. Es gilt offensichtlich $\rho \subset \rho^*$. Analog zur Menge $P_A$ lässt sich damit definieren $P_A^* := \{\rho^* \subset A \times A: \rho^* \text{ erfüllt } x \rho^* y \iff r(x) \le r(y) \text{ für eine Rangabbildung } r\}$. Beispiel: $A = \{x, y, z\}$, $r(x) = 1$, $r(y) = r(z) = 2$. Zwischen beiden Relationen gilt folgende Beziehung: $x \rho y \iff \neg(y \rho^* x)$. Rangabbildungen vor allem für...
Entscheidungsverfahren: Extrembeispiel 1: Externer Diktator. Für beliebiges $\rho_E \in P_A$ gilt... Ergebnis ist offensichtlich Abbildung $P_A \to P_A$, aber unabhängig von den $\rho_i$. Verfahren kann kaum als „gerecht“ oder „demokratisch“ bezeichnet werden. Extrembeispiel 2: Interner Diktator. Festlegung eines Individuums $d \in I$, dessen Präferenz $\rho_d$ das Ergebnis bestimmt. Damit gilt... Rangaddition: Beispiel: $I = \{1, 2\}$, $A = \{x, y, z\}$. Rangaddition hat keine offensichtlichen Nachteile, liefert aber ggf. unschöne Ergebnisse.
Mehrheit: Es folgt $x \rho y$, $y \rho z$ und $z \rho x$. Aus der Transitivität folgt schließlich $x \rho x \to$ kein gültiges Ergebnis, d.h. $\rho \notin P_A$. Einstimmigkeit: Element $x$ wird Element $y$ vorgezogen $\iff$ alle Individuen teilen diese Präferenz für alle. ABER: Ein einziges Individuum, das $y$... Rangfolge zwischen zwei Wahlmöglichkeiten kann nicht durch Präferenzänderungen der Individuen im Hinblick auf eine dritte Wahlmöglichkeit gekippt werden. Problem: Bereits mit diesen zwei Forderungen kein annähernd demokratisches Verfahren mehr möglich (Satz von Arrow). Quintessenz: Demokratie funktioniert nicht…?
Bedingungen an Auswahlverfahren: Möglichkeit $z$ soll keinen Einfluss auf Ergebnis haben. Oder formal: Wenn kein Individuum Präferenz $\rho_i, \rho_i' \in P_A$ bzgl. $x$ und $y$ ändert, soll gelten (für alle) $\implies$ (...). Rangaddition somit als „gerechtes“ Verfahren ausgeschlossen. Condorcet-Verfahren und Einstimmigkeit liefern für $|A| > 2$ evtl. ungültiges Ergebnis. Nur interner Diktator $K_D$ erfüllt alle Bedingungen. Der Diktator ist „großzügiger“ gegenüber anderen Gruppenmitgliedern. Bei Indifferenz (es gilt weder $x \rho_d y$ noch $y \rho_d x$) beliebige Rangfolgen von $x, y$ zulässig. US-Wahlen haben nur zwei Kandidaten.
---
## Game Theory Introduction
# Einführung in die Spieltheorie (CDS-1012) HS 2024 Prof. Dr. rer. nat. habil. Ralf-Peter Mundani, DAViS
**Einleitung:** Ein Überblick über die Spieltheorie, ein Teilgebiet der Mathematik, das das strategische Denken modelliert. Wir behandeln die Modellierung von Entscheidungssituationen, Spiele in reinen Strategien, das Nash-Gleichgewicht und dominante Strategien, Zwei-Personen-Nullsummenspiele, konservative Strategien, Spiele in gemischten Strategien und die Berechnung von Sattelpunkten. Mehrheitsbeschlüsse und Gruppenentscheidungen werden im zweiten Teil behandelt.
**Motivation aus der Stochastik: Das Ziegenproblem (a.k.a. Monty-Hall-Dilemma):** Eine Spielshow mit drei Türen zwei Ziegen und ein Auto. Der Spieler wählt eine Tür, der Showmaster öffnet eine andere Tür mit einer Ziege. Sollte der Spieler seine Wahl ändern? Die Fälle, in denen der Spieler Tür B oder C wählt, sind symmetrisch. In drei von neun Fällen verliert der Spieler, in sechs von neun Fällen gewinnt er. Das Ändern der Wahl ist also vorteilhaft.
**Grundlagen:** Die Spieltheorie modelliert Entscheidungssituationen, in denen die Akteure (Spieler) ihre Wahl gleichzeitig und nur einmal treffen (ein Durchlauf). Eine übliche Darstellung ist die Normalform (z.B. Gefangenendilemma). Sequentielle Spiele weisen eine spezifische Ordnung auf, die bestimmt, welcher Spieler wann entscheidet. Spieler haben in jedem Schritt vollständiges oder unvollständiges Wissen über den aktuellen Status (frühere Entscheidungen). Die übliche Darstellungsform ist extensiv oder als Baum.
**Spiele in reinen Strategien:** Das Gefangenendilemma ist ein bekanntes nicht-kooperatives Spiel in reinen Strategien. Zwei Gefangene werden beschuldigt, gemeinsam ein Verbrechen begangen zu haben. Sie werden getrennt vernommen und können nicht kommunizieren. Mangels Beweisen kann beiden nur ein Teil der Tat nachgewiesen werden. Mögliche Aktionen sind Leugnen (L) mit einer niedrigen Strafe (2 Jahre) und Gestehen (G) mit einer hohen Strafe (5 Jahre) oder Höchststrafe (8 Jahre Kronzeugenregel). Die Auszahlung wird durch die Funktion $u_i$ modelliert, die den Gewinn an Freiheit (Höchststrafe tatsächliche Strafe) darstellt.
**Gefangenendilemma (Fortsetzung):** Die Darstellung in Normalform (bei zwei Spielern auch Bimatrixform genannt) lautet:
| | G | L |
| :---- | :---- | :---- |
| **G** | (6, 6) | (8, 0) |
| **L** | (0, 8) | (3, 3) |
Die Frage ist: Wie finden beide Spieler die für sie beste Strategie?
**Ein bisschen Mathematik:** Das Nash-Gleichgewicht ist ein Aktionsprofil, bei dem kein Spieler einen Anreiz hat, seine Strategie einseitig zu ändern. Eine stark dominante Strategie $a_i$ ist besser als jede andere Strategie $a_i$ unabhängig von den Strategien der anderen Spieler. Profile dominanter Strategien führen zu Nash-Gleichgewichten (die Umkehrung gilt nicht). Was bedeutet das für das Gefangenendilemma?
**Stark dominante Strategie:** Die stark dominante Strategie beider Spieler ist G.
**Übung: Steuerhinterziehung:** Ein Unternehmen, Zanoma, hat 200 Millionen CHF nicht versteuert. Wird die Steuerhinterziehung nachgewiesen, muss das Unternehmen eine Nachzahlung von $s$ Millionen CHF (Steuer plus Busse) leisten. Der Steuerprüfer erhält im Erfolgsfall 5% der Nachzahlung als Prämie. Der Steuerprüfer hat die Strategien Prüfung (P; Kosten: 10M CHF) und keine Prüfung (KP; Kosten: 0). Zanoma hat die Strategien Steuerhinterziehung (S) und keine Steuerhinterziehung (KS).
a) Wie sieht die Situation als Spiel in Bimatrixform aus?
b) Gibt es für $s < 200$M CHF dominante Strategien und Nash-Gleichgewichte?
**(jede Ähnlichkeit mit real existierenden Unternehmen ist rein zufällig)**
**Konservative Strategien:** Konservative Strategien minimieren den maximal möglichen Verlust (Minimax). Der Minimierer $P_1$: $U^- = \min_i \max_j a_{ij}$. Der Maximierer $P_2$: $U^+ = \max_j \min_i a_{ij}$.
**Spiele in gemischten Strategien:** Spiele in gemischten Strategien haben immer einen Sattelpunkt. Spieler $P_1$ spielt mit Wahrscheinlichkeit $p$ Strategie $S_{11}$ und mit $1-p$ Strategie $S_{12}$. Spieler $P_2$ spielt mit Wahrscheinlichkeit $q$ Strategie $S_{21}$ und mit $1-q$ Strategie $S_{22}$. Für den Fall $n > 2$ Strategien werden Wahrscheinlichkeiten $p_1, p_2, \dots, p_n$ verwendet.
**Steuerhinterziehung (Fortsetzung):** Aus Sicht von Zanoma: $(200 - s) \cdot q + 200 \cdot (1 - q) = 0 \cdot q + 0 \cdot (1 - q) \iff q = \frac{200}{s}$. Aus Sicht des Steuerprüfers: $(0.05 \cdot s - 10) \cdot p - 10 \cdot (1 - p) = 0 \cdot p + 0 \cdot (1 - p) \iff p = \frac{200}{s}$. Das Nash-Gleichgewicht in gemischten Strategien ist somit für $p = q$, d.h. für $(\frac{200}{s}, \frac{200}{s})$. Höhere Nachzahlungen (Bussen) senken die Wahrscheinlichkeit der Prüfung.
**Gruppenentscheidungen:** Der Satz von Arrow: Sei $A$ mit $|A| > 2$ eine Menge von Auswahlmöglichkeiten. $K: PA \to PA$ sei eine kollektive Auswahlfunktion, die die Pareto-Bedingung und Unabhängigkeit von irrelevanten Alternativen erfüllt. Dann existiert immer ein Diktator $d \in I$: Für alle $(\rho_1, \dots, \rho_n) \in PA$: Für alle $(x, y) \in A \times A$: $x \rho_d y \implies x \rho y$. ABER: Der Diktator ist „großzügiger“ gegenüber anderen.
---
## Game Theory Basics
Nicht-kooperative Spiele zeichnen sich dadurch aus, dass alle Spieler ihre Auszahlung maximieren, indem sie ihre beste Strategie wählen basierend auf ihrem Wissen oder ihren Erwartungen bezüglich der Strategien der anderen Spieler. Vereinbarungen zwischen den SpielerInnen gibt es nicht. Im Gegensatz dazu stehen kooperative Spiele, bei denen alle SpielerInnen nach gemeinsamen Aktionen suchen, die optimal für die gesamte Gruppe sind. In kooperativen Spielen können die SpielerInnen vor Spielbeginn Absprachen treffen.
---
## Game Theory Strategies
Mixed Strategies
Group Decision Making
Preference Rankings
Decision Procedures
# Gruppenentscheidungen und Entscheidungsverfahren
Vorhersehbarkeit durch Mitspieler*innen ist ein wichtiges Thema. Ein Beispiel: Schere (100%), Stein (0%), Papier (0%) repräsentiert eine reine Strategie. Gemischte Strategien hingegen bedeuten, dass eine Spieler*in zufällig zwischen Strategien entscheidet. Formal lässt sich dies als Wahrscheinlichkeitsfunktion über (reinen) Strategien charakterisieren. Beispiel: Schere (25%), Stein (50%), Papier (25%). Reine Strategien führen aber häufig nicht zu Nash-Gleichgewichten. Nicht jedes Zwei-Personen-Nullsummenspiel (2PNS-Spiel) in reinen Strategien hat einen Sattelpunkt. Betrachten wir das Beispiel:
$$
\begin{array}{c|cc}
& S_{21} & S_{22} \\
\hline
S_{11} & 3 & -1 \\
S_{12} & -1 & 5 \\
\end{array}
$$
Hier gilt: $\min_i \max_j = 3$ und $\max_j \min_i = 1$. Daher ist $i^* = S_{11}$ und $j^* = S_{22}$, mit $U^- = 3$ und $U^+ = 1$. Zwei-Personen-Nullsummenspiele in gemischten Strategien haben immer einen Sattelpunkt. Dies wird durch das Min-Max-Theorem nochmals verdeutlicht.
Situationen mit unerwünschten Ergebnissen sind in der Regel nicht vermeidbar, auch abhängig von den gewählten Entscheidungsverfahren.
Rangabbildungen sind ein hilfreiches Werkzeug bei Gruppenentscheidungen. Gegeben ist eine endliche Menge $A$ von Möglichkeiten (z.B. Kandidat*innen, Pläne...). Präferenzen entstehen durch die Vergabe von Rangnummern $r(x)$ mit $x \in A$. Für zwei Möglichkeiten $x, y \in A$ bedeutet $r(x) < r(y)$, dass $x$ gegenüber $y$ bevorzugt wird. Zwei (oder mehr) Möglichkeiten können dieselbe Rangnummer erhalten. Eine Rangabbildung $r: A \to P$ ist eine surjektive Abbildung der Menge der Möglichkeiten $A$ auf eine Menge von Präferenzen $P = \{1, \dots, k\} \subset \mathbb{N}$. Beispiel:
$A = \{x, y, z\}$, $P = \{1, 2\}$
$r(x) = 1$, $r(y) = r(z) = 2$.
Surjektivität bedeutet, dass jedes Element der Bildmenge mindestens ein zugehöriges Element in der Urbildmenge hat.
Eigenschaften von Relationen sind wichtig: Transitiv: Mit $xRy$ und $yRz$ folgt auch $xRz$ (z.B. aus $2 < 3$ und $3 < 4$ folgt $2 < 4$). Reflexiv: $xRx$ gilt für alle $x \in A$ (z.B. $2 \le 2$). Asymmetrisch: $xRy$ und $yRx$ gelten niemals gleichzeitig (z.B. $2 < 3$, aber nicht $3 < 2$). Transitive und reflexive Relationen werden auch Quasiordnungen genannt. Rangabbildungen eignen sich vor allem für Visualisierungen (z.B. Fussballtabellen).
Betrachten wir nun Entscheidungsverfahren. Die Menge der Wähler*innen $I = \{1, \dots, n\}$ besteht aus Individuen, durchnummeriert von 1 bis n. Jede*r Wähler*in hat eine persönliche Präferenz $P_i$. Gesucht ist eine kollektive Auswahlfunktion.
Mehrheitsentscheidung (Condorcet-Verfahren): Im direkten Vergleich zweier Elemente $x, y \in A$ gibt es Individuen $\{i \in I: x \rho_i y\}$, die $x$ bevorzugen, Individuen $\{i \in I: y \rho_i x\}$, die $y$ bevorzugen, und Individuen, die bezüglich $x$ und $y$ indifferent sind. Das Condorcet-Verfahren zählt, wer mehr Vergleiche gewinnt. Für zwei Elemente $x, y$ gilt: $K_C(\rho_1, \dots, \rho_n)$ ist eine Relation $\rho$. Das Verfahren ist für beliebige $\rho$ durchführbar, aber die Relation $\rho$ ist im Fall von mehr als zwei Möglichkeiten nicht immer transitiv, d.h. $\rho$ ist keine zulässige Präferenzrelation aus $P_A$. Beispiel: $I = \{1, 2, 3\}$, $A = \{x, y, z\}$. Es folgt $x \rho y$, $y \rho z$ und $z \rho x$. Aus der Transitivität würde $x \rho z$ folgen, was aber nicht der Fall ist. In der Praxis liefert das Verfahren keine echten Präferenzen (außerdem: für $|A| > 2$, $\rho \notin P_A$). Beispiel: $i = 1$: $x < y < z$ und $i = 2$: $y < z < x$. $\rho$ enthält genau ein Paar $y \rho z \implies \rho \notin P_A$.
Bedingungen an Auswahlverfahren: Pareto-Bedingung (Einstimmigkeit): Eine kollektive Auswahlfunktion $K: P_A \to P_A$ erfüllt die Pareto-Bedingung, wenn für alle $\rho_i \in P_A$ gilt: für alle $x, y \in A$ mit $x \rho_i y$ für alle $i \in I$ folgt $x \rho y$. Somit scheidet der externe Diktator aus, alle anderen Verfahren erfüllen die Bedingung. Beispiel: Beide Individuen sehen $x, y$ vor $z$.
Unabhängigkeit von irrelevanten Alternativen: Die Platzierung einer dritten Möglichkeit $z$ soll keinen Einfluss auf die Rangordnung zwischen $x$ und $y$ haben. Eine Präferenzänderung bei einem Individuum kann die kollektive Präferenz beeinflussen.
---
## Game Theory Basics
# Spieltheorie: Grundlagen und Anwendungen
Die Spieltheorie modelliert Entscheidungssituationen, oft in sozialen Konflikten. Der Erfolg hängt dabei nicht nur von den eigenen, sondern auch von den Entscheidungen anderer ab. Wichtige Anwendungsgebiete sind die Wirtschaftswissenschaften und Ökonomie. Bekannte Vertreter sind John von Neumann und John Forbes Nash. Man unterscheidet zwischen kooperativen und nicht-kooperativen Spielen sowie simultanen und sequentiellen Spielen.
Grundlagen: Entscheidungen können unter Gewissheit (alle Aktionen und Konsequenzen sind bekannt), Risiko (bestimmte Wahrscheinlichkeiten von Aktionen und Konsequenzen sind bekannt) und Unsicherheit (keine Aktionen und Konsequenzen sind bekannt) getroffen werden. Die Modellierung umfasst: eine Menge von SpielerInnen $N = \{1, 2, \dots, n\}$, eine Menge der Aktionen (auch Strategien genannt) $A_i$ von SpielerIn $i$ für alle $i \in N$, und eine Menge der Aktionsprofile (auch Strategieprofile) $A = \{(a_i)_{i \in N}, a_i \in A_i \text{ für alle } i \in N\}$. Die Auszahlungsfunktion $u_i: A \to \mathbb{R}$ beschreibt die Auszahlung für SpielerIn $i$. Beispiel: Entscheidung zwischen zwei Möglichkeiten mit Aktionen $A_1 = \{X, Y\}$ und ...
... ein Nash-Gleichgewicht liegt vor, wenn keine SpielerIn durch einseitige Abweichung von ihrer Entscheidung (während alle anderen SpielerInnen bei ihren Entscheidungen bleiben) eine höhere Auszahlung erzielen kann. Formal: Ein Aktionsprofil bildet genau dann ein Nash-Gleichgewicht, wenn keine der SpielerInnen durch Abweichung davon eine höhere Auszahlung erhält.
Zwei-Personen-Nullsummenspiele: Hier ist der Gewinn einer SpielerIn der Verlust der anderen (die Summe ist immer null). Die USA nutzten diese Spielart während der Kuba-Krise für strategische Analysen. Das Spiel wird interessant, wenn die Kosten für den Kampf ($C$) die Kosten bzw. den Wert des Sieges ($V$) überschreiten, d.h. $C > V > 0$.
Übung: Steuerhinterziehung. Unternehmen Zanoma hat durch kreative Buchführung 200 Millionen CHF nicht versteuert. Falls $s < 200$, folgt $200 - s > 0$, also ist S eine strikt dominante Strategie. Falls $s < 200$, folgt $0.05 \cdot s - 10 < 0$, also ist KP eine strikt dominante Strategie.
Spielen in gemischten Strategien: Alternative Berechnung (als reine Strategien) aus der jeweiligen Sicht von SpielerIn P1 und P2. Sattelpunkt bei (0.5, 0.25); durch Einsetzen von $p$ in $S_{21}$ oder $S_{22}$ sowie $q$ in $S_{11}$ oder $S_{12}$ ergibt sich ... $f(x,y) = -8xy + 2x + 4y + 1$ und `splot [0:1][0:1] f(x,y)`.
Zwei-Personen-Nullsummenspiele: Darstellung in Matrixform. Konservative Strategien (MinimiererIn/MaximiererIn). Spiele in gemischten Strategien. Gleichgewichtspunkte/Sattelpunkt.
Gruppenentscheidungen: Verschiedene Möglichkeiten (Entscheidungsvarianten: Wahlen, Wettbewerbe, ...). Ziel: Gemeinsame Bestimmung einer Rangfolge der Möglichkeiten. Beispiel: WählerInnen ➡️ KandidatInnen (Wahl), Publikum ➡️ TeilnehmerInnen (Wettbewerb). Nicht alle werden mit der Rangfolge einverstanden sein (Unzufriedenheit). Axiomatischer Ansatz: Aufstellung von Eigenschaften und Prüfung, welche Entscheidungsverfahren sie erfüllen. Modellierung individueller Präferenzen und der Entscheidungsverfahren selbst.
Bedingungen an Auswahlverfahren: Unabhängigkeit von irrelevanten Alternativen. Beispiel: $I = \{1, 2\}$, $A = \{x, y, z\}$ mit Rangaddition $K_A$ als Auswahlverfahren. Als Gruppenentscheidung bzgl. $x$ und $y$ gilt $y \rho' x$, aber nicht $x \rho y$. Das Ergebnis ändert sich, obwohl kein Individuum die Präferenz im direkten Vergleich zwischen $x$ und $y$ ändert ($i=1$ sieht $x < y$ und $i=2$ ...).

View File

@ -0,0 +1,293 @@
# Clustered and Rewritten Text Document
This document groups text chunks based on semantic similarity. Topics and rewritten text (formatted in Markdown with LaTeX for equations) are generated by the Gemini API.
## Game Theory Basics
Nash Equilibrium & Dominance
Zero-Sum Games
Mixed Strategies
Collective Decision Making
# Spieltheorie: Zusammenfassung
Nicht-kooperative Spiele sind in der Literatur und in Anwendungen weit verbreitet. Spieler können keine Absprachen vor dem Spiel treffen und haben keinerlei Vereinbarungen über gemeinsame Aktionen, die optimal für die Gruppe sind. Eine Unterscheidung ist die zwischen simultanen Spielen, bei denen alle Spieler ihre Wahl ein für alle Mal treffen (nur ein Zug), und sequentiellen Spielen.
Spielen in reinen Strategien: Eine dominante Strategie ist eine Strategie $a_i$, die mindestens so gut ist wie eine andere Strategie $a_i' \in A_i$ für alle möglichen Aktionen der anderen Spieler $a_j \in A_j \neq i$ ($a_i \ge a_i'$). Gilt die Ungleichung im strengen Sinn ($a_i > a_i'$), spricht man von starker Dominanz. Ein Nash-Gleichgewicht liegt vor, wenn kein Spieler durch eine einseitige Abweichung davon eine höhere Auszahlung erzielen kann, d.h. für alle $a_i \in A_i$ und $i \in N$. Das Gefangenendilemma illustriert dies: Die dominante Strategie beider Spieler ist G, ABER: das Gleichgewicht (G, G) ist ineffizient, da (L, L) eine bessere Auszahlung ergeben würde. Ein weiteres Beispiel ist das Falke-und-Taube-Spiel.
Zwei-Personen-Nullsummenspiele: Hier versuchen Spieler ihren Gewinn zu maximieren (und den Verlust des anderen zu minimieren); die Summe der Auszahlungen ist immer Null. Sie werden üblicherweise in Normalform (oder Matrixform) dargestellt. Konservative Strategien wählen den besten Wert aus allen ungünstigsten Fällen. Der Sattelpunkt (Schnittpunkt von Minimum und Maximum) repräsentiert die beste Strategie für beide Spieler. Kein Spieler kann sich durch einen einseitigen Strategiewechsel verbessern. Ein Beispiel ist die Schlacht in der Bismarcksee. Falls die Amerikaner die richtige Route überprüfen, kann die Bombardierung sofort begonnen werden (andernfalls verbleiben zwei Tage für die andere Route). Auf der Nordroute muss wegen schlechter Sicht die Bombardierung einen Tag ausbleiben. Dies ergibt folgendes 2PNS-Spiel (Gewinn ≡ mögliche Tage für Bombardierung):
```
SN12N32S
Japan (min)U.S. Air Force (max)
```
$\implies i^* = N$ und $U^- = 2 \implies j^* = N$ und $U^+ = 2 \implies$ Sattelpunkt bei (N, N).
Spielen in gemischten Strategien: Im Gegensatz zu reinen Strategien, bei denen sich ein Spieler *a priori* auf eine Strategie festlegt, werden hier Wahrscheinlichkeiten für verschiedene Strategien verwendet. Dies reduziert die Vorhersehbarkeit. Die Lösung findet man oft durch Multiplikation des 2PNS-Spiels mit Wahrscheinlichkeiten p und q und die Lösung der zugehörigen Gleichung (oftmals durch lineare Programmierung). Ein Beispiel:
```
1qq
S22S2131
S11p15
S121p
P1(min)P2(max)
```
$\implies$ Sattelpunkt der Funktion (graphisch) bei $p = 0.5$ und $q = 0.25$.
Checkpoints: Wichtige Begriffe sind Spiele in reinen Strategien, Darstellung in Normalform/Bimatrixform, dominante Strategie, Nash-Gleichgewicht und Zwei-Personen-Nullsummenspiele.
Gruppenentscheidungen: Gesucht ist eine kollektive Auswahlfunktion K für die Präferenz der Gesamtheit: $K: PA = PA \times PA \times \dots \times PA \to PA$. Wesentliche Bedingungen sind, dass die Auswahlfunktion total sein muss (für jede Kombination von Präferenzen muss es ein Ergebnis geben) und dass das Ergebnis selbst eine Relation in PA sein muss. Ein einfaches Verfahren ist die Rangaddition. Jede Individualpräferenz $\rho_i$ legt eine Rangabbildung fest. Die kollektive Präferenz wird aus den Rangnummern der Individuen bestimmt. Die Summe der Rangnummern ist keine Rangabbildung, kann aber korrigiert werden. Das Verfahren hat keine offensichtlichen Nachteile, aber kollektive Auswahlfunktionen $PA \to PA$ werden auch von unerwünschten Verfahren erfüllt. Zwei Bedingungen für „gerechte“ Verfahren sind die Pareto-Bedingung und die Unabhängigkeit von irrelevanten Alternativen.
---
## Game Theory Basics
Two-Person Zero-Sum Games
Bismarck Sea Battle
Mixed Strategies Game
Group Decisions
Preference Relations
Decision Procedures
Arrow's Impossibility Theorem
# Spieltheorie: Eine Einführung
## Zwei-Personen-Nullsummenspiele
Zwei-Personen-Nullsummenspiele (2PNS-Spiele) werden auch als MinMax-Spiele bezeichnet. In Matrixform wird Spieler 1 zur Minimiererin (auch Zeilenspielerin genannt) und Spieler 2 zur Maximiererin (auch Spaltenspielerin genannt). Aufgrund der speziellen Struktur von 2PNS-Spielen nehmen Nash-Gleichgewichte die Form von Sattelpunkten an (Schnittpunkt von Minimum und Maximum). Der Min-Max-Theorem besagt: Ein Sattelpunkt existiert genau dann, wenn $U^- = a_{i*j*} = U^+$. Ein Beispiel hierfür ist die Schlacht in der Bismarcksee (2.-4. März 1943). Die Japaner wollten Truppen und Material von Rabaul (Bismarck-Archipel) nach Lae (Papua-Neuguinea) verlegen. Es standen zwei mögliche Routen zur Verfügung: eine regnerische Nordroute und eine sonnige Südroute. Der japanische Konvoi war unabhängig von der gewählten Route drei Tage unterwegs. Die U.S. Air Force wurde über die Verlegung informiert und wollte den Konvoi bombardieren, hatte aber nicht genügend Flugzeuge, um beide Routen gleichzeitig zu überwachen. Die Amerikaner mussten also eine Entscheidung treffen. Wenn beispielsweise $q$ in $S_{22}$ sowie $q$ in $S_{11}$ oder $S_{12}$ ist, ergibt sich $U^- = 2 = U^+$.
## Möglichkeiten, Aktionen und Auszahlungsfunktionen
Möglichkeiten/Aktionen: $A_1 = \{X, Y\}$ und $A_2 = \{X, Y\}$. Aktionsprofile: $A = \{(X, X), (X, Y), (Y, X), (Y, Y)\}$. Auszahlungsfunktion: $u_{1,2}: A \to (1, 0, 0, 1)$. Wie verändert sich das Spiel, wenn folgende Auszahlungsfunktionen gelten? Spieler 1: $u_1: A \to (1, 0, 0, 0)$; Spieler 2: $u_2: A \to (0, 0, 0, 1)$.
## Spielen in gemischten Strategien
Aufgabe: Steuerhinterziehung. Problem: Keine dominante Strategie/kein Nash-Gleichgewicht in reinen Strategien. Wie ändert sich die Situation für den Fall $s > 200$ Mio. CHF?
$$
\begin{array}{c|cc}
& K & S \\
\hline
P & (200, 0) & (200 - s, 0.05 \cdot s - 10) \\
S & (0, 0) & (0, -10)
\end{array}
$$
## Gruppenentscheidungen: Relationen und Präferenzen
Idee: Beschreibung von Beziehungen (z.B. Rangfolgen, Präferenzen) zwischen Elementen. Darstellung als Relation $R$ auf Paaren $(x, y)$ von Elementen aus $A$. Formal geschrieben als $(x, y) \in R$ oder abkürzend als $xRy$. Beispiel: Mit $R$ ist $<$ (kleiner) und $xRy$ folgt $x < y$. Rangabbildungen definieren eine Präferenzrelation: $x \rho y \iff r(x) < r(y)$. Relation $\rho$ ist transitiv und asymmetrisch. Die Menge aller (möglichen) darstellbaren Relationen auf $A$ ist definiert als $P_A := \{\rho \subset A \times A: \rho \text{ erfüllt } x \rho y \iff r(x) < r(y) \text{ für eine Rangabbildung } r\}$. Erweiterung der Relation durch alle Paare mit gleichem Rang: $x \rho^* y \iff r(x) \le r(y)$. Relation $\rho^*$ ist transitiv und reflexiv. Es gilt offensichtlich $\rho \subset \rho^*$. Analog zur Menge $P_A$ lässt sich damit definieren $P_A^* := \{\rho^* \subset A \times A: \rho^* \text{ erfüllt } x \rho^* y \iff r(x) \le r(y) \text{ für eine Rangabbildung } r\}$. Beispiel: $A = \{x, y, z\}$, $r(x) = 1$, $r(y) = r(z) = 2$. Zwischen beiden Relationen gilt folgende Beziehung: $x \rho y \iff \neg(y \rho^* x)$. Rangabbildungen sind vor allem für
## Gruppenentscheidungen: Entscheidungsverfahren
Entscheidungsverfahren (Fortsetzung): Extrembeispiel 1: externer Diktator. Für beliebiges $\rho_E \in P_A$ gilt… Das Ergebnis ist offensichtlich eine Abbildung $P_A \to P_A$, aber unabhängig von den $\rho_i$. Das Verfahren kann kaum als „gerecht“ oder „demokratisch“ bezeichnet werden. Extrembeispiel 2: interner Diktator. Festlegung eines Individuums $d \in I$, dessen Präferenz $\rho_d$ das Ergebnis bestimmt. Damit gilt… Rangaddition: Beispiel: $I = \{1, 2\}$, $A = \{x, y, z\}$. Es folgt $x \rho y$, $y \rho z$ und $z \rho x$. Aus der Transitivität folgt schließlich $x \rho x \to$ kein gültiges Ergebnis, d.h. $\rho \notin P_A$. Einstimmigkeit: Element $x$ wird Element $y$ vorgezogen $\iff$ alle Individuen teilen diese Präferenz für alle. ABER: Ein einziges Individuum, das $y$… Die Rangfolge zwischen zwei Wahlmöglichkeiten kann nicht durch Präferenzänderungen der Individuen im Hinblick auf eine dritte Wahlmöglichkeit gekippt werden. Problem: Bereits mit diesen zwei Forderungen ist kein annähernd demokratisches Verfahren mehr möglich (Satz von Arrow). Quintessenz: Demokratie funktioniert nicht…? Bedingungen an Auswahlverfahren: Möglichkeit $z$ soll keinen Einfluss auf das Ergebnis haben. Oder formal: Wenn kein Individuum Präferenz $\rho_i, \rho_i' \in P_A$ bzgl. $x$ und $y$ ändert, soll gelten (für alle) $\implies$ (). Rangaddition somit als „gerechtes“ Verfahren ausgeschlossen. Condorcet-Verfahren und Einstimmigkeit liefern für $|A| > 2$ evtl. ein ungültiges Ergebnis. Nur interner Diktator $K_d$ erfüllt alle Bedingungen. Der Diktator ist „großzügiger“ gegenüber anderen Gruppenmitgliedern. Bei Indifferenz (es gilt weder $x \rho_d y$ noch $y \rho_d x$) sind beliebige Rangfolgen von $x, y$ zulässig. US-Wahlen haben nur zwei Kandidaten.
---
## Game Theory Introduction
# Einführung in die Spieltheorie (CDS-1012) HS 2024 Prof. Dr. rer. nat. habil. Ralf-Peter Mundani DAViS
**R.-P. Mundani, ICS, HS 2024 Einleitung**
* Überblick
* Einführung in die Spieltheorie
* Modellierung und Definitionen
* Spiele in reinen Strategien
* Nash-Gleichgewicht und dominante Strategien
* Zwei-Personen-Nullsummenspiele
* Konservative Strategien
* Spiele in gemischten Strategien
* Berechnung von Sattelpunkten
* Mehrheitsbeschlüsse / Gruppenentscheidungen (→ Teil 2)
**R.-P. Mundani, ICS, HS 2024 Motivation aus der Stochastik: Ziegenproblem (a.k.a. Monty-Hall-Dilemma)**
* Spielshow: 3 Türen zwei Nieten (Ziege) und ein Gewinn (Auto)
* SpielerIn wählt Tür, ShowmasterIn öffnet andere Tür (Ziege) Strategie: Wahl ändern…?
* Die anderen beiden Fälle (SpielerIn wählt Tür B oder C) sind symmetrisch
* In drei Fällen (3/9) Verlust, in sechs Fällen (6/9) Gewinn Wahl ändern 
* Quellen: depositphotos.com, jamara.com
**R.-P. Mundani, ICS, HS 2024 Einführung in die Spieltheorie**
* Grundlagen
* Definition: Spieltheorie
* Teilgebiet der Mathematik („Theorie des strategischen Denkens“)
* Modellierung von Entscheidungssituationen
**R.-P. Mundani, ICS, HS 2024 Spiele in reinen Strategien**
* Gefangenendilemma (das wohl bekannteste nicht-kooperative Spiel in reinen Strategien)
* Hintergrund
* Zwei Gefangene werden beschuldigt, gemeinsam ein Verbrechen verübt zu haben
* Beide Gefangenen werden getrennt vernommen und können nicht kommunizieren
* Mangels konkreter Beweise kann beiden nur ein Teil der Tat nachgewiesen werden
* Mögliche Aktionen:
* Leugnen (L): niedrige Strafe (2 Jahre)
* Gestehen (G): hohe Strafe (5 Jahre) oder Höchststrafe (8 Jahre ➡Kronzeugenregel)
* Maximierung der Auszahlung
* Funktion $u_i$ modelliert den Gewinn an Freiheit (also Höchststrafe tatsächlicher Strafe)
**R.-P. Mundani, ICS, HS 2024 Spiele in reinen Strategien (Fortsetzung)**
* Darstellung in Normalform (bei zwei SpielerInnen auch Bimatrixform genannt)
* Frage: Wie finden beide SpielerInnen die für sich beste Strategie…?
$$
\begin{array}{c|cc}
& G & L \\
\hline
G & (6, 6) & (8, 0) \\
L & (0, 8) & (3, 3) \\
\end{array}
$$
$A_1 A_2 (u_1, u_2)$
**R.-P. Mundani, ICS, HS 2024 Spiele in reinen Strategien**
* Ein bisschen Mathematik 
* Nash-Gleichgewicht
* Ein Aktionsprofil ist ein Nash-Gleichgewicht, wenn kein Spieler durch einseitige Änderung seiner Strategie seinen Nutzen verbessern kann.
* Wenn eine Strategie $a_i$ für alle möglichen Strategien des Gegners einen höheren Nutzen liefert als eine andere Strategie $a_i$, dann wird von starker Dominanz gesprochen, d.h. Strategie $a_i$ ist stark dominant über Strategie $a_i$.
* Profile dominanter Strategien führen zu Nash-Gleichgewichten (Umkehrung nicht gültig).
* Nochmals Frage: Was bedeutet das für das Gefangenendilemma…?
**R.-P. Mundani, ICS, HS 2024 Spiele in reinen Strategien**
* Ein bisschen Mathematik (Fortsetzung)
* Stark dominante Strategie beider SpielerInnen ist G
**R.-P. Mundani, ICS, HS 2024 Spiele in reinen Strategien**
* Übung: Steuerhinterziehung (Fortsetzung)
* Zanoma, ein fiktives Unternehmen, hat im Jahr 2023 durch kreative Buchführung 200M CHF nicht versteuert.
* Wird Zanoma durch einen privaten Steuerprüfer die Steuerhinterziehung nachgewiesen, so muss das Unternehmen eine Nachzahlung von $s$ Millionen CHF (Steuer plus Busse) leisten.
* Steuerprüfer bekommt im Erfolgsfall 5% der Nachzahlung als Prämie.
* Steuerprüfer hat Strategien Prüfung (P; Kosten: 10M CHF) und keine Prüfung (KP; Kosten: 0).
* Zanoma hat Strategien Steuerhinterziehung (S) und keine Steuerhinterziehung (KS).
* Fragen:
* a) Wie sieht die dargestellte Situation als Spiel in Bimatrixform aus…?
* b) Gibt es für $s < 200$M CHF dominante Strategien und Nash-Gleichgewichte?
* Jede Ähnlichkeit mit real existierenden Unternehmen ist rein zufällig.
**R.-P. Mundani, ICS, HS 2024 Spiele in reinen Strategien**
* Konservative Strategien
* In Zwei-Personen-Nullsummenspielen (2PNS) wählt man Strategien, die im ungünstigsten Fall die beste Auszahlung garantieren.
* MinimiererIn P1: $U^- = \text{minimax}_{i,j} a_{ij}$
* Für jede Strategie $i$: Maximiere über alle Spalten $j$ (➡größtmöglicher Verlust)
* Wähle Minimum aller Spaltenmaxima ➡konservative Strategie $i^*$ (Obergrenze $U^-$)
* MaximiererIn P2: $U^+ = \text{max}_j \text{min}_i a_{ij}$
* Für jede Strategie $j$: Minimiere über alle Zeilen $i$ (➡kleinstmöglicher Gewinn)
* Wähle Maximum aller Zeilenminima ➡konservative Strategie $j^*$ (Untergrenze $U^+$)
* Minimax-Theorem: 2PNS-Spiele in gemischten Strategien haben immer einen Sattelpunkt.
**R.-P. Mundani, ICS, HS 2024 Spiele in gemischten Strategien**
* Einführung von Wahrscheinlichkeiten
* SpielerIn P1: Spielt mit Wahrscheinlichkeit $p$ Strategie $S_{11}$ und mit $1-p$ Strategie $S_{12}$.
* SpielerIn P2: Spielt mit Wahrscheinlichkeit $q$ Strategie $S_{21}$ und mit $1-q$ Strategie $S_{22}$.
* Für den Fall $n > 2$ Strategien: Wahrscheinlichkeiten $p_1, p_2, \dots, p_n$ je Strategie mit $\sum_{i=1}^n p_i = 1$.
* Bestimmung des Sattelpunkts
* Multiplizieren des 2PNS-Spiels mit $p$ und $q$:
$$
\begin{pmatrix} p & 1-p \end{pmatrix}
\begin{pmatrix} a_{11} & a_{12} \\ a_{21} & a_{22} \end{pmatrix}
\begin{pmatrix} q \\ 1-q \end{pmatrix}
$$
**R.-P. Mundani, ICS, HS 2024 Spiele in gemischten Strategien**
* Nochmals Aufgabe: Steuerhinterziehung (Fortsetzung)
* Aus Sicht von Zanoma: $(200 - s) \cdot q + 200 \cdot (1 - q) = 0 \cdot q + 0 \cdot (1 - q) \iff q = 200/s$
* Aus Sicht des Steuerprüfers: $(0.05 \cdot s - 10) \cdot p - 10 \cdot (1 - p) = 0 \cdot p + 0 \cdot (1 - p) \iff p = 200/s$
* D.h. Nash-Gleichgewicht in gemischten Strategien somit für $p = q$, d.h. für $(200/s, 200/s)$.
* In anderen Worten: Höhere Nachzahlungen (Bussen) senken die Wahrscheinlichkeit einer Steuerprüfung.
**R.-P. Mundani, ICS, HS 2024 Gruppenentscheidungen**
* Satz von Arrow
* Mit $|A| > 2$ sei eine Menge von Auswahlmöglichkeiten.
* $K: P^A \to P^A$ sei kollektive Auswahlfunktion, die Pareto-Bedingung und Unabhängigkeit von irrelevanten Alternativen erfüllt.
* Dann existiert immer ein Diktator: Es gibt ein $d \in I$: Für alle $(\rho_1, \dots, \rho_n) \in P^A$: Für alle $(x, y) \in A \times A$: $x \rho_d y \implies x \rho y$.
* ABER: Diktator ist „großzügiger“ gegenüber anderen.
---
## Game Theory Basics
Nicht-kooperative Spiele zeichnen sich dadurch aus, dass alle Spieler ihre Auszahlung maximieren, indem sie ihre beste Strategie wählen basierend auf ihrem Wissen über die Strategien der anderen. Vereinbarungen zwischen den SpielerInnen gibt es keine. Im Gegensatz dazu stehen kooperative Spiele: Hier suchen alle SpielerInnen nach gemeinsamen Aktionen, die optimal für die Gruppe sind. Vor dem Spiel können Absprachen getroffen werden. Die Unterscheidung zwischen diesen beiden Spieltypen liegt also in der Möglichkeit zur Kooperation und der damit verbundenen Vereinbarung gemeinsamer Strategien.
---
## Game Theory Strategies
Mixed Strategies Nash
Group Decision Rankings
Group Decision Preferences
Group Decision Methods
# Spieltheorie und Gruppenentscheidungen
Vorhersehbarkeit durch Mitspieler*innen ist beispielsweise bei der Schere-Stein-Papier-Variante gegeben: Schere (100%), Stein (0%), Papier (0%). Gemischte Strategien hingegen entstehen, wenn eine Spielerin zufällig zwischen Strategien entscheidet. Formal wird dies durch eine Wahrscheinlichkeitsfunktion über (reinen) Strategien charakterisiert. Ein Beispiel wäre: Schere (25%), Stein (50%), Papier (25%). Reine Strategien führen jedoch häufig nicht zu Nash-Gleichgewichten. Nicht jedes Zwei-Personen-Nullsummenspiel (2PNS-Spiel) in reinen Strategien hat einen Sattelpunkt. Betrachten wir beispielsweise die folgende Auszahlungsmatrix:
$$
\begin{array}{c|cc}
& S_{21} & S_{22} \\
\hline
S_{11} & 3 & -1 \\
S_{12} & -1 & 5 \\
\end{array}
$$
$\min_i \max_j \rightarrow i^* = S_{11}$ und $U^- = 3$, $\max_j \min_i \rightarrow j^* = S_{22}$ und $U^+ = 1$. Zwei-Personen-Nullsummenspiele in gemischten Strategien haben immer einen Sattelpunkt. Das Min-Max-Theorem wird hier erneut relevant.
Gruppenentscheidungen basieren auf Präferenzen und Entscheidungsverfahren. Situationen mit unerwünschten Ergebnissen sind jedoch in der Regel nicht vermeidbar. Wir betrachten eine endliche Menge $A$ von Möglichkeiten (z.B. Kandidat*innen, Pläne). Präferenzen entstehen durch die Vergabe von Rangnummern $r(x)$ mit $x \in A$. Für zwei Möglichkeiten $x, y \in A$ bedeutet $r(x) < r(y)$, dass $x$ gegenüber $y$ bevorzugt wird. Zwei (oder mehr) Möglichkeiten können dieselbe Rangnummer erhalten. Eine Rangabbildung $r: A \to P$ ist eine surjektive Abbildung der Menge der Möglichkeiten $A$ auf eine Menge von Präferenzen $P = \{1, \dots, k\} \subset \mathbb{N}$. Beispiel:
$A = \{x, y, z\}$, $P = \{1, 2\}$
$r(x) = 1$, $r(y) = r(z) = 2$.
Eigenschaften von Relationen sind Transitivität (aus $xRy$ und $yRz$ folgt $xRz$), Reflexivität ($xRx$ für alle $x \in A$), und Asymmetrie ($xRy$ und $yRx$ gelten niemals gleichzeitig). Transitive und reflexive Relationen werden auch Quasiordnungen genannt. Rangabbildungen eignen sich besonders für Visualisierungen (z.B. Fußballtabellen). $x \rho y \iff \neg(y \rho^* x)$.
Betrachten wir nun Entscheidungsverfahren. Die Menge der Wähler*innen $I = \{1, \dots, n\}$ besteht aus Individuen, die von 1 bis n durchnummeriert sind. Jede Wählerin hat eine persönliche Präferenz $P_A$. Gesucht ist eine kollektive Auswahlfunktion. Die Mehrheitsentscheidung (Condorcet-Verfahren) vergleicht im direkten Vergleich zweier Elemente $x, y \in A$ die Individuen $\{i \in I: x \rho_i y\}$, die $x$ bevorzugen, mit den Individuen $\{i \in I: y \rho_i x\}$, die $y$ bevorzugen. Das Condorcet-Verfahren zählt, wer mehr Vergleiche gewinnt. Für zwei Elemente $x, y$ gilt: $K_C(\rho_1, \dots, \rho_n)$ ist eine Relation $\rho$. Das Verfahren ist für beliebige $\rho$ durchführbar, aber die Relation $\rho$ ist im Fall von mehr als zwei Möglichkeiten nicht immer transitiv, d.h. $\rho$ ist keine zulässige Präferenzrelation aus $P_A$. Beispiel: $I = \{1, 2, 3\}$, $A = \{x, y, z\}$. Es folgt $x \rho y$, $y \rho z$ und $z \rho x$. Aus der Transitivität würde $x \rho z$ folgen, was jedoch nicht der Fall ist. Ein einziges Individuum, das $y$ mindestens so schätzt wie $x$ ($y \le x$), führt dazu, dass das Verfahren in der Praxis keine echten Präferenzen liefert (für $|A| > 2$, $\rho \notin P_A$).
Bedingungen an Auswahlverfahren umfassen die Pareto-Bedingung (Einstimmigkeit). Eine kollektive Auswahlfunktion $K: P_A \to P_A$ erfüllt die Pareto-Bedingung, wenn für alle $\rho_i \in P_A$ gilt: Für alle $x, y \in A$, wenn $x \rho_i y$ für alle $i$, dann $x \rho y$. Der externe Diktator scheidet somit aus, alle anderen Verfahren erfüllen die Bedingung. Die Unabhängigkeit von irrelevanten Alternativen fordert, dass die Platzierung einer dritten Möglichkeit $z$ keinen Einfluss auf die Rangordnung zwischen $x$ und $y$ haben sollte. Eine Präferenzänderung bei einem Individuum kann die kollektive Präferenz beeinflussen.
---
## Game Theory Basics
# Einführung in die Spieltheorie: Grundlagen und Anwendungen
Die Spieltheorie modelliert Entscheidungssituationen, oft im Kontext sozialer Konflikte. Die zentrale Idee ist, dass der Erfolg nicht nur von den eigenen Entscheidungen, sondern auch von den Entscheidungen anderer abhängt. Wichtige Anwendungsgebiete finden sich in den Wirtschaftswissenschaften und der Ökonomie. Bekannte Vertreter sind John von Neumann und John Forbes Nash. Man unterscheidet zwischen kooperativen und nicht-kooperativen Spielen sowie simultanen und sequentiellen Spielen.
Entscheidungen können unter Gewissheit getroffen werden (alle Aktionen und Konsequenzen sind bekannt), unter Risiko (bestimmte Wahrscheinlichkeiten von Aktionen und Konsequenzen sind bekannt) oder unter Unsicherheit (keine Aktionen und Konsequenzen sind bekannt). Die Modellierung umfasst eine Menge von SpielerInnen $N = \{1, 2, \dots, n\}$, eine Menge der Aktionen (auch Strategien genannt) $A_i$ von SpielerIn $i$ für alle $i \in N$, und eine Menge der Aktionsprofile (auch Strategieprofile) $A = \{(a_i)_{i \in N}, a_i \in A_i \text{ für alle } i \in N\}$. Die Auszahlungsfunktion $u_i: A \to \mathbb{R}$ beschreibt die Auszahlung für SpielerIn $i$. Ein Beispiel: Die Entscheidung zwischen zwei Möglichkeiten mit Aktionen $A_1 = \{X, Y\}$ und ...
Ein Nash-Gleichgewicht liegt vor, wenn kein Spieler durch einseitige Abweichung von seiner Entscheidung eine höhere Auszahlung erzielen kann, während alle anderen SpielerInnen an ihren Entscheidungen festhalten. Formal: Ein Aktionsprofil bildet genau dann ein Nash-Gleichgewicht, wenn keine der SpielerInnen durch Abweichung davon eine höhere Auszahlung erhält.
Zwei-Personen-Nullsummenspiele zeichnen sich dadurch aus, dass der Gewinn einer SpielerIn dem Verlust der anderen entspricht (die Summe ist immer null). Ein Beispiel ist das Spiel "Chicken" (Hühner-Spiel), bei dem zwei SpielerInnen (z.B. mit Autos) sich auf einer Kollisionskurs befinden und unabhängig voneinander entscheiden, ob sie ausweichen oder nicht (d.h. "hartnäckiges" Verhalten). Die USA nutzten dieses Spielmodell für strategische Analysen während der Kuba-Krise. Das Spiel wird interessant, wenn die Kosten für den Kampf ($C$) die Kosten bzw. den Wert des Sieges ($V$) überschreiten, d.h. $C > V > 0$.
Als Übung betrachten wir Steuerhinterziehung. Ein Unternehmen, Zanoma, hat durch kreative Buchführung 200 Millionen CHF nicht versteuert. Falls $s < 200$, gilt $200 - s > 0$, und "S" (Steuerhinterziehung) ist eine strikt dominante Strategie. Falls $s < 200$, gilt $0.05 \cdot s - 10 < 0$, und "KP" (keine Prüfung) ist eine strikt dominante Strategie.
Spiele in gemischten Strategien können alternativ als reine Strategien aus der jeweiligen Sicht von SpielerIn P1 und P2 berechnet werden. Ein Sattelpunkt beschreibt einen Gleichgewichtspunkt. Die Darstellung in Matrixform ermöglicht die Analyse konservativer Strategien (MinimiererIn/MaximiererIn).
Gruppenentscheidungen befassen sich mit der Bestimmung einer Rangfolge von Möglichkeiten (z.B. Wahlen, Wettbewerbe). Nicht alle Beteiligten werden mit der Rangfolge einverstanden sein. Ein axiomatischer Ansatz stellt Eigenschaften auf und prüft, welche Entscheidungsverfahren diese erfüllen. Die Modellierung individueller Präferenzen und der Entscheidungsverfahren selbst ist zentral. Bedingungen an Auswahlverfahren beinhalten die Unabhängigkeit von irrelevanten Alternativen.

View File

@ -0,0 +1,15 @@
[project]
name = "pipeline-example"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"dotenv>=0.9.9",
"google>=3.0.0",
"google-genai>=1.11.0",
"numpy>=2.2.4",
"pypdf>=5.4.0",
"scikit-learn>=1.6.1",
"sentence-transformers>=4.1.0",
]

941
Code/pipeline-example/uv.lock generated Normal file
View File

@ -0,0 +1,941 @@
version = 1
revision = 1
requires-python = ">=3.13"
[[package]]
name = "annotated-types"
version = "0.7.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 },
]
[[package]]
name = "anyio"
version = "4.9.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "idna" },
{ name = "sniffio" },
]
sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916 },
]
[[package]]
name = "beautifulsoup4"
version = "4.13.4"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "soupsieve" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/d8/e4/0c4c39e18fd76d6a628d4dd8da40543d136ce2d1752bd6eeeab0791f4d6b/beautifulsoup4-4.13.4.tar.gz", hash = "sha256:dbb3c4e1ceae6aefebdaf2423247260cd062430a410e38c66f2baa50a8437195", size = 621067 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/50/cd/30110dc0ffcf3b131156077b90e9f60ed75711223f306da4db08eff8403b/beautifulsoup4-4.13.4-py3-none-any.whl", hash = "sha256:9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b", size = 187285 },
]
[[package]]
name = "cachetools"
version = "5.5.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/6c/81/3747dad6b14fa2cf53fcf10548cf5aea6913e96fab41a3c198676f8948a5/cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4", size = 28380 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/72/76/20fa66124dbe6be5cafeb312ece67de6b61dd91a0247d1ea13db4ebb33c2/cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a", size = 10080 },
]
[[package]]
name = "certifi"
version = "2025.1.31"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393 },
]
[[package]]
name = "charset-normalizer"
version = "3.4.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698 },
{ url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162 },
{ url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263 },
{ url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966 },
{ url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992 },
{ url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162 },
{ url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972 },
{ url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095 },
{ url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668 },
{ url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073 },
{ url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732 },
{ url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391 },
{ url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702 },
{ url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 },
]
[[package]]
name = "colorama"
version = "0.4.6"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
]
[[package]]
name = "dotenv"
version = "0.9.9"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "python-dotenv" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/b2/b7/545d2c10c1fc15e48653c91efde329a790f2eecfbbf2bd16003b5db2bab0/dotenv-0.9.9-py2.py3-none-any.whl", hash = "sha256:29cf74a087b31dafdb5a446b6d7e11cbce8ed2741540e2339c69fbef92c94ce9", size = 1892 },
]
[[package]]
name = "filelock"
version = "3.18.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/0a/10/c23352565a6544bdc5353e0b15fc1c563352101f30e24bf500207a54df9a/filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2", size = 18075 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/4d/36/2a115987e2d8c300a974597416d9de88f2444426de9571f4b59b2cca3acc/filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de", size = 16215 },
]
[[package]]
name = "fsspec"
version = "2025.3.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/45/d8/8425e6ba5fcec61a1d16e41b1b71d2bf9344f1fe48012c2b48b9620feae5/fsspec-2025.3.2.tar.gz", hash = "sha256:e52c77ef398680bbd6a98c0e628fbc469491282981209907bbc8aea76a04fdc6", size = 299281 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/44/4b/e0cfc1a6f17e990f3e64b7d941ddc4acdc7b19d6edd51abf495f32b1a9e4/fsspec-2025.3.2-py3-none-any.whl", hash = "sha256:2daf8dc3d1dfa65b6aa37748d112773a7a08416f6c70d96b264c96476ecaf711", size = 194435 },
]
[[package]]
name = "google"
version = "3.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "beautifulsoup4" },
]
sdist = { url = "https://files.pythonhosted.org/packages/89/97/b49c69893cddea912c7a660a4b6102c6b02cd268f8c7162dd70b7c16f753/google-3.0.0.tar.gz", hash = "sha256:143530122ee5130509ad5e989f0512f7cb218b2d4eddbafbad40fd10e8d8ccbe", size = 44978 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ac/35/17c9141c4ae21e9a29a43acdfd848e3e468a810517f862cad07977bf8fe9/google-3.0.0-py2.py3-none-any.whl", hash = "sha256:889cf695f84e4ae2c55fbc0cfdaf4c1e729417fa52ab1db0485202ba173e4935", size = 45258 },
]
[[package]]
name = "google-auth"
version = "2.39.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cachetools" },
{ name = "pyasn1-modules" },
{ name = "rsa" },
]
sdist = { url = "https://files.pythonhosted.org/packages/cb/8e/8f45c9a32f73e786e954b8f9761c61422955d23c45d1e8c347f9b4b59e8e/google_auth-2.39.0.tar.gz", hash = "sha256:73222d43cdc35a3aeacbfdcaf73142a97839f10de930550d89ebfe1d0a00cde7", size = 274834 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ce/12/ad37a1ef86006d0a0117fc06a4a00bd461c775356b534b425f00dde208ea/google_auth-2.39.0-py2.py3-none-any.whl", hash = "sha256:0150b6711e97fb9f52fe599f55648950cc4540015565d8fbb31be2ad6e1548a2", size = 212319 },
]
[[package]]
name = "google-genai"
version = "1.11.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
{ name = "google-auth" },
{ name = "httpx" },
{ name = "pydantic" },
{ name = "requests" },
{ name = "typing-extensions" },
{ name = "websockets" },
]
sdist = { url = "https://files.pythonhosted.org/packages/73/44/64c6c23724580add879cbcca81ffed500955c1c21850468cd4dcf9c62a03/google_genai-1.11.0.tar.gz", hash = "sha256:0643b2f5373fbeae945d0cd5a37d157eab0c172bb5e14e905f2f8d45aa51cabb", size = 160955 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/dc/9b/55f97203720cbda5a1c8e0460793914980e41c6ca4859fea735dd66d2c3a/google_genai-1.11.0-py3-none-any.whl", hash = "sha256:34fbe3c85419adbcddcb8222f99514596b3a69c80ff1a4ae30a01a763da27acc", size = 159687 },
]
[[package]]
name = "h11"
version = "0.14.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 },
]
[[package]]
name = "httpcore"
version = "1.0.8"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "certifi" },
{ name = "h11" },
]
sdist = { url = "https://files.pythonhosted.org/packages/9f/45/ad3e1b4d448f22c0cff4f5692f5ed0666658578e358b8d58a19846048059/httpcore-1.0.8.tar.gz", hash = "sha256:86e94505ed24ea06514883fd44d2bc02d90e77e7979c8eb71b90f41d364a1bad", size = 85385 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/18/8d/f052b1e336bb2c1fc7ed1aaed898aa570c0b61a09707b108979d9fc6e308/httpcore-1.0.8-py3-none-any.whl", hash = "sha256:5254cf149bcb5f75e9d1b2b9f729ea4a4b883d1ad7379fc632b727cec23674be", size = 78732 },
]
[[package]]
name = "httpx"
version = "0.28.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
{ name = "certifi" },
{ name = "httpcore" },
{ name = "idna" },
]
sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 },
]
[[package]]
name = "huggingface-hub"
version = "0.30.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "filelock" },
{ name = "fsspec" },
{ name = "packaging" },
{ name = "pyyaml" },
{ name = "requests" },
{ name = "tqdm" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/df/22/8eb91736b1dcb83d879bd49050a09df29a57cc5cd9f38e48a4b1c45ee890/huggingface_hub-0.30.2.tar.gz", hash = "sha256:9a7897c5b6fd9dad3168a794a8998d6378210f5b9688d0dfc180b1a228dc2466", size = 400868 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/93/27/1fb384a841e9661faad1c31cbfa62864f59632e876df5d795234da51c395/huggingface_hub-0.30.2-py3-none-any.whl", hash = "sha256:68ff05969927058cfa41df4f2155d4bb48f5f54f719dd0390103eefa9b191e28", size = 481433 },
]
[[package]]
name = "idna"
version = "3.10"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
]
[[package]]
name = "jinja2"
version = "3.1.6"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "markupsafe" },
]
sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 },
]
[[package]]
name = "joblib"
version = "1.4.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/64/33/60135848598c076ce4b231e1b1895170f45fbcaeaa2c9d5e38b04db70c35/joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e", size = 2116621 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/91/29/df4b9b42f2be0b623cbd5e2140cafcaa2bef0759a00b7b70104dcfe2fb51/joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6", size = 301817 },
]
[[package]]
name = "markupsafe"
version = "3.0.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274 },
{ url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352 },
{ url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122 },
{ url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085 },
{ url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978 },
{ url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208 },
{ url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357 },
{ url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344 },
{ url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101 },
{ url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603 },
{ url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510 },
{ url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486 },
{ url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480 },
{ url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914 },
{ url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796 },
{ url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473 },
{ url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114 },
{ url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098 },
{ url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208 },
{ url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 },
]
[[package]]
name = "mpmath"
version = "1.3.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198 },
]
[[package]]
name = "networkx"
version = "3.4.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/fd/1d/06475e1cd5264c0b870ea2cc6fdb3e37177c1e565c43f56ff17a10e3937f/networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1", size = 2151368 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b9/54/dd730b32ea14ea797530a4479b2ed46a6fb250f682a9cfb997e968bf0261/networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f", size = 1723263 },
]
[[package]]
name = "numpy"
version = "2.2.4"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/e1/78/31103410a57bc2c2b93a3597340a8119588571f6a4539067546cb9a0bfac/numpy-2.2.4.tar.gz", hash = "sha256:9ba03692a45d3eef66559efe1d1096c4b9b75c0986b5dff5530c378fb8331d4f", size = 20270701 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2a/d0/bd5ad792e78017f5decfb2ecc947422a3669a34f775679a76317af671ffc/numpy-2.2.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cf4e5c6a278d620dee9ddeb487dc6a860f9b199eadeecc567f777daace1e9e7", size = 20933623 },
{ url = "https://files.pythonhosted.org/packages/c3/bc/2b3545766337b95409868f8e62053135bdc7fa2ce630aba983a2aa60b559/numpy-2.2.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1974afec0b479e50438fc3648974268f972e2d908ddb6d7fb634598cdb8260a0", size = 14148681 },
{ url = "https://files.pythonhosted.org/packages/6a/70/67b24d68a56551d43a6ec9fe8c5f91b526d4c1a46a6387b956bf2d64744e/numpy-2.2.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:79bd5f0a02aa16808fcbc79a9a376a147cc1045f7dfe44c6e7d53fa8b8a79392", size = 5148759 },
{ url = "https://files.pythonhosted.org/packages/1c/8b/e2fc8a75fcb7be12d90b31477c9356c0cbb44abce7ffb36be39a0017afad/numpy-2.2.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:3387dd7232804b341165cedcb90694565a6015433ee076c6754775e85d86f1fc", size = 6683092 },
{ url = "https://files.pythonhosted.org/packages/13/73/41b7b27f169ecf368b52533edb72e56a133f9e86256e809e169362553b49/numpy-2.2.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f527d8fdb0286fd2fd97a2a96c6be17ba4232da346931d967a0630050dfd298", size = 14081422 },
{ url = "https://files.pythonhosted.org/packages/4b/04/e208ff3ae3ddfbafc05910f89546382f15a3f10186b1f56bd99f159689c2/numpy-2.2.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bce43e386c16898b91e162e5baaad90c4b06f9dcbe36282490032cec98dc8ae7", size = 16132202 },
{ url = "https://files.pythonhosted.org/packages/fe/bc/2218160574d862d5e55f803d88ddcad88beff94791f9c5f86d67bd8fbf1c/numpy-2.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31504f970f563d99f71a3512d0c01a645b692b12a63630d6aafa0939e52361e6", size = 15573131 },
{ url = "https://files.pythonhosted.org/packages/a5/78/97c775bc4f05abc8a8426436b7cb1be806a02a2994b195945600855e3a25/numpy-2.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:81413336ef121a6ba746892fad881a83351ee3e1e4011f52e97fba79233611fd", size = 17894270 },
{ url = "https://files.pythonhosted.org/packages/b9/eb/38c06217a5f6de27dcb41524ca95a44e395e6a1decdc0c99fec0832ce6ae/numpy-2.2.4-cp313-cp313-win32.whl", hash = "sha256:f486038e44caa08dbd97275a9a35a283a8f1d2f0ee60ac260a1790e76660833c", size = 6308141 },
{ url = "https://files.pythonhosted.org/packages/52/17/d0dd10ab6d125c6d11ffb6dfa3423c3571befab8358d4f85cd4471964fcd/numpy-2.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:207a2b8441cc8b6a2a78c9ddc64d00d20c303d79fba08c577752f080c4007ee3", size = 12636885 },
{ url = "https://files.pythonhosted.org/packages/fa/e2/793288ede17a0fdc921172916efb40f3cbc2aa97e76c5c84aba6dc7e8747/numpy-2.2.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8120575cb4882318c791f839a4fd66161a6fa46f3f0a5e613071aae35b5dd8f8", size = 20961829 },
{ url = "https://files.pythonhosted.org/packages/3a/75/bb4573f6c462afd1ea5cbedcc362fe3e9bdbcc57aefd37c681be1155fbaa/numpy-2.2.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a761ba0fa886a7bb33c6c8f6f20213735cb19642c580a931c625ee377ee8bd39", size = 14161419 },
{ url = "https://files.pythonhosted.org/packages/03/68/07b4cd01090ca46c7a336958b413cdbe75002286295f2addea767b7f16c9/numpy-2.2.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:ac0280f1ba4a4bfff363a99a6aceed4f8e123f8a9b234c89140f5e894e452ecd", size = 5196414 },
{ url = "https://files.pythonhosted.org/packages/a5/fd/d4a29478d622fedff5c4b4b4cedfc37a00691079623c0575978d2446db9e/numpy-2.2.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:879cf3a9a2b53a4672a168c21375166171bc3932b7e21f622201811c43cdd3b0", size = 6709379 },
{ url = "https://files.pythonhosted.org/packages/41/78/96dddb75bb9be730b87c72f30ffdd62611aba234e4e460576a068c98eff6/numpy-2.2.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f05d4198c1bacc9124018109c5fba2f3201dbe7ab6e92ff100494f236209c960", size = 14051725 },
{ url = "https://files.pythonhosted.org/packages/00/06/5306b8199bffac2a29d9119c11f457f6c7d41115a335b78d3f86fad4dbe8/numpy-2.2.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f085ce2e813a50dfd0e01fbfc0c12bbe5d2063d99f8b29da30e544fb6483b8", size = 16101638 },
{ url = "https://files.pythonhosted.org/packages/fa/03/74c5b631ee1ded596945c12027649e6344614144369fd3ec1aaced782882/numpy-2.2.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:92bda934a791c01d6d9d8e038363c50918ef7c40601552a58ac84c9613a665bc", size = 15571717 },
{ url = "https://files.pythonhosted.org/packages/cb/dc/4fc7c0283abe0981e3b89f9b332a134e237dd476b0c018e1e21083310c31/numpy-2.2.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ee4d528022f4c5ff67332469e10efe06a267e32f4067dc76bb7e2cddf3cd25ff", size = 17879998 },
{ url = "https://files.pythonhosted.org/packages/e5/2b/878576190c5cfa29ed896b518cc516aecc7c98a919e20706c12480465f43/numpy-2.2.4-cp313-cp313t-win32.whl", hash = "sha256:05c076d531e9998e7e694c36e8b349969c56eadd2cdcd07242958489d79a7286", size = 6366896 },
{ url = "https://files.pythonhosted.org/packages/3e/05/eb7eec66b95cf697f08c754ef26c3549d03ebd682819f794cb039574a0a6/numpy-2.2.4-cp313-cp313t-win_amd64.whl", hash = "sha256:188dcbca89834cc2e14eb2f106c96d6d46f200fe0200310fc29089657379c58d", size = 12739119 },
]
[[package]]
name = "nvidia-cublas-cu12"
version = "12.4.5.8"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ae/71/1c91302526c45ab494c23f61c7a84aa568b8c1f9d196efa5993957faf906/nvidia_cublas_cu12-12.4.5.8-py3-none-manylinux2014_x86_64.whl", hash = "sha256:2fc8da60df463fdefa81e323eef2e36489e1c94335b5358bcb38360adf75ac9b", size = 363438805 },
]
[[package]]
name = "nvidia-cuda-cupti-cu12"
version = "12.4.127"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/67/42/f4f60238e8194a3106d06a058d494b18e006c10bb2b915655bd9f6ea4cb1/nvidia_cuda_cupti_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:9dec60f5ac126f7bb551c055072b69d85392b13311fcc1bcda2202d172df30fb", size = 13813957 },
]
[[package]]
name = "nvidia-cuda-nvrtc-cu12"
version = "12.4.127"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2c/14/91ae57cd4db3f9ef7aa99f4019cfa8d54cb4caa7e00975df6467e9725a9f/nvidia_cuda_nvrtc_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a178759ebb095827bd30ef56598ec182b85547f1508941a3d560eb7ea1fbf338", size = 24640306 },
]
[[package]]
name = "nvidia-cuda-runtime-cu12"
version = "12.4.127"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ea/27/1795d86fe88ef397885f2e580ac37628ed058a92ed2c39dc8eac3adf0619/nvidia_cuda_runtime_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:64403288fa2136ee8e467cdc9c9427e0434110899d07c779f25b5c068934faa5", size = 883737 },
]
[[package]]
name = "nvidia-cudnn-cu12"
version = "9.1.0.70"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "nvidia-cublas-cu12" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/9f/fd/713452cd72343f682b1c7b9321e23829f00b842ceaedcda96e742ea0b0b3/nvidia_cudnn_cu12-9.1.0.70-py3-none-manylinux2014_x86_64.whl", hash = "sha256:165764f44ef8c61fcdfdfdbe769d687e06374059fbb388b6c89ecb0e28793a6f", size = 664752741 },
]
[[package]]
name = "nvidia-cufft-cu12"
version = "11.2.1.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "nvidia-nvjitlink-cu12" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/27/94/3266821f65b92b3138631e9c8e7fe1fb513804ac934485a8d05776e1dd43/nvidia_cufft_cu12-11.2.1.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f083fc24912aa410be21fa16d157fed2055dab1cc4b6934a0e03cba69eb242b9", size = 211459117 },
]
[[package]]
name = "nvidia-curand-cu12"
version = "10.3.5.147"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/8a/6d/44ad094874c6f1b9c654f8ed939590bdc408349f137f9b98a3a23ccec411/nvidia_curand_cu12-10.3.5.147-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a88f583d4e0bb643c49743469964103aa59f7f708d862c3ddb0fc07f851e3b8b", size = 56305206 },
]
[[package]]
name = "nvidia-cusolver-cu12"
version = "11.6.1.9"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "nvidia-cublas-cu12" },
{ name = "nvidia-cusparse-cu12" },
{ name = "nvidia-nvjitlink-cu12" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/3a/e1/5b9089a4b2a4790dfdea8b3a006052cfecff58139d5a4e34cb1a51df8d6f/nvidia_cusolver_cu12-11.6.1.9-py3-none-manylinux2014_x86_64.whl", hash = "sha256:19e33fa442bcfd085b3086c4ebf7e8debc07cfe01e11513cc6d332fd918ac260", size = 127936057 },
]
[[package]]
name = "nvidia-cusparse-cu12"
version = "12.3.1.170"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "nvidia-nvjitlink-cu12" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/db/f7/97a9ea26ed4bbbfc2d470994b8b4f338ef663be97b8f677519ac195e113d/nvidia_cusparse_cu12-12.3.1.170-py3-none-manylinux2014_x86_64.whl", hash = "sha256:ea4f11a2904e2a8dc4b1833cc1b5181cde564edd0d5cd33e3c168eff2d1863f1", size = 207454763 },
]
[[package]]
name = "nvidia-cusparselt-cu12"
version = "0.6.2"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/78/a8/bcbb63b53a4b1234feeafb65544ee55495e1bb37ec31b999b963cbccfd1d/nvidia_cusparselt_cu12-0.6.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:df2c24502fd76ebafe7457dbc4716b2fec071aabaed4fb7691a201cde03704d9", size = 150057751 },
]
[[package]]
name = "nvidia-nccl-cu12"
version = "2.21.5"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/df/99/12cd266d6233f47d00daf3a72739872bdc10267d0383508b0b9c84a18bb6/nvidia_nccl_cu12-2.21.5-py3-none-manylinux2014_x86_64.whl", hash = "sha256:8579076d30a8c24988834445f8d633c697d42397e92ffc3f63fa26766d25e0a0", size = 188654414 },
]
[[package]]
name = "nvidia-nvjitlink-cu12"
version = "12.4.127"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ff/ff/847841bacfbefc97a00036e0fce5a0f086b640756dc38caea5e1bb002655/nvidia_nvjitlink_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:06b3b9b25bf3f8af351d664978ca26a16d2c5127dbd53c0497e28d1fb9611d57", size = 21066810 },
]
[[package]]
name = "nvidia-nvtx-cu12"
version = "12.4.127"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/87/20/199b8713428322a2f22b722c62b8cc278cc53dffa9705d744484b5035ee9/nvidia_nvtx_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:781e950d9b9f60d8241ccea575b32f5105a5baf4c2351cab5256a24869f12a1a", size = 99144 },
]
[[package]]
name = "packaging"
version = "24.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 },
]
[[package]]
name = "pillow"
version = "11.2.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/af/cb/bb5c01fcd2a69335b86c22142b2bccfc3464087efb7fd382eee5ffc7fdf7/pillow-11.2.1.tar.gz", hash = "sha256:a64dd61998416367b7ef979b73d3a85853ba9bec4c2925f74e588879a58716b6", size = 47026707 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/36/9c/447528ee3776e7ab8897fe33697a7ff3f0475bb490c5ac1456a03dc57956/pillow-11.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fdec757fea0b793056419bca3e9932eb2b0ceec90ef4813ea4c1e072c389eb28", size = 3190098 },
{ url = "https://files.pythonhosted.org/packages/b5/09/29d5cd052f7566a63e5b506fac9c60526e9ecc553825551333e1e18a4858/pillow-11.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0e130705d568e2f43a17bcbe74d90958e8a16263868a12c3e0d9c8162690830", size = 3030166 },
{ url = "https://files.pythonhosted.org/packages/71/5d/446ee132ad35e7600652133f9c2840b4799bbd8e4adba881284860da0a36/pillow-11.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bdb5e09068332578214cadd9c05e3d64d99e0e87591be22a324bdbc18925be0", size = 4408674 },
{ url = "https://files.pythonhosted.org/packages/69/5f/cbe509c0ddf91cc3a03bbacf40e5c2339c4912d16458fcb797bb47bcb269/pillow-11.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d189ba1bebfbc0c0e529159631ec72bb9e9bc041f01ec6d3233d6d82eb823bc1", size = 4496005 },
{ url = "https://files.pythonhosted.org/packages/f9/b3/dd4338d8fb8a5f312021f2977fb8198a1184893f9b00b02b75d565c33b51/pillow-11.2.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:191955c55d8a712fab8934a42bfefbf99dd0b5875078240943f913bb66d46d9f", size = 4518707 },
{ url = "https://files.pythonhosted.org/packages/13/eb/2552ecebc0b887f539111c2cd241f538b8ff5891b8903dfe672e997529be/pillow-11.2.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:ad275964d52e2243430472fc5d2c2334b4fc3ff9c16cb0a19254e25efa03a155", size = 4610008 },
{ url = "https://files.pythonhosted.org/packages/72/d1/924ce51bea494cb6e7959522d69d7b1c7e74f6821d84c63c3dc430cbbf3b/pillow-11.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:750f96efe0597382660d8b53e90dd1dd44568a8edb51cb7f9d5d918b80d4de14", size = 4585420 },
{ url = "https://files.pythonhosted.org/packages/43/ab/8f81312d255d713b99ca37479a4cb4b0f48195e530cdc1611990eb8fd04b/pillow-11.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fe15238d3798788d00716637b3d4e7bb6bde18b26e5d08335a96e88564a36b6b", size = 4667655 },
{ url = "https://files.pythonhosted.org/packages/94/86/8f2e9d2dc3d308dfd137a07fe1cc478df0a23d42a6c4093b087e738e4827/pillow-11.2.1-cp313-cp313-win32.whl", hash = "sha256:3fe735ced9a607fee4f481423a9c36701a39719252a9bb251679635f99d0f7d2", size = 2332329 },
{ url = "https://files.pythonhosted.org/packages/6d/ec/1179083b8d6067a613e4d595359b5fdea65d0a3b7ad623fee906e1b3c4d2/pillow-11.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:74ee3d7ecb3f3c05459ba95eed5efa28d6092d751ce9bf20e3e253a4e497e691", size = 2676388 },
{ url = "https://files.pythonhosted.org/packages/23/f1/2fc1e1e294de897df39fa8622d829b8828ddad938b0eaea256d65b84dd72/pillow-11.2.1-cp313-cp313-win_arm64.whl", hash = "sha256:5119225c622403afb4b44bad4c1ca6c1f98eed79db8d3bc6e4e160fc6339d66c", size = 2414950 },
{ url = "https://files.pythonhosted.org/packages/c4/3e/c328c48b3f0ead7bab765a84b4977acb29f101d10e4ef57a5e3400447c03/pillow-11.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8ce2e8411c7aaef53e6bb29fe98f28cd4fbd9a1d9be2eeea434331aac0536b22", size = 3192759 },
{ url = "https://files.pythonhosted.org/packages/18/0e/1c68532d833fc8b9f404d3a642991441d9058eccd5606eab31617f29b6d4/pillow-11.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:9ee66787e095127116d91dea2143db65c7bb1e232f617aa5957c0d9d2a3f23a7", size = 3033284 },
{ url = "https://files.pythonhosted.org/packages/b7/cb/6faf3fb1e7705fd2db74e070f3bf6f88693601b0ed8e81049a8266de4754/pillow-11.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9622e3b6c1d8b551b6e6f21873bdcc55762b4b2126633014cea1803368a9aa16", size = 4445826 },
{ url = "https://files.pythonhosted.org/packages/07/94/8be03d50b70ca47fb434a358919d6a8d6580f282bbb7af7e4aa40103461d/pillow-11.2.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63b5dff3a68f371ea06025a1a6966c9a1e1ee452fc8020c2cd0ea41b83e9037b", size = 4527329 },
{ url = "https://files.pythonhosted.org/packages/fd/a4/bfe78777076dc405e3bd2080bc32da5ab3945b5a25dc5d8acaa9de64a162/pillow-11.2.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:31df6e2d3d8fc99f993fd253e97fae451a8db2e7207acf97859732273e108406", size = 4549049 },
{ url = "https://files.pythonhosted.org/packages/65/4d/eaf9068dc687c24979e977ce5677e253624bd8b616b286f543f0c1b91662/pillow-11.2.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:062b7a42d672c45a70fa1f8b43d1d38ff76b63421cbbe7f88146b39e8a558d91", size = 4635408 },
{ url = "https://files.pythonhosted.org/packages/1d/26/0fd443365d9c63bc79feb219f97d935cd4b93af28353cba78d8e77b61719/pillow-11.2.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4eb92eca2711ef8be42fd3f67533765d9fd043b8c80db204f16c8ea62ee1a751", size = 4614863 },
{ url = "https://files.pythonhosted.org/packages/49/65/dca4d2506be482c2c6641cacdba5c602bc76d8ceb618fd37de855653a419/pillow-11.2.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f91ebf30830a48c825590aede79376cb40f110b387c17ee9bd59932c961044f9", size = 4692938 },
{ url = "https://files.pythonhosted.org/packages/b3/92/1ca0c3f09233bd7decf8f7105a1c4e3162fb9142128c74adad0fb361b7eb/pillow-11.2.1-cp313-cp313t-win32.whl", hash = "sha256:e0b55f27f584ed623221cfe995c912c61606be8513bfa0e07d2c674b4516d9dd", size = 2335774 },
{ url = "https://files.pythonhosted.org/packages/a5/ac/77525347cb43b83ae905ffe257bbe2cc6fd23acb9796639a1f56aa59d191/pillow-11.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:36d6b82164c39ce5482f649b437382c0fb2395eabc1e2b1702a6deb8ad647d6e", size = 2681895 },
{ url = "https://files.pythonhosted.org/packages/67/32/32dc030cfa91ca0fc52baebbba2e009bb001122a1daa8b6a79ad830b38d3/pillow-11.2.1-cp313-cp313t-win_arm64.whl", hash = "sha256:225c832a13326e34f212d2072982bb1adb210e0cc0b153e688743018c94a2681", size = 2417234 },
]
[[package]]
name = "pipeline-example"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "dotenv" },
{ name = "google" },
{ name = "google-genai" },
{ name = "numpy" },
{ name = "pypdf" },
{ name = "scikit-learn" },
{ name = "sentence-transformers" },
]
[package.metadata]
requires-dist = [
{ name = "dotenv", specifier = ">=0.9.9" },
{ name = "google", specifier = ">=3.0.0" },
{ name = "google-genai", specifier = ">=1.11.0" },
{ name = "numpy", specifier = ">=2.2.4" },
{ name = "pypdf", specifier = ">=5.4.0" },
{ name = "scikit-learn", specifier = ">=1.6.1" },
{ name = "sentence-transformers", specifier = ">=4.1.0" },
]
[[package]]
name = "pyasn1"
version = "0.6.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135 },
]
[[package]]
name = "pyasn1-modules"
version = "0.4.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pyasn1" },
]
sdist = { url = "https://files.pythonhosted.org/packages/e9/e6/78ebbb10a8c8e4b61a59249394a4a594c1a7af95593dc933a349c8d00964/pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6", size = 307892 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a", size = 181259 },
]
[[package]]
name = "pydantic"
version = "2.11.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "annotated-types" },
{ name = "pydantic-core" },
{ name = "typing-extensions" },
{ name = "typing-inspection" },
]
sdist = { url = "https://files.pythonhosted.org/packages/10/2e/ca897f093ee6c5f3b0bee123ee4465c50e75431c3d5b6a3b44a47134e891/pydantic-2.11.3.tar.gz", hash = "sha256:7471657138c16adad9322fe3070c0116dd6c3ad8d649300e3cbdfe91f4db4ec3", size = 785513 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b0/1d/407b29780a289868ed696d1616f4aad49d6388e5a77f567dcd2629dcd7b8/pydantic-2.11.3-py3-none-any.whl", hash = "sha256:a082753436a07f9ba1289c6ffa01cd93db3548776088aa917cc43b63f68fa60f", size = 443591 },
]
[[package]]
name = "pydantic-core"
version = "2.33.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/17/19/ed6a078a5287aea7922de6841ef4c06157931622c89c2a47940837b5eecd/pydantic_core-2.33.1.tar.gz", hash = "sha256:bcc9c6fdb0ced789245b02b7d6603e17d1563064ddcfc36f046b61c0c05dd9df", size = 434395 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/7a/24/eed3466a4308d79155f1cdd5c7432c80ddcc4530ba8623b79d5ced021641/pydantic_core-2.33.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:70af6a21237b53d1fe7b9325b20e65cbf2f0a848cf77bed492b029139701e66a", size = 2033551 },
{ url = "https://files.pythonhosted.org/packages/ab/14/df54b1a0bc9b6ded9b758b73139d2c11b4e8eb43e8ab9c5847c0a2913ada/pydantic_core-2.33.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:282b3fe1bbbe5ae35224a0dbd05aed9ccabccd241e8e6b60370484234b456266", size = 1852785 },
{ url = "https://files.pythonhosted.org/packages/fa/96/e275f15ff3d34bb04b0125d9bc8848bf69f25d784d92a63676112451bfb9/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b315e596282bbb5822d0c7ee9d255595bd7506d1cb20c2911a4da0b970187d3", size = 1897758 },
{ url = "https://files.pythonhosted.org/packages/b7/d8/96bc536e975b69e3a924b507d2a19aedbf50b24e08c80fb00e35f9baaed8/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1dfae24cf9921875ca0ca6a8ecb4bb2f13c855794ed0d468d6abbec6e6dcd44a", size = 1986109 },
{ url = "https://files.pythonhosted.org/packages/90/72/ab58e43ce7e900b88cb571ed057b2fcd0e95b708a2e0bed475b10130393e/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6dd8ecfde08d8bfadaea669e83c63939af76f4cf5538a72597016edfa3fad516", size = 2129159 },
{ url = "https://files.pythonhosted.org/packages/dc/3f/52d85781406886c6870ac995ec0ba7ccc028b530b0798c9080531b409fdb/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f593494876eae852dc98c43c6f260f45abdbfeec9e4324e31a481d948214764", size = 2680222 },
{ url = "https://files.pythonhosted.org/packages/f4/56/6e2ef42f363a0eec0fd92f74a91e0ac48cd2e49b695aac1509ad81eee86a/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:948b73114f47fd7016088e5186d13faf5e1b2fe83f5e320e371f035557fd264d", size = 2006980 },
{ url = "https://files.pythonhosted.org/packages/4c/c0/604536c4379cc78359f9ee0aa319f4aedf6b652ec2854953f5a14fc38c5a/pydantic_core-2.33.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e11f3864eb516af21b01e25fac915a82e9ddad3bb0fb9e95a246067398b435a4", size = 2120840 },
{ url = "https://files.pythonhosted.org/packages/1f/46/9eb764814f508f0edfb291a0f75d10854d78113fa13900ce13729aaec3ae/pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:549150be302428b56fdad0c23c2741dcdb5572413776826c965619a25d9c6bde", size = 2072518 },
{ url = "https://files.pythonhosted.org/packages/42/e3/fb6b2a732b82d1666fa6bf53e3627867ea3131c5f39f98ce92141e3e3dc1/pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:495bc156026efafd9ef2d82372bd38afce78ddd82bf28ef5276c469e57c0c83e", size = 2248025 },
{ url = "https://files.pythonhosted.org/packages/5c/9d/fbe8fe9d1aa4dac88723f10a921bc7418bd3378a567cb5e21193a3c48b43/pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ec79de2a8680b1a67a07490bddf9636d5c2fab609ba8c57597e855fa5fa4dacd", size = 2254991 },
{ url = "https://files.pythonhosted.org/packages/aa/99/07e2237b8a66438d9b26482332cda99a9acccb58d284af7bc7c946a42fd3/pydantic_core-2.33.1-cp313-cp313-win32.whl", hash = "sha256:ee12a7be1742f81b8a65b36c6921022301d466b82d80315d215c4c691724986f", size = 1915262 },
{ url = "https://files.pythonhosted.org/packages/8a/f4/e457a7849beeed1e5defbcf5051c6f7b3c91a0624dd31543a64fc9adcf52/pydantic_core-2.33.1-cp313-cp313-win_amd64.whl", hash = "sha256:ede9b407e39949d2afc46385ce6bd6e11588660c26f80576c11c958e6647bc40", size = 1956626 },
{ url = "https://files.pythonhosted.org/packages/20/d0/e8d567a7cff7b04e017ae164d98011f1e1894269fe8e90ea187a3cbfb562/pydantic_core-2.33.1-cp313-cp313-win_arm64.whl", hash = "sha256:aa687a23d4b7871a00e03ca96a09cad0f28f443690d300500603bd0adba4b523", size = 1909590 },
{ url = "https://files.pythonhosted.org/packages/ef/fd/24ea4302d7a527d672c5be06e17df16aabfb4e9fdc6e0b345c21580f3d2a/pydantic_core-2.33.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:401d7b76e1000d0dd5538e6381d28febdcacb097c8d340dde7d7fc6e13e9f95d", size = 1812963 },
{ url = "https://files.pythonhosted.org/packages/5f/95/4fbc2ecdeb5c1c53f1175a32d870250194eb2fdf6291b795ab08c8646d5d/pydantic_core-2.33.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7aeb055a42d734c0255c9e489ac67e75397d59c6fbe60d155851e9782f276a9c", size = 1986896 },
{ url = "https://files.pythonhosted.org/packages/71/ae/fe31e7f4a62431222d8f65a3bd02e3fa7e6026d154a00818e6d30520ea77/pydantic_core-2.33.1-cp313-cp313t-win_amd64.whl", hash = "sha256:338ea9b73e6e109f15ab439e62cb3b78aa752c7fd9536794112e14bee02c8d18", size = 1931810 },
]
[[package]]
name = "pypdf"
version = "5.4.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f9/43/4026f6ee056306d0e0eb04fcb9f2122a0f1a5c57ad9dc5e0d67399e47194/pypdf-5.4.0.tar.gz", hash = "sha256:9af476a9dc30fcb137659b0dec747ea94aa954933c52cf02ee33e39a16fe9175", size = 5012492 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/0b/27/d83f8f2a03ca5408dc2cc84b49c0bf3fbf059398a6a2ea7c10acfe28859f/pypdf-5.4.0-py3-none-any.whl", hash = "sha256:db994ab47cadc81057ea1591b90e5b543e2b7ef2d0e31ef41a9bfe763c119dab", size = 302306 },
]
[[package]]
name = "python-dotenv"
version = "1.1.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/88/2c/7bb1416c5620485aa793f2de31d3df393d3686aa8a8506d11e10e13c5baf/python_dotenv-1.1.0.tar.gz", hash = "sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5", size = 39920 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/1e/18/98a99ad95133c6a6e2005fe89faedf294a748bd5dc803008059409ac9b1e/python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d", size = 20256 },
]
[[package]]
name = "pyyaml"
version = "6.0.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 },
{ url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 },
{ url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 },
{ url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 },
{ url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 },
{ url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 },
{ url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 },
{ url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 },
{ url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 },
]
[[package]]
name = "regex"
version = "2024.11.6"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/8e/5f/bd69653fbfb76cf8604468d3b4ec4c403197144c7bfe0e6a5fc9e02a07cb/regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519", size = 399494 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/90/73/bcb0e36614601016552fa9344544a3a2ae1809dc1401b100eab02e772e1f/regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84", size = 483525 },
{ url = "https://files.pythonhosted.org/packages/0f/3f/f1a082a46b31e25291d830b369b6b0c5576a6f7fb89d3053a354c24b8a83/regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4", size = 288324 },
{ url = "https://files.pythonhosted.org/packages/09/c9/4e68181a4a652fb3ef5099e077faf4fd2a694ea6e0f806a7737aff9e758a/regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0", size = 284617 },
{ url = "https://files.pythonhosted.org/packages/fc/fd/37868b75eaf63843165f1d2122ca6cb94bfc0271e4428cf58c0616786dce/regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0", size = 795023 },
{ url = "https://files.pythonhosted.org/packages/c4/7c/d4cd9c528502a3dedb5c13c146e7a7a539a3853dc20209c8e75d9ba9d1b2/regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7", size = 833072 },
{ url = "https://files.pythonhosted.org/packages/4f/db/46f563a08f969159c5a0f0e722260568425363bea43bb7ae370becb66a67/regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7", size = 823130 },
{ url = "https://files.pythonhosted.org/packages/db/60/1eeca2074f5b87df394fccaa432ae3fc06c9c9bfa97c5051aed70e6e00c2/regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c", size = 796857 },
{ url = "https://files.pythonhosted.org/packages/10/db/ac718a08fcee981554d2f7bb8402f1faa7e868c1345c16ab1ebec54b0d7b/regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3", size = 784006 },
{ url = "https://files.pythonhosted.org/packages/c2/41/7da3fe70216cea93144bf12da2b87367590bcf07db97604edeea55dac9ad/regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07", size = 781650 },
{ url = "https://files.pythonhosted.org/packages/a7/d5/880921ee4eec393a4752e6ab9f0fe28009435417c3102fc413f3fe81c4e5/regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e", size = 789545 },
{ url = "https://files.pythonhosted.org/packages/dc/96/53770115e507081122beca8899ab7f5ae28ae790bfcc82b5e38976df6a77/regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6", size = 853045 },
{ url = "https://files.pythonhosted.org/packages/31/d3/1372add5251cc2d44b451bd94f43b2ec78e15a6e82bff6a290ef9fd8f00a/regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4", size = 860182 },
{ url = "https://files.pythonhosted.org/packages/ed/e3/c446a64984ea9f69982ba1a69d4658d5014bc7a0ea468a07e1a1265db6e2/regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d", size = 787733 },
{ url = "https://files.pythonhosted.org/packages/2b/f1/e40c8373e3480e4f29f2692bd21b3e05f296d3afebc7e5dcf21b9756ca1c/regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff", size = 262122 },
{ url = "https://files.pythonhosted.org/packages/45/94/bc295babb3062a731f52621cdc992d123111282e291abaf23faa413443ea/regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a", size = 273545 },
]
[[package]]
name = "requests"
version = "2.32.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "certifi" },
{ name = "charset-normalizer" },
{ name = "idna" },
{ name = "urllib3" },
]
sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 },
]
[[package]]
name = "rsa"
version = "4.9.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pyasn1" },
]
sdist = { url = "https://files.pythonhosted.org/packages/da/8a/22b7beea3ee0d44b1916c0c1cb0ee3af23b700b6da9f04991899d0c555d4/rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75", size = 29034 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696 },
]
[[package]]
name = "safetensors"
version = "0.5.3"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/71/7e/2d5d6ee7b40c0682315367ec7475693d110f512922d582fef1bd4a63adc3/safetensors-0.5.3.tar.gz", hash = "sha256:b6b0d6ecacec39a4fdd99cc19f4576f5219ce858e6fd8dbe7609df0b8dc56965", size = 67210 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/18/ae/88f6c49dbd0cc4da0e08610019a3c78a7d390879a919411a410a1876d03a/safetensors-0.5.3-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:bd20eb133db8ed15b40110b7c00c6df51655a2998132193de2f75f72d99c7073", size = 436917 },
{ url = "https://files.pythonhosted.org/packages/b8/3b/11f1b4a2f5d2ab7da34ecc062b0bc301f2be024d110a6466726bec8c055c/safetensors-0.5.3-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:21d01c14ff6c415c485616b8b0bf961c46b3b343ca59110d38d744e577f9cce7", size = 418419 },
{ url = "https://files.pythonhosted.org/packages/5d/9a/add3e6fef267658075c5a41573c26d42d80c935cdc992384dfae435feaef/safetensors-0.5.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11bce6164887cd491ca75c2326a113ba934be596e22b28b1742ce27b1d076467", size = 459493 },
{ url = "https://files.pythonhosted.org/packages/df/5c/bf2cae92222513cc23b3ff85c4a1bb2811a2c3583ac0f8e8d502751de934/safetensors-0.5.3-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4a243be3590bc3301c821da7a18d87224ef35cbd3e5f5727e4e0728b8172411e", size = 472400 },
{ url = "https://files.pythonhosted.org/packages/58/11/7456afb740bd45782d0f4c8e8e1bb9e572f1bf82899fb6ace58af47b4282/safetensors-0.5.3-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8bd84b12b1670a6f8e50f01e28156422a2bc07fb16fc4e98bded13039d688a0d", size = 522891 },
{ url = "https://files.pythonhosted.org/packages/57/3d/fe73a9d2ace487e7285f6e157afee2383bd1ddb911b7cb44a55cf812eae3/safetensors-0.5.3-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:391ac8cab7c829452175f871fcaf414aa1e292b5448bd02620f675a7f3e7abb9", size = 537694 },
{ url = "https://files.pythonhosted.org/packages/a6/f8/dae3421624fcc87a89d42e1898a798bc7ff72c61f38973a65d60df8f124c/safetensors-0.5.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cead1fa41fc54b1e61089fa57452e8834f798cb1dc7a09ba3524f1eb08e0317a", size = 471642 },
{ url = "https://files.pythonhosted.org/packages/ce/20/1fbe16f9b815f6c5a672f5b760951e20e17e43f67f231428f871909a37f6/safetensors-0.5.3-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1077f3e94182d72618357b04b5ced540ceb71c8a813d3319f1aba448e68a770d", size = 502241 },
{ url = "https://files.pythonhosted.org/packages/5f/18/8e108846b506487aa4629fe4116b27db65c3dde922de2c8e0cc1133f3f29/safetensors-0.5.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:799021e78287bac619c7b3f3606730a22da4cda27759ddf55d37c8db7511c74b", size = 638001 },
{ url = "https://files.pythonhosted.org/packages/82/5a/c116111d8291af6c8c8a8b40628fe833b9db97d8141c2a82359d14d9e078/safetensors-0.5.3-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:df26da01aaac504334644e1b7642fa000bfec820e7cef83aeac4e355e03195ff", size = 734013 },
{ url = "https://files.pythonhosted.org/packages/7d/ff/41fcc4d3b7de837963622e8610d998710705bbde9a8a17221d85e5d0baad/safetensors-0.5.3-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:32c3ef2d7af8b9f52ff685ed0bc43913cdcde135089ae322ee576de93eae5135", size = 670687 },
{ url = "https://files.pythonhosted.org/packages/40/ad/2b113098e69c985a3d8fbda4b902778eae4a35b7d5188859b4a63d30c161/safetensors-0.5.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:37f1521be045e56fc2b54c606d4455573e717b2d887c579ee1dbba5f868ece04", size = 643147 },
{ url = "https://files.pythonhosted.org/packages/0a/0c/95aeb51d4246bd9a3242d3d8349c1112b4ee7611a4b40f0c5c93b05f001d/safetensors-0.5.3-cp38-abi3-win32.whl", hash = "sha256:cfc0ec0846dcf6763b0ed3d1846ff36008c6e7290683b61616c4b040f6a54ace", size = 296677 },
{ url = "https://files.pythonhosted.org/packages/69/e2/b011c38e5394c4c18fb5500778a55ec43ad6106126e74723ffaee246f56e/safetensors-0.5.3-cp38-abi3-win_amd64.whl", hash = "sha256:836cbbc320b47e80acd40e44c8682db0e8ad7123209f69b093def21ec7cafd11", size = 308878 },
]
[[package]]
name = "scikit-learn"
version = "1.6.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "joblib" },
{ name = "numpy" },
{ name = "scipy" },
{ name = "threadpoolctl" },
]
sdist = { url = "https://files.pythonhosted.org/packages/9e/a5/4ae3b3a0755f7b35a280ac90b28817d1f380318973cff14075ab41ef50d9/scikit_learn-1.6.1.tar.gz", hash = "sha256:b4fc2525eca2c69a59260f583c56a7557c6ccdf8deafdba6e060f94c1c59738e", size = 7068312 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2e/59/8eb1872ca87009bdcdb7f3cdc679ad557b992c12f4b61f9250659e592c63/scikit_learn-1.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2ffa1e9e25b3d93990e74a4be2c2fc61ee5af85811562f1288d5d055880c4322", size = 12010001 },
{ url = "https://files.pythonhosted.org/packages/9d/05/f2fc4effc5b32e525408524c982c468c29d22f828834f0625c5ef3d601be/scikit_learn-1.6.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:dc5cf3d68c5a20ad6d571584c0750ec641cc46aeef1c1507be51300e6003a7e1", size = 11096360 },
{ url = "https://files.pythonhosted.org/packages/c8/e4/4195d52cf4f113573fb8ebc44ed5a81bd511a92c0228889125fac2f4c3d1/scikit_learn-1.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c06beb2e839ecc641366000ca84f3cf6fa9faa1777e29cf0c04be6e4d096a348", size = 12209004 },
{ url = "https://files.pythonhosted.org/packages/94/be/47e16cdd1e7fcf97d95b3cb08bde1abb13e627861af427a3651fcb80b517/scikit_learn-1.6.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8ca8cb270fee8f1f76fa9bfd5c3507d60c6438bbee5687f81042e2bb98e5a97", size = 13171776 },
{ url = "https://files.pythonhosted.org/packages/34/b0/ca92b90859070a1487827dbc672f998da95ce83edce1270fc23f96f1f61a/scikit_learn-1.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:7a1c43c8ec9fde528d664d947dc4c0789be4077a3647f232869f41d9bf50e0fb", size = 11071865 },
{ url = "https://files.pythonhosted.org/packages/12/ae/993b0fb24a356e71e9a894e42b8a9eec528d4c70217353a1cd7a48bc25d4/scikit_learn-1.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a17c1dea1d56dcda2fac315712f3651a1fea86565b64b48fa1bc090249cbf236", size = 11955804 },
{ url = "https://files.pythonhosted.org/packages/d6/54/32fa2ee591af44507eac86406fa6bba968d1eb22831494470d0a2e4a1eb1/scikit_learn-1.6.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:6a7aa5f9908f0f28f4edaa6963c0a6183f1911e63a69aa03782f0d924c830a35", size = 11100530 },
{ url = "https://files.pythonhosted.org/packages/3f/58/55856da1adec655bdce77b502e94a267bf40a8c0b89f8622837f89503b5a/scikit_learn-1.6.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0650e730afb87402baa88afbf31c07b84c98272622aaba002559b614600ca691", size = 12433852 },
{ url = "https://files.pythonhosted.org/packages/ff/4f/c83853af13901a574f8f13b645467285a48940f185b690936bb700a50863/scikit_learn-1.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:3f59fe08dc03ea158605170eb52b22a105f238a5d512c4470ddeca71feae8e5f", size = 11337256 },
]
[[package]]
name = "scipy"
version = "1.15.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "numpy" },
]
sdist = { url = "https://files.pythonhosted.org/packages/b7/b9/31ba9cd990e626574baf93fbc1ac61cf9ed54faafd04c479117517661637/scipy-1.15.2.tar.gz", hash = "sha256:cd58a314d92838f7e6f755c8a2167ead4f27e1fd5c1251fd54289569ef3495ec", size = 59417316 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/53/40/09319f6e0f276ea2754196185f95cd191cb852288440ce035d5c3a931ea2/scipy-1.15.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01edfac9f0798ad6b46d9c4c9ca0e0ad23dbf0b1eb70e96adb9fa7f525eff0bf", size = 38717587 },
{ url = "https://files.pythonhosted.org/packages/fe/c3/2854f40ecd19585d65afaef601e5e1f8dbf6758b2f95b5ea93d38655a2c6/scipy-1.15.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:08b57a9336b8e79b305a143c3655cc5bdbe6d5ece3378578888d2afbb51c4e37", size = 30100266 },
{ url = "https://files.pythonhosted.org/packages/dd/b1/f9fe6e3c828cb5930b5fe74cb479de5f3d66d682fa8adb77249acaf545b8/scipy-1.15.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:54c462098484e7466362a9f1672d20888f724911a74c22ae35b61f9c5919183d", size = 22373768 },
{ url = "https://files.pythonhosted.org/packages/15/9d/a60db8c795700414c3f681908a2b911e031e024d93214f2d23c6dae174ab/scipy-1.15.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:cf72ff559a53a6a6d77bd8eefd12a17995ffa44ad86c77a5df96f533d4e6c6bb", size = 25154719 },
{ url = "https://files.pythonhosted.org/packages/37/3b/9bda92a85cd93f19f9ed90ade84aa1e51657e29988317fabdd44544f1dd4/scipy-1.15.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9de9d1416b3d9e7df9923ab23cd2fe714244af10b763975bea9e4f2e81cebd27", size = 35163195 },
{ url = "https://files.pythonhosted.org/packages/03/5a/fc34bf1aa14dc7c0e701691fa8685f3faec80e57d816615e3625f28feb43/scipy-1.15.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb530e4794fc8ea76a4a21ccb67dea33e5e0e60f07fc38a49e821e1eae3b71a0", size = 37255404 },
{ url = "https://files.pythonhosted.org/packages/4a/71/472eac45440cee134c8a180dbe4c01b3ec247e0338b7c759e6cd71f199a7/scipy-1.15.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5ea7ed46d437fc52350b028b1d44e002646e28f3e8ddc714011aaf87330f2f32", size = 36860011 },
{ url = "https://files.pythonhosted.org/packages/01/b3/21f890f4f42daf20e4d3aaa18182dddb9192771cd47445aaae2e318f6738/scipy-1.15.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11e7ad32cf184b74380f43d3c0a706f49358b904fa7d5345f16ddf993609184d", size = 39657406 },
{ url = "https://files.pythonhosted.org/packages/0d/76/77cf2ac1f2a9cc00c073d49e1e16244e389dd88e2490c91d84e1e3e4d126/scipy-1.15.2-cp313-cp313-win_amd64.whl", hash = "sha256:a5080a79dfb9b78b768cebf3c9dcbc7b665c5875793569f48bf0e2b1d7f68f6f", size = 40961243 },
{ url = "https://files.pythonhosted.org/packages/4c/4b/a57f8ddcf48e129e6054fa9899a2a86d1fc6b07a0e15c7eebff7ca94533f/scipy-1.15.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:447ce30cee6a9d5d1379087c9e474628dab3db4a67484be1b7dc3196bfb2fac9", size = 38870286 },
{ url = "https://files.pythonhosted.org/packages/0c/43/c304d69a56c91ad5f188c0714f6a97b9c1fed93128c691148621274a3a68/scipy-1.15.2-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:c90ebe8aaa4397eaefa8455a8182b164a6cc1d59ad53f79943f266d99f68687f", size = 30141634 },
{ url = "https://files.pythonhosted.org/packages/44/1a/6c21b45d2548eb73be9b9bff421aaaa7e85e22c1f9b3bc44b23485dfce0a/scipy-1.15.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:def751dd08243934c884a3221156d63e15234a3155cf25978b0a668409d45eb6", size = 22415179 },
{ url = "https://files.pythonhosted.org/packages/74/4b/aefac4bba80ef815b64f55da06f62f92be5d03b467f2ce3668071799429a/scipy-1.15.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:302093e7dfb120e55515936cb55618ee0b895f8bcaf18ff81eca086c17bd80af", size = 25126412 },
{ url = "https://files.pythonhosted.org/packages/b1/53/1cbb148e6e8f1660aacd9f0a9dfa2b05e9ff1cb54b4386fe868477972ac2/scipy-1.15.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7cd5b77413e1855351cdde594eca99c1f4a588c2d63711388b6a1f1c01f62274", size = 34952867 },
{ url = "https://files.pythonhosted.org/packages/2c/23/e0eb7f31a9c13cf2dca083828b97992dd22f8184c6ce4fec5deec0c81fcf/scipy-1.15.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d0194c37037707b2afa7a2f2a924cf7bac3dc292d51b6a925e5fcb89bc5c776", size = 36890009 },
{ url = "https://files.pythonhosted.org/packages/03/f3/e699e19cabe96bbac5189c04aaa970718f0105cff03d458dc5e2b6bd1e8c/scipy-1.15.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:bae43364d600fdc3ac327db99659dcb79e6e7ecd279a75fe1266669d9a652828", size = 36545159 },
{ url = "https://files.pythonhosted.org/packages/af/f5/ab3838e56fe5cc22383d6fcf2336e48c8fe33e944b9037fbf6cbdf5a11f8/scipy-1.15.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f031846580d9acccd0044efd1a90e6f4df3a6e12b4b6bd694a7bc03a89892b28", size = 39136566 },
{ url = "https://files.pythonhosted.org/packages/0a/c8/b3f566db71461cabd4b2d5b39bcc24a7e1c119535c8361f81426be39bb47/scipy-1.15.2-cp313-cp313t-win_amd64.whl", hash = "sha256:fe8a9eb875d430d81755472c5ba75e84acc980e4a8f6204d402849234d3017db", size = 40477705 },
]
[[package]]
name = "sentence-transformers"
version = "4.1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "huggingface-hub" },
{ name = "pillow" },
{ name = "scikit-learn" },
{ name = "scipy" },
{ name = "torch" },
{ name = "tqdm" },
{ name = "transformers" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/73/84/b30d1b29ff58cfdff423e36a50efd622c8e31d7039b1a0d5e72066620da1/sentence_transformers-4.1.0.tar.gz", hash = "sha256:f125ffd1c727533e0eca5d4567de72f84728de8f7482834de442fd90c2c3d50b", size = 272420 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/45/2d/1151b371f28caae565ad384fdc38198f1165571870217aedda230b9d7497/sentence_transformers-4.1.0-py3-none-any.whl", hash = "sha256:382a7f6be1244a100ce40495fb7523dbe8d71b3c10b299f81e6b735092b3b8ca", size = 345695 },
]
[[package]]
name = "setuptools"
version = "78.1.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/a9/5a/0db4da3bc908df06e5efae42b44e75c81dd52716e10192ff36d0c1c8e379/setuptools-78.1.0.tar.gz", hash = "sha256:18fd474d4a82a5f83dac888df697af65afa82dec7323d09c3e37d1f14288da54", size = 1367827 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/54/21/f43f0a1fa8b06b32812e0975981f4677d28e0f3271601dc88ac5a5b83220/setuptools-78.1.0-py3-none-any.whl", hash = "sha256:3e386e96793c8702ae83d17b853fb93d3e09ef82ec62722e61da5cd22376dcd8", size = 1256108 },
]
[[package]]
name = "sniffio"
version = "1.3.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 },
]
[[package]]
name = "soupsieve"
version = "2.6"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", size = 101569 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 },
]
[[package]]
name = "sympy"
version = "1.13.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "mpmath" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ca/99/5a5b6f19ff9f083671ddf7b9632028436167cd3d33e11015754e41b249a4/sympy-1.13.1.tar.gz", hash = "sha256:9cebf7e04ff162015ce31c9c6c9144daa34a93bd082f54fd8f12deca4f47515f", size = 7533040 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b2/fe/81695a1aa331a842b582453b605175f419fe8540355886031328089d840a/sympy-1.13.1-py3-none-any.whl", hash = "sha256:db36cdc64bf61b9b24578b6f7bab1ecdd2452cf008f34faa33776680c26d66f8", size = 6189177 },
]
[[package]]
name = "threadpoolctl"
version = "3.6.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/b7/4d/08c89e34946fce2aec4fbb45c9016efd5f4d7f24af8e5d93296e935631d8/threadpoolctl-3.6.0.tar.gz", hash = "sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e", size = 21274 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638 },
]
[[package]]
name = "tokenizers"
version = "0.21.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "huggingface-hub" },
]
sdist = { url = "https://files.pythonhosted.org/packages/92/76/5ac0c97f1117b91b7eb7323dcd61af80d72f790b4df71249a7850c195f30/tokenizers-0.21.1.tar.gz", hash = "sha256:a1bb04dc5b448985f86ecd4b05407f5a8d97cb2c0532199b2a302a604a0165ab", size = 343256 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a5/1f/328aee25f9115bf04262e8b4e5a2050b7b7cf44b59c74e982db7270c7f30/tokenizers-0.21.1-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:e78e413e9e668ad790a29456e677d9d3aa50a9ad311a40905d6861ba7692cf41", size = 2780767 },
{ url = "https://files.pythonhosted.org/packages/ae/1a/4526797f3719b0287853f12c5ad563a9be09d446c44ac784cdd7c50f76ab/tokenizers-0.21.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:cd51cd0a91ecc801633829fcd1fda9cf8682ed3477c6243b9a095539de4aecf3", size = 2650555 },
{ url = "https://files.pythonhosted.org/packages/4d/7a/a209b29f971a9fdc1da86f917fe4524564924db50d13f0724feed37b2a4d/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28da6b72d4fb14ee200a1bd386ff74ade8992d7f725f2bde2c495a9a98cf4d9f", size = 2937541 },
{ url = "https://files.pythonhosted.org/packages/3c/1e/b788b50ffc6191e0b1fc2b0d49df8cff16fe415302e5ceb89f619d12c5bc/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:34d8cfde551c9916cb92014e040806122295a6800914bab5865deb85623931cf", size = 2819058 },
{ url = "https://files.pythonhosted.org/packages/36/aa/3626dfa09a0ecc5b57a8c58eeaeb7dd7ca9a37ad9dd681edab5acd55764c/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaa852d23e125b73d283c98f007e06d4595732104b65402f46e8ef24b588d9f8", size = 3133278 },
{ url = "https://files.pythonhosted.org/packages/a4/4d/8fbc203838b3d26269f944a89459d94c858f5b3f9a9b6ee9728cdcf69161/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a21a15d5c8e603331b8a59548bbe113564136dc0f5ad8306dd5033459a226da0", size = 3144253 },
{ url = "https://files.pythonhosted.org/packages/d8/1b/2bd062adeb7c7511b847b32e356024980c0ffcf35f28947792c2d8ad2288/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2fdbd4c067c60a0ac7eca14b6bd18a5bebace54eb757c706b47ea93204f7a37c", size = 3398225 },
{ url = "https://files.pythonhosted.org/packages/8a/63/38be071b0c8e06840bc6046991636bcb30c27f6bb1e670f4f4bc87cf49cc/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dd9a0061e403546f7377df940e866c3e678d7d4e9643d0461ea442b4f89e61a", size = 3038874 },
{ url = "https://files.pythonhosted.org/packages/ec/83/afa94193c09246417c23a3c75a8a0a96bf44ab5630a3015538d0c316dd4b/tokenizers-0.21.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:db9484aeb2e200c43b915a1a0150ea885e35f357a5a8fabf7373af333dcc8dbf", size = 9014448 },
{ url = "https://files.pythonhosted.org/packages/ae/b3/0e1a37d4f84c0f014d43701c11eb8072704f6efe8d8fc2dcdb79c47d76de/tokenizers-0.21.1-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:ed248ab5279e601a30a4d67bdb897ecbe955a50f1e7bb62bd99f07dd11c2f5b6", size = 8937877 },
{ url = "https://files.pythonhosted.org/packages/ac/33/ff08f50e6d615eb180a4a328c65907feb6ded0b8f990ec923969759dc379/tokenizers-0.21.1-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:9ac78b12e541d4ce67b4dfd970e44c060a2147b9b2a21f509566d556a509c67d", size = 9186645 },
{ url = "https://files.pythonhosted.org/packages/5f/aa/8ae85f69a9f6012c6f8011c6f4aa1c96154c816e9eea2e1b758601157833/tokenizers-0.21.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e5a69c1a4496b81a5ee5d2c1f3f7fbdf95e90a0196101b0ee89ed9956b8a168f", size = 9384380 },
{ url = "https://files.pythonhosted.org/packages/e8/5b/a5d98c89f747455e8b7a9504910c865d5e51da55e825a7ae641fb5ff0a58/tokenizers-0.21.1-cp39-abi3-win32.whl", hash = "sha256:1039a3a5734944e09de1d48761ade94e00d0fa760c0e0551151d4dd851ba63e3", size = 2239506 },
{ url = "https://files.pythonhosted.org/packages/e6/b6/072a8e053ae600dcc2ac0da81a23548e3b523301a442a6ca900e92ac35be/tokenizers-0.21.1-cp39-abi3-win_amd64.whl", hash = "sha256:0f0dcbcc9f6e13e675a66d7a5f2f225a736745ce484c1a4e07476a89ccdad382", size = 2435481 },
]
[[package]]
name = "torch"
version = "2.6.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "filelock" },
{ name = "fsspec" },
{ name = "jinja2" },
{ name = "networkx" },
{ name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-cuda-cupti-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-cuda-nvrtc-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-cuda-runtime-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-cudnn-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-cufft-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-curand-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-cusolver-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-cusparse-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-cusparselt-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "setuptools" },
{ name = "sympy" },
{ name = "triton", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "typing-extensions" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/24/85/ead1349fc30fe5a32cadd947c91bda4a62fbfd7f8c34ee61f6398d38fb48/torch-2.6.0-cp313-cp313-manylinux1_x86_64.whl", hash = "sha256:4874a73507a300a5d089ceaff616a569e7bb7c613c56f37f63ec3ffac65259cf", size = 766626191 },
{ url = "https://files.pythonhosted.org/packages/dd/b0/26f06f9428b250d856f6d512413e9e800b78625f63801cbba13957432036/torch-2.6.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:a0d5e1b9874c1a6c25556840ab8920569a7a4137afa8a63a32cee0bc7d89bd4b", size = 95611439 },
{ url = "https://files.pythonhosted.org/packages/c2/9c/fc5224e9770c83faed3a087112d73147cd7c7bfb7557dcf9ad87e1dda163/torch-2.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:510c73251bee9ba02ae1cb6c9d4ee0907b3ce6020e62784e2d7598e0cfa4d6cc", size = 204126475 },
{ url = "https://files.pythonhosted.org/packages/88/8b/d60c0491ab63634763be1537ad488694d316ddc4a20eaadd639cedc53971/torch-2.6.0-cp313-none-macosx_11_0_arm64.whl", hash = "sha256:ff96f4038f8af9f7ec4231710ed4549da1bdebad95923953a25045dcf6fd87e2", size = 66536783 },
]
[[package]]
name = "tqdm"
version = "4.67.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540 },
]
[[package]]
name = "transformers"
version = "4.51.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "filelock" },
{ name = "huggingface-hub" },
{ name = "numpy" },
{ name = "packaging" },
{ name = "pyyaml" },
{ name = "regex" },
{ name = "requests" },
{ name = "safetensors" },
{ name = "tokenizers" },
{ name = "tqdm" },
]
sdist = { url = "https://files.pythonhosted.org/packages/f1/11/7414d5bc07690002ce4d7553602107bf969af85144bbd02830f9fb471236/transformers-4.51.3.tar.gz", hash = "sha256:e292fcab3990c6defe6328f0f7d2004283ca81a7a07b2de9a46d67fd81ea1409", size = 8941266 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a9/b6/5257d04ae327b44db31f15cce39e6020cc986333c715660b1315a9724d82/transformers-4.51.3-py3-none-any.whl", hash = "sha256:fd3279633ceb2b777013234bbf0b4f5c2d23c4626b05497691f00cfda55e8a83", size = 10383940 },
]
[[package]]
name = "triton"
version = "3.2.0"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c7/30/37a3384d1e2e9320331baca41e835e90a3767303642c7a80d4510152cbcf/triton-3.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5dfa23ba84541d7c0a531dfce76d8bcd19159d50a4a8b14ad01e91734a5c1b0", size = 253154278 },
]
[[package]]
name = "typing-extensions"
version = "4.13.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806 },
]
[[package]]
name = "typing-inspection"
version = "0.4.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125 },
]
[[package]]
name = "urllib3"
version = "2.4.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680 },
]
[[package]]
name = "websockets"
version = "15.0.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440 },
{ url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098 },
{ url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329 },
{ url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111 },
{ url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054 },
{ url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496 },
{ url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829 },
{ url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217 },
{ url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195 },
{ url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393 },
{ url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837 },
{ url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743 },
]