Delete app.py
Browse files
app.py
DELETED
|
@@ -1,126 +0,0 @@
|
|
| 1 |
-
import gradio as gr
|
| 2 |
-
import pandas as pd
|
| 3 |
-
import numpy as np
|
| 4 |
-
import random
|
| 5 |
-
|
| 6 |
-
regions = ["Riyadh", "Makkah", "Eastern", "Madinah", "Qassim", "Asir", "Tabuk", "Hail", "Northern",
|
| 7 |
-
"Jazan", "Najran", "Bahah", "Jawf"]
|
| 8 |
-
income_bands = ["Low", "Mid", "High"]
|
| 9 |
-
property_types = ["Land", "Off-plan", "Ready", "Self-build"]
|
| 10 |
-
|
| 11 |
-
def default_subsidy_values():
|
| 12 |
-
base = 300_000
|
| 13 |
-
factor = 0.5
|
| 14 |
-
return {(r, i, p): int((base - 100_000 * income_bands.index(i)) * factor) for r in regions for i in income_bands for p in property_types}
|
| 15 |
-
|
| 16 |
-
def monte_carlo_optimization(subsidies, budget_limit, target_contracts, supply_dict, interest_rate, demand_increase, n_trials=10000):
|
| 17 |
-
keys = list(subsidies.keys())
|
| 18 |
-
best_result = None
|
| 19 |
-
best_score = float('-inf')
|
| 20 |
-
fairness_penalty_weight = 10_000_000
|
| 21 |
-
|
| 22 |
-
demand_multiplier = 1 + (demand_increase / 100)
|
| 23 |
-
cost_multiplier = 1 + (interest_rate / 100)
|
| 24 |
-
|
| 25 |
-
for _ in range(n_trials):
|
| 26 |
-
contracts = {}
|
| 27 |
-
total_budget = 0
|
| 28 |
-
total_contracts = 0
|
| 29 |
-
shuffled_subs = {k: int(random.randint(150_000, 400_000) * cost_multiplier) for k in keys}
|
| 30 |
-
available_supply = {(r, p): supply_dict.get((p, r), 10000) for (p, r) in supply_dict}
|
| 31 |
-
|
| 32 |
-
for k in keys:
|
| 33 |
-
r, i, p = k
|
| 34 |
-
max_supply = available_supply.get((r, p), 10000)
|
| 35 |
-
max_demand = int(max_supply * demand_multiplier)
|
| 36 |
-
max_possible_contracts = int(min((budget_limit - total_budget) // shuffled_subs[k], max_demand)) if shuffled_subs[k] > 0 else 0
|
| 37 |
-
c = random.randint(0, max_possible_contracts) if max_possible_contracts > 0 else 0
|
| 38 |
-
contracts[k] = c
|
| 39 |
-
total_budget += shuffled_subs[k] * c
|
| 40 |
-
total_contracts += c
|
| 41 |
-
|
| 42 |
-
if total_budget > budget_limit:
|
| 43 |
-
continue
|
| 44 |
-
|
| 45 |
-
achieved_regions = set(r for (r, i, p) in contracts if contracts[(r, i, p)] > 0)
|
| 46 |
-
achieved_income = set(i for (r, i, p) in contracts if contracts[(r, i, p)] > 0)
|
| 47 |
-
achieved_props = set(p for (r, i, p) in contracts if contracts[(r, i, p)] > 0)
|
| 48 |
-
fairness_penalty = (
|
| 49 |
-
len(regions) - len(achieved_regions) +
|
| 50 |
-
len(income_bands) - len(achieved_income) +
|
| 51 |
-
len(property_types) - len(achieved_props)
|
| 52 |
-
) * fairness_penalty_weight
|
| 53 |
-
|
| 54 |
-
score = total_contracts - fairness_penalty
|
| 55 |
-
|
| 56 |
-
if score > best_score:
|
| 57 |
-
best_score = score
|
| 58 |
-
best_result = (contracts, total_budget, total_contracts, shuffled_subs)
|
| 59 |
-
|
| 60 |
-
return best_result if best_result else ({}, 0, 0, subsidies)
|
| 61 |
-
|
| 62 |
-
def build_app():
|
| 63 |
-
supply_costs = {(p, r): random.randint(1000, 10000) for p in ["Land", "Off-plan"] for r in regions}
|
| 64 |
-
with gr.Blocks() as demo:
|
| 65 |
-
gr.Markdown("# 🏨 Strategic Gears Housing Simulator – Auto Optimization")
|
| 66 |
-
|
| 67 |
-
with gr.Row():
|
| 68 |
-
ir = gr.Slider(0, 10, 5, label="Interest Rate (%)")
|
| 69 |
-
dp = gr.Slider(0, 100, 10, label="Demand Increase (%)")
|
| 70 |
-
n = gr.Slider(100, 10000, 1000, step=100, label="Number of Simulations")
|
| 71 |
-
budget_limit = gr.Slider(10_000_000, 1_000_000_000, 500_000_000, step=10_000_000, label="Budget Limit (SAR)")
|
| 72 |
-
target_contracts = gr.Slider(1000, 20000, 5000, step=100, label="Target Contracts")
|
| 73 |
-
|
| 74 |
-
supply_inputs = {}
|
| 75 |
-
with gr.Accordion("Supply Inputs by Region and Property Type", open=False):
|
| 76 |
-
for p in ["Land", "Off-plan"]:
|
| 77 |
-
with gr.Accordion(p, open=False):
|
| 78 |
-
for r in regions:
|
| 79 |
-
supply_inputs[(p, r)] = gr.Slider(minimum=1, maximum=10000, value=supply_costs[(p, r)], step=1, label=f"{r} {p} Supply")
|
| 80 |
-
|
| 81 |
-
run = gr.Button("Run Simulation")
|
| 82 |
-
|
| 83 |
-
summary = gr.Markdown("Optimization summary will appear here.")
|
| 84 |
-
df_subsidy_policy = gr.Dataframe(label="1️⃣ Recommended Subsidy Support (SAR) - Sorted High to Low")
|
| 85 |
-
df_contract_summary = gr.Dataframe(label="2️⃣ Contract Distribution - Sorted High to Low")
|
| 86 |
-
df_budget_summary = gr.Dataframe(label="3️⃣ Budget Distribution - Sorted High to Low")
|
| 87 |
-
df_discount_table = gr.Dataframe(label="Discount Table (Land & Off-plan)")
|
| 88 |
-
|
| 89 |
-
def run_sim(interest, demand, sims, budget, target, *supplies):
|
| 90 |
-
supply_dict = {(p, r): supplies[i] for i, (p, r) in enumerate(supply_inputs)}
|
| 91 |
-
result, total_bgt, total_con, final_subs = monte_carlo_optimization(
|
| 92 |
-
default_subsidy_values(), budget, target, supply_dict, interest, demand, sims)
|
| 93 |
-
|
| 94 |
-
df = pd.DataFrame([{
|
| 95 |
-
"Region": r, "Income Band": i, "Property Type": p,
|
| 96 |
-
"Contracts": result.get((r, i, p), 0),
|
| 97 |
-
"Subsidy (SAR)": final_subs[(r, i, p)],
|
| 98 |
-
"Budget (SAR)": result.get((r, i, p), 0) * final_subs[(r, i, p)]
|
| 99 |
-
} for (r, i, p) in final_subs])
|
| 100 |
-
|
| 101 |
-
subsidy_df = df[["Region", "Income Band", "Property Type", "Subsidy (SAR)"]].sort_values(by="Subsidy (SAR)", ascending=False)
|
| 102 |
-
contract_df = df[["Region", "Income Band", "Property Type", "Contracts"]].sort_values(by="Contracts", ascending=False)
|
| 103 |
-
budget_df = df[["Region", "Income Band", "Property Type", "Budget (SAR)"]].sort_values(by="Budget (SAR)", ascending=False)
|
| 104 |
-
|
| 105 |
-
df_discount = pd.DataFrame([{
|
| 106 |
-
"Region": r, "Property Type": p,
|
| 107 |
-
"Discount (SAR)": random.randint(50_000, 300_000)
|
| 108 |
-
} for p in ["Land", "Off-plan"] for r in regions])
|
| 109 |
-
|
| 110 |
-
summary_text = f"""
|
| 111 |
-
### 🧾 Optimization Summary
|
| 112 |
-
- **Total Budget Used:** {total_bgt:,.0f} SAR
|
| 113 |
-
- **Budget Utilization:** {(total_bgt / budget) * 100:.2f}%
|
| 114 |
-
- **Total Contracts Signed:** {total_con:,}
|
| 115 |
-
- **Target Achievement:** {(total_con / target) * 100:.2f}%
|
| 116 |
-
"""
|
| 117 |
-
return summary_text, subsidy_df, contract_df, budget_df, df_discount
|
| 118 |
-
|
| 119 |
-
run.click(fn=run_sim,
|
| 120 |
-
inputs=[ir, dp, n, budget_limit, target_contracts] + list(supply_inputs.values()),
|
| 121 |
-
outputs=[summary, df_subsidy_policy, df_contract_summary, df_budget_summary, df_discount_table])
|
| 122 |
-
|
| 123 |
-
return demo
|
| 124 |
-
|
| 125 |
-
app = build_app()
|
| 126 |
-
app.launch()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|