Nagaraj81 commited on
Commit
e14d331
·
verified ·
1 Parent(s): b971ce5

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +126 -0
  2. requirements.txt +3 -0
app.py ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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()
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio
2
+ pandas
3
+ numpy