目錄
模型建立與求解
1.問題一的模型建立與求解
1.1?搬遷補償模型設計
1.2?住戶是否搬遷的應對策略與分析
1.3 定量討論
2.問題二的模型建立與求解
2.1?搬遷方案模型的優化介紹
2.2 模型的評估
2.3?模型結果
3.問題三的模型建立與求解
3.1?拐點存在性分析模型的建立
3.2 模型的評估
3.2 結果計算
4.問題四的模型建立與求解
4.1?智能計算“平移置換”決策模型建立
4.2 算法優化介紹
4.3?算法評價
4.4 結果說明
模型建立與求解
1.問題一的模型建立與求解
1.1?搬遷補償模型設計
????????1.依據面積補償,前提條件居民搬遷遷入地塊面積S新需要滿足So≤Sn≤1.3×So。補償范圍依據問題介紹:若Sn>So,開發商需要承擔面積差對應的潛在租金損失。即面積補償:
Sn∈[So,1.3×So]
????????2.依據采光補償,我們將問題的舒適等級按照正南=正北(等級為1)>東廂(等級為2)>西廂(等級為3)劃分。為了有效推動居民搬遷。遷入條件設置為:遷入地塊的舒適度等級需≥原地塊。設計補償策略,若遷入地塊舒適度等級提升(如從西廂遷入東廂),可以減少修繕費用;若等級相同,需要通過修繕來進行補償。即R(i) ∈ {1,2,3} ,R('南')=R('北')=1,R('東')=2,R('西')=3,補光補償:
R(o) ≤ R(n)
????????3.針對修繕補償,從問題已知每戶修繕的費用上限為20萬元。第一種情況若遷入地塊條件顯著優于原地塊,可以不修繕。第二種情況若遷入地塊于原地塊相近,需要按照修繕費用上限補償。修繕費用與舒適度差值掛鉤。即修繕補償:
Snew_cost?= max(0, 20 × (1 - (r - 1)/0.3 - ΔR × 0.2))
其中:r = Sn/So (面積比);ΔR = R(o) - R(n) (朝向等級差)
????????4.將面積補償、采光補償以及修繕補償加合得出一次搬遷的總費用:
Stotal_cost?= 3 + Snew_cost?+ (Sn - So) × p × 365 × 10 / 10000
其中:p = 15(當朝向為南/北)或 8(其他朝向)萬元/平方米·年
1.2?住戶是否搬遷的應對策略與分析
????????結合現實情況分析,決定住戶是否搬遷的其他影響因素分別為遷入地塊的位置,房屋的密集度,社區的歸屬感,以及搬遷的成本。
- 依據實際情況進行分析,靠近主街區可能噪音大但交通便利,我們需要對噪音敏感的住戶,優先分配遠離街道的地塊;可以選擇對交通便利需求高的住戶,并進行補償提供交通補貼。
- 房屋在高密集度區域采光、隱私較差,倘若住戶能夠搬遷,我們可以為能夠搬遷的住戶提供額外的修繕或者面積補償。
- 搬遷可能會導致住戶的原有社交網絡斷裂。盡量將同一院落的住戶集中搬遷至同一院中,或者為能夠搬遷的住戶提供社區活動經費,增進住戶之間的交流使得新住戶能夠更好的適應新居住區。
1.3 定量討論
????????對問題一的策略進行定量討論,我們通過補償方案需要綜合面積、采光、修繕以及其他環境因素,通過定量模型計算每戶的搬遷成本,并結合住戶心理和社區關系優化決策。
????????問題一通過面積進行考慮,對附件1的前五為住戶的搬遷結果進行定量分析通過計算原來住戶的地塊ID轉到遷入地塊ID的成本。結果表如下:
表1 定量結果表
地塊ID | 遷入地塊ID | 搬遷成本(萬元) |
3 | 227 | 3.00 |
5 | 410 | 3.18 |
7 | 112 | 3.18 |
9 | 442 | 3.48 |
14 | 98 | 3.00 |
????????通過對問題的定量分析,檢驗了搬遷補償模型范圍的可行性。同時通過模型進行檢驗出當前住戶數量有113戶,可搬遷住戶數為112戶,搬遷比例為99.1%,因此“平移置換”搬遷規劃很有必要。
2.問題二的模型建立與求解
2.1?搬遷方案模型的優化介紹
????????我們在問題一的范圍條件內,為模型設計目標條件,需要同時滿足搬遷決策對騰出完整院落數量最大,騰出的完整院落需要盡可能毗鄰。通過分別計算面積補償、采光補償、溝通成本、面積損失以及修繕成本,通過搬遷規劃模型嘗試將其搬遷到空置地塊,順序優化包括,優先不修繕盡量的避免修繕成本,以降低成本;另一方面在預算允許的情況下,修繕部分地塊以滿足搬遷需求,同時限制了最多的修繕成本為20萬元。最終使得投入的Stotal_cost目標成本最小,達到的最終收入以及W盈利最大。
????????通過附件2提供的老城街區詳細圖示觀察可知,毗鄰的院落ID大部分是連續的,因此將院落的毗鄰情況我們可以近似于相鄰院落ID差1。
2.2 模型的評估
????????我們通過回答的問題進行分析,設計評價指標,我們對搬遷質量進行評估。首先我們對搬遷成本分布,面積補償與成本關系,采光改善情況,院落完整化效果進行可視化分析如圖1:
圖1模型各變量可視化效果評估
????????通過可視化結果顯示,搬遷成本花費少的頻率較大,同時我們發現隨著面積補償的增多成本也在逐漸增多,采光補償的趨勢大部分比較分布于零采光補償,能夠騰出完整院落的數量占比大于50%。因此該模型有很好的應用價值。
????????通過模型可視化,我們也對搬遷的質量進行評價。搬遷質量的結果如下表所示:
表 2?問題二搬遷質量結果表
面積補償占比 | 采光補償占比 | 平均每平方米成本 |
100% | 100% | 4694.86 元/平方米 |
????????通過模型的搬遷質量結果,以及可視化結果顯示,該模型在解決問題二有著很好的使用價值,能夠幫助解決類似于問題二的實際問題。
2.3?模型結果
????????通過模型建立以及驗證了模型的在問題二中的可行性,我們對問題二的結果進行計算。我們通過將居民的搬遷方式的結果通過分析,最終結果統計在下表(只展示部分結果,完整結果表如附件表1采光負值含義是產生采光補償,數值越小,采光補償程度越大):
表3 搬遷最終結果統計表
原地塊ID | 新地塊ID | 面積補償 | 采光補償 | 成本消耗 | 是否修繕 |
241 | 52 | 4 | -2 | 146800 | FALSE |
242 | 56 | 0 | 0 | 30000 | FALSE |
243 | 79 | 0 | 0 | 30000 | FALSE |
385 | 419 | 5 | 0 | 176000 | FALSE |
38 | 46 | 1 | 0 | 84750 | FALSE |
39 | 10 | 0 | 0 | 30000 | FALSE |
41 | 51 | 3 | -2 | 117600 | FALSE |
452 | 63 | 5 | 0 | 176000 | FALSE |
49 | 123 | 3 | 0 | 194250 | FALSE |
5 | 68 | 2 | 0 | 139500 | FALSE |
????????通過統計結果顯示騰出完整院落總面積為11225.0平方米,總的拆遷成本為25998500.0萬元,歷經十年后的盈利8515278900萬元。
3.問題三的模型建立與求解
3.1?拐點存在性分析模型的建立
????????在問題一的范圍模型基礎上,我們首先對原始數據進行了全面的處理。這一階段的目標是將數據按照一定的標準進行分類,以便后續建模時能夠更高效地利用信息。具體我們將數據劃分為兩類:一是有住戶的院子,另一類是空閑的院子。通過引入目標與評估指標m:
m = 總收益 / 總成本
????????再對模型利用最大化“性價比(m)”≤20進行限制;其中總收益:騰出的土地面積×30元/平方米/天×年;總成本:包括搬遷成本(3萬元/戶)、裝修補貼(30萬元/戶)和面積差價補償。
????????我們再對模型使用模擬退火算法進行全局優化,模擬退火(simulated annealing, SA)算法是一種基于固體退火過程來搜索全局最優解的算法[2],用于在求解空間中尋找近似最優解,使用模型退火輔助對目標模型的計算。模擬退火用于拐點存在性分析模型的具體流程如下圖:
圖2 模擬退火應用該模型流程
????????初始化參數包括初始溫度T=1000,最低溫度Tmin=1,溫度衰減系數alpha=0.95;主循環通過隨機改變院落的順序,計算新解的總成本和總收益,同時依據溫度衰減系數降低溫度,最終輸出結果。
3.2 模型的評估
????????我們為了能夠評估上述模型的性能,我們通過結果可視化,關鍵指標計算,模型穩定性以及搬遷方案合理性檢查。
????????通過設計收斂性分析繪制性價比與迭代次數的關系變化曲線,在通過關鍵指標的穩定性評分,對遷移方案的驗證等角度對模型進行的分析。下面是結果可視化包括變化曲線,標記最大性價比點以及計算收斂速度如下圖:
圖 3 可視化收斂性分析
????????通過對結果的可視化收斂性進行分析判斷,我們通過退火算法輔助模型尋找拐點,利用退火算法的特點,充分的體現出了模型的穩定性,通過搬遷成本的分布體現出模型的有利性。
????????我們再通過對模型穩定性進行評分和對遷移方案的驗證兩個角度,對模型結果提出檢驗,評估詳細的結果如下表:
表4 穩定性評分和遷移方案檢驗表
穩定性評分(1.0表示最穩定) | 總移動次數 | 重復的目標圖 | 約束違規 |
1.00 | 111 | 19 | 0 |
????????通過可視化以及各個指標的驗證充分體現出模型的穩定性和可靠性,再使用退火算法的輔助,能夠解決大部分類似于問題三的現實情況。
3.2 結果計算
????????依據對建立模型的分析,驗證了模型的穩定性和可靠性,我們使用模型進行計算得出問題三的結果。依據結果顯示,問題存在增益的拐點,拐點的m值為39.19,通過計算最終的成本為3687.53萬元,最終收益為144529.05萬元,最終結果顯示收益達到拐點收終止通過計算,搬遷方案結果表(只展示部分結果,完整結果表如附錄表2)如下:
表5 搬遷規劃結果
原地塊ID | 搬入地塊ID | 搬遷成本 |
210 | 27 | 33.216 |
211 | 11 | 33.072 |
29 | 11 | 33.024 |
30 | 27 | 33.12 |
31 | 4 | 33.288 |
376 | 27 | 33.168 |
224 | 1 | 33.24 |
225 | 6 | 33.432 |
????????通過使用該模型能夠給出很好的搬遷方案。
4.問題四的模型建立與求解
4.1?智能計算“平移置換”決策模型建立
????????結合問題二和問題三的模型計算,我們將兩個問題的模型總結在一起。基于搬遷方案模型和拐點存在性分析模型,我們將使用拐點存在性以及優化后的搬遷方案模型對問題四的智能計算決策模型進行設計。
????????在問題二和問題三的基礎上結合現實考慮,我們對每個居民的資源進行限制,每個居民只能參與搬遷一次。再對下面新的問題四的結果進行說明。
4.2 算法優化介紹
????????我們通過增加約束條件對問題模型進行升級,在文章最后我們對問題模型使用多種優化算法進行檢驗,我們通過對不同算法的評價,能夠為智能計算設計提出有效的方案。下面我們對問題四用到的所有優化算法進行介紹。
????????(1)模擬退火算法
????????我們通過繼續使用問題三的模擬退火算法,結合問題四的模型進行計算,初始解生成,我們將修改問題三的初始解為隨機選擇不沖突的搬遷對構成初始可行解,并確保每個居民和空地塊最多被選擇一次。退火過程控制隨著溫度降低,接受劣解的概率減小,在高溫階段廣泛探索,低溫階段精細探索的方式,對問題進行求解。
????????(2)灰狼算法
????????灰狼算法優化實現了灰狼的社會等級,模擬了灰狼的狩獵行為;通過位置更新機制,每只狼的位置根據等級進行更新,使用線性遞減的參數來控制探索和開發;適應度函數通過考慮騰空院落的收益情況以及搬遷的總成本和性價比約束。我們通過顯示每次狼的等級變化來改變住戶的舒適度,通過這種方式計算問題。
????????(3)量子群優化算法
????????首先我們通過每個粒子代表一個可能搬遷的方案,使用量子旋轉門來更新粒子狀態,同時考慮到了問題的約束條件。計算函數通過計算院落的總收益,總成本以及確保解決方案滿足性價比閾值要求。更新機制依據當前解、個人最優和全局最優來調整量子為,同時使用概率來決定是否選擇某個搬遷對。最終計算出問題解。
????????(4)遺傳算法
????????遺傳算法(genetic algorithm,GA)的基本思想是通過逐代進化的方式來優化一個種群,根據自然選擇的原則,優秀個體被篩選并傳遞到后代中[3]。遺傳算法的個體表示,每個個體是一個二進制串,長度等于有效搬遷對的數量,1表示選擇該搬遷對,0表示不選擇。計算函數檢查解的有效性,計算騰出院落的總收益,確保性價比的準確約束。遺傳算子約束,選擇最為競標賽選擇,交叉方式是兩點交叉,變異屬于是位翻轉變異。參數設置,我們將種群大小設為100,進化代數為50,交叉概率0.7,變異概率設置為0.2。最終計算出問題答案。
????????(5)鯨魚優化算法
????????鯨魚優化算法模擬了座頭鯨在捕食過程中的行為,參考了座頭鯨具有獨特的"氣泡網捕食”技術,即鯨魚在捕捉獵物的過程中,通過圍繞獵物做出螺旋上升的運動,最終捕捉獵物。鯨魚優化算法利用這種捕獵模式,通過模擬鯨魚在捕食過程中對獵物的搜索與包圍來解決復雜的優化問題,鯨魚優化算法的基本思想是通過鯨魚個體的圍捕行為(局部搜索)和螺旋上升運動(全局搜索),在解空間中找到最優解[4]。我們通過模擬鯨魚的行為進行實現代碼,包括包圍獵物鯨魚通過識別獵物位置并包圍它們;使用氣泡網攻擊,鯨魚以螺旋方式接近獵物;鯨魚通過隨機搜索獵物。求解的表示每個鯨魚代表一組搬遷對的集合,并確保每個居民和空地塊最多被選擇一次。參數控制我們將參數從2線性減小到0,控制探索與開發;或者將參數從2到1再減小到0,控制隨機搜索概率;最終概率決定選擇哪種更新策略。優化過程,在早期迭代中更傾向于全局探索,在后期迭代中更傾向于局部開發,通過三種行為模式的動態切換平衡探索與開發。
4.3?算法評價
????????我們通過使用五種優化算法對問題的結果進行對比以及檢驗,通過每個算法的結果正確的反映出適合智能計算軟件框架的算法與模型的結合,下面我們將每種算法的總收益、搬遷總成本以及約束條件的結果以及評價表如下
表6 算法評估表
算法 | 總收益(萬元) | 總成本(萬元) | 總性價比 | 主要特點 |
模擬退火算法 | 137411.55 | 3617.26 | 37.99 | 中等收益,成本控制較好,性價比高 |
灰狼算法 | 141506.85 | 3621.55 | 39.07 | 高收益,成本控制優秀,性價比高 |
量子群優化算法 | 141506.85 | 3619.54 | 39.10 | 與灰狼算法相當,性能略優 |
遺傳算法 | 142472.45 | 42037.42 | 3.39 | 收益最高但成本失控,性價比不達標 |
鯨魚優化算法 | 141506.85 | 3655.58 | 38.71 | 與灰狼算法和量子群相當,性價比略低 |
????????通過結果分析我們再對每個算法的性能進行評判,通過設計綜合評分對每個算法的性能進行評判。綜合評分計算評分方式如下:
綜合評分 = 0.5×收益標準化 + 0.3×成本標準化 + 0.2×性價比標準化
????????紅色虛線表示性價比的最低閾值要求(20),同時通過可視化直觀展示每個算法之間的優缺點。可視化結果如下圖:
圖4 算法性能對比圖
????????結合五種優化算法的結果和評價,對問題四進行說明。最佳選擇算法是:灰狼算法,它的效果最優穩定性強,實用性強,并且參數調節相對簡單;次選量子群優化和鯨魚算法,量子群的性能和灰狼算法性能相同但效果略弱,鯨魚算法結果略遜可以作為備選;不推薦遺傳算法雖然收益最高但成本失控,性價比不達標,模擬退火收益相對較低。
4.4 結果說明
????????該問題通過模型求解,以及模型評價。最終結論使用灰狼算法最為本問題的最佳選擇,其在收益、成本和性價比三個關鍵指標上取得了最佳平衡,且算法穩定性好,并且實現難度適中。灰狼算法的應用給出軟件實現的構架。
圖5軟件實現架構
問題二代碼 import pandas as pd# 讀取數據
data = pd.read_excel('附件一:老城街區地塊信息.xlsx')
# 預處理數據
data['地塊面積'] = data['地塊面積'].astype(float)
data['是否有住戶'] = data['是否有住戶'].astype(int)
# 分離有住戶和無住戶的地塊
occupied = data[data['是否有住戶'] == 1].copy()
vacant = data[data['是否有住戶'] == 0].copy()
# 定義采光舒適度等級
light_comfort = {'南': 1, '北': 1, '東': 2, '西': 3}
# 計算每個院落的統計信息(假設院落ID連續)
max_yard_id = data['院落ID'].max()
yard_stats = pd.DataFrame(index=range(1, max_yard_id + 1))
yard_stats['total_plots'] = data.groupby('院落ID')['地塊ID'].count()
yard_stats['occupied_plots'] = data.groupby('院落ID')['是否有住戶'].sum()
yard_stats['vacant_plots'] = yard_stats['total_plots'] - yard_stats['occupied_plots']
yard_stats['yard_area'] = data.groupby('院落ID')['地塊面積'].sum()
yard_stats = yard_stats.fillna(0).reset_index().rename(columns={'index': '院落ID'})
# 找出可以成為完整院落的候選(當前有住戶但有空置地塊的院落)
candidate_yards = yard_stats[(yard_stats['occupied_plots'] > 0) & (yard_stats['vacant_plots'] > 0)].copy()
candidate_yards['potential_full_area'] = candidate_yards['yard_area']
# 找出可以作為搬遷目標的院落(當前空置地塊較多的院落)
target_yards = yard_stats[yard_stats['occupied_plots'] == 0].copy()
target_yards = target_yards.sort_values('vacant_plots', ascending=False)
# 搬遷補償策略
def can_relocate(source_plot, target_plot):# 面積補償:遷入地塊面積 ≥ 原地塊面積,且 ≤ 原面積的130%area_ok = (target_plot['地塊面積'] >= source_plot['地塊面積']) and \(target_plot['地塊面積'] <= 1.3 * source_plot['地塊面積'])# 采光補償:遷入地塊采光等級 <= 原地塊light_ok = light_comfort[target_plot['地塊方位']] <= light_comfort[source_plot['地塊方位']]return area_ok and light_ok
# 搬遷成本計算
def calculate_cost(source_plot, target_plot, repair=False):cost = 30000 # 溝通成本# 面積損失成本area_diff = target_plot['地塊面積'] - source_plot['地塊面積']if area_diff > 0:rent = 15 if source_plot['地塊方位'] in ['南', '北'] else 8cost += area_diff * rent * 365 * 10 # 按10年計算# 修繕成本if repair:cost += 200000return cost
# 搬遷規劃算法(優化版)
def relocation_plan(occupied, vacant, budget=20000000, max_repair=20):relocated = []total_cost = 0repair_count = 0# 按院落潛在完整面積排序candidate_yards_sorted = candidate_yards.sort_values('potential_full_area', ascending=False)for yard_id in candidate_yards_sorted['院落ID']:yard_plots = data[data['院落ID'] == yard_id]occupied_in_yard = yard_plots[yard_plots['是否有住戶'] == 1]for _, source_plot in occupied_in_yard.iterrows():# 在空置地塊中尋找合適的搬遷目標for _, target_plot in vacant.iterrows():if can_relocate(source_plot, target_plot):# 嘗試不修繕cost = calculate_cost(source_plot, target_plot, repair=False)if total_cost + cost <= budget * 1.3:relocated.append({'source_plot_id': source_plot['地塊ID'],'source_yard_id': yard_id,'target_plot_id': target_plot['地塊ID'],'target_yard_id': target_plot['院落ID'],'area_diff': target_plot['地塊面積'] - source_plot['地塊面積'],'light_improvement': light_comfort[target_plot['地塊方位']] - light_comfort[source_plot['地塊方位']],'cost': cost,'repair': False})vacant = vacant[vacant['地塊ID'] != target_plot['地塊ID']]total_cost += costbreak# 嘗試修繕elif repair_count < max_repair:cost = calculate_cost(source_plot, target_plot, repair=True)if total_cost + cost <= budget * 1.3:relocated.append({'source_plot_id': source_plot['地塊ID'],'source_yard_id': yard_id,'target_plot_id': target_plot['地塊ID'],'target_yard_id': target_plot['院落ID'],'area_diff': target_plot['地塊面積'] - source_plot['地塊面積'],'light_improvement': light_comfort[target_plot['地塊方位']] - light_comfort[source_plot['地塊方位']],'cost': cost,'repair': True})vacant = vacant[vacant['地塊ID'] != target_plot['地塊ID']]total_cost += costrepair_count += 1breakelse:continuereturn pd.DataFrame(relocated), total_cost
# 執行搬遷規劃
relocation_df, total_cost = relocation_plan(occupied, vacant)
# 計算騰出的完整院落
def calculate_full_yards(data, relocation_df):updated_data = data.copy()for _, row in relocation_df.iterrows():updated_data.loc[updated_data['地塊ID'] == row['source_plot_id'], '是否有住戶'] = 0updated_data.loc[updated_data['地塊ID'] == row['target_plot_id'], '是否有住戶'] = 1yard_status = updated_data.groupby('院落ID')['是否有住戶'].sum().reset_index()full_yards = yard_status[yard_status['是否有住戶'] == 0]full_yards_area = updated_data[updated_data['院落ID'].isin(full_yards['院落ID'])]['地塊面積'].sum()return full_yards, full_yards_area
full_yards, full_yards_area = calculate_full_yards(data, relocation_df)# 計算收益(簡化版)
def calculate_revenue(full_yards, data):# 原分散出租收益original_vacant = data[data['是否有住戶'] == 0]original_rent = sum(plot['地塊面積'] * (15 if plot['地塊方位'] in ['南', '北'] else 8)for _, plot in original_vacant.iterrows())# 新整院出租收益full_yards_rent = sum(data[data['院落ID'] == yard_id]['地塊面積'].sum() * 30for yard_id in full_yards['院落ID'])# 毗鄰效益(假設院落ID連續,相鄰院落ID差為1)adjacent_pairs = 0full_yard_ids = set(full_yards['院落ID'])for yard_id in full_yard_ids:if (yard_id + 1) in full_yard_ids:adjacent_pairs += 1if (yard_id - 1) in full_yard_ids:adjacent_pairs += 1adjacent_pairs = adjacent_pairs // 2 # 避免重復計數full_yards_rent *= (1 + 0.2 * adjacent_pairs)return original_rent * 365 * 10, full_yards_rent * 365 * 10original_revenue, new_revenue = calculate_revenue(full_yards, data)
profit = new_revenue - original_revenue - total_cost# 輸出結果
print("問題二搬遷規劃結果:")
print(relocation_df)
relocation_df.to_excel('問題二搬遷規劃結果.xlsx', index=False)
print("\n騰出的完整院落ID:", full_yards['院落ID'].tolist())
print("騰出的完整院落總面積:", full_yards_area)
print("總搬遷成本:", total_cost)
print("十年租金收益(新):", new_revenue)
print("十年租金收益(原):", original_revenue)
print("十年盈利:", profit)問題三代碼import pandas as pd
import random
import math# 加載數據
data = pd.read_excel(r'附件一:老城街區地塊信息.xlsx')
rate_map = {'東': 2, '西': 3, '南': 1, '北': 1}
data['單價'] = data['地塊方位'].map(rate_map)residents = data[data['是否有住戶'] == 1].copy()
vacants = data[data['是否有住戶'] == 0].copy()# 初始化
yard_ids = data['院落ID'].unique()
total_cost = 0
total_benefit = 0
overall_m = [] # 性價比列表
m_step = [] # 推進輪數
moves = []
vacated_yards = []# 模擬退火的初始化
T = 1000 # 初始溫度
T_min = 1 # 最低溫度
alpha = 0.95 # 溫度衰減系數
step = 1# 初始化一個初始解
current_yards = list(yard_ids) # 當前解是所有院落ID的順序
current_cost = total_cost
current_benefit = total_benefit
current_m = current_benefit / current_cost if current_cost != 0 else 0while T > T_min:# 在當前解的鄰域內隨機選擇一個新解new_yards = current_yards.copy()random.shuffle(new_yards) # 隨機改變院落順序作為鄰域解new_total_cost = 0new_total_benefit = 0new_moves = []new_vacated_yards = []new_m = 0# 計算新解的總成本和總收益for yard in new_yards:yard_residents = residents[residents['院落ID'] == yard]if len(yard_residents) == 0 or yard in new_vacated_yards:continueyard_moves = []yard_cost = 0for _, r in yard_residents.iterrows():r_ok = Falsefor _, v in vacants.iterrows():if (v['地塊面積'] >= r['地塊面積'] andv['地塊面積'] <= r['地塊面積'] * 1.3 andrate_map[v['地塊方位']] <= rate_map[r['地塊方位']]):area_diff = max(0, v['地塊面積'] - r['地塊面積'])cost = 3 + 30 + area_diff * rate_map[v['地塊方位']] * 240 / 10000yard_moves.append((r['地塊ID'], v['地塊ID'], cost))yard_cost += costr_ok = Truebreakif not r_ok:breakif len(yard_moves) == len(yard_residents):area = data[data['院落ID'] == yard]['地塊面積'].sum()yard_benefit = area * 30 * 3650 / 10000new_total_cost += yard_costnew_total_benefit += yard_benefitnew_moves.extend(yard_moves)new_vacated_yards.append(yard)if new_total_cost > 0:new_m = new_total_benefit / new_total_costelse:new_m = 0# 判斷是否接受新解new_cost = new_total_cost - current_costif new_m > current_m or random.random() < math.exp((current_m - new_m) / T):current_yards = new_yardscurrent_cost = new_total_costcurrent_benefit = new_total_benefitcurrent_m = new_mvacated_yards = new_vacated_yardsmoves = new_moves# 溫度衰減T *= alpha# 記錄性價比overall_m.append(current_m)m_step.append(step)step += 1# 輸出結果
df_moves = pd.DataFrame(moves, columns=['原地塊ID', '搬入地塊ID', '搬遷成本'])
df_moves.to_excel('問題三搬遷規劃結果.xlsx', index=False)
print(f"推進院落數: {len(vacated_yards)}")
print(f"最終收益: {round(current_benefit, 2)}")
print(f"最終成本: {round(current_cost, 2)}")
print(f"最終性價比 m: {round(current_benefit / current_cost, 2)}")
print(f"收益拐點出現后終止: {True}")
print(f"推進院落ID: {vacated_yards}")問題四代碼 灰狼算法import pandas as pd
import numpy as np
import random
import math
from collections import defaultdict# 讀取數據
data = pd.read_excel(r'附件一:老城街區地塊信息.xlsx')
residents = data[data['是否有住戶'] == 1].copy()
vacants = data[data['是否有住戶'] == 0].copy()# 參數設定
rate_map = {'東': 2, '西': 3, '南': 1, '北': 1}
data['單價'] = data['地塊方位'].map(rate_map)
m_threshold = 20 # 性價比閾值
rent_days = 3650
rent_price = 30 # 每㎡每天收益# 計算院落收益(按整院)
b_k = {}
for k in data['院落ID'].unique():area = data[data['院落ID'] == k]['地塊面積'].sum()b_k[k] = area * rent_price * rent_days / 10000 # 萬元# 計算所有合法搬遷對 (i,j) 的成本
c_ij = {}
valid_pairs = []
for i in residents.index:for j in vacants.index:ri = residents.loc[i]vj = vacants.loc[j]if vj['地塊面積'] >= ri['地塊面積'] and vj['地塊面積'] <= 1.3 * ri['地塊面積']:if rate_map[vj['地塊方位']] <= rate_map[ri['地塊方位']]:diff = max(0, vj['地塊面積'] - ri['地塊面積'])cost = 3 + 30 + diff * rate_map[vj['地塊方位']] * 240 / 10000 # 萬元c_ij[(i, j)] = costvalid_pairs.append((i, j))# 灰狼優化算法實現
class GreyWolfOptimizer:def __init__(self, n_wolves, valid_pairs, residents, vacants, b_k, c_ij, m_threshold, max_iter=100):self.n_wolves = n_wolvesself.valid_pairs = valid_pairsself.residents = residentsself.vacants = vacantsself.b_k = b_kself.c_ij = c_ijself.m_threshold = m_thresholdself.max_iter = max_iter# 創建居民到院落的映射self.resident_to_yard = {i: residents.loc[i]['院落ID'] for i in residents.index}# 初始化狼群self.wolves = []for _ in range(n_wolves):wolf = self.create_random_wolf()self.wolves.append(wolf)# 記錄alpha, beta, delta狼self.alpha = Noneself.alpha_fitness = -float('inf')self.beta = Noneself.beta_fitness = -float('inf')self.delta = Noneself.delta_fitness = -float('inf')def create_random_wolf(self):# 隨機選擇一個有效的搬遷方案solution = {}used_residents = set()used_vacants = set()# 隨機打亂有效對shuffled_pairs = random.sample(self.valid_pairs, len(self.valid_pairs))for i, j in shuffled_pairs:if i not in used_residents and j not in used_vacants:solution[(i, j)] = 1used_residents.add(i)used_vacants.add(j)else:solution[(i, j)] = 0return solutiondef evaluate_fitness(self, solution):# 計算總收益moved_residents = set()for (i, j), val in solution.items():if val > 0.5: # 認為大于0.5表示選擇了這個搬遷對moved_residents.add(i)# 計算騰空的院落yard_residents = defaultdict(list)for i in self.residents.index:yard_residents[self.resident_to_yard[i]].append(i)vacant_yards = []for yard, residents in yard_residents.items():if all(r in moved_residents for r in residents):vacant_yards.append(yard)total_benefit = sum(self.b_k[yard] for yard in vacant_yards)# 計算總成本total_cost = sum(self.c_ij[pair] for pair, val in solution.items() if val > 0.5)# 如果總成本為0,避免除以0if total_cost == 0:return -float('inf')# 檢查性價比約束m = total_benefit / total_costif m < self.m_threshold:return -float('inf') # 不滿足約束的解決方案給予極低適應度return total_benefitdef update_hierarchy(self):# 評估所有狼并更新alpha, beta, deltafitnesses = [self.evaluate_fitness(wolf) for wolf in self.wolves]# 找到前三名sorted_indices = np.argsort(fitnesses)[::-1] # 降序排列# 更新alphaif fitnesses[sorted_indices[0]] > self.alpha_fitness:self.alpha = self.wolves[sorted_indices[0]].copy()self.alpha_fitness = fitnesses[sorted_indices[0]]# 更新betaif len(self.wolves) > 1 and fitnesses[sorted_indices[1]] > self.beta_fitness:self.beta = self.wolves[sorted_indices[1]].copy()self.beta_fitness = fitnesses[sorted_indices[1]]# 更新deltaif len(self.wolves) > 2 and fitnesses[sorted_indices[2]] > self.delta_fitness:self.delta = self.wolves[sorted_indices[2]].copy()self.delta_fitness = fitnesses[sorted_indices[2]]def update_position(self, wolf, a):new_wolf = {}for pair in self.valid_pairs:# 獲取alpha, beta, delta的決策alpha_decision = self.alpha.get(pair, 0)beta_decision = self.beta.get(pair, 0)delta_decision = self.delta.get(pair, 0)# 計算A1, A2, A3A1 = 2 * a * random.random() - aC1 = 2 * random.random()D_alpha = abs(C1 * alpha_decision - wolf.get(pair, 0))X1 = alpha_decision - A1 * D_alphaA2 = 2 * a * random.random() - aC2 = 2 * random.random()D_beta = abs(C2 * beta_decision - wolf.get(pair, 0))X2 = beta_decision - A2 * D_betaA3 = 2 * a * random.random() - aC3 = 2 * random.random()D_delta = abs(C3 * delta_decision - wolf.get(pair, 0))X3 = delta_decision - A3 * D_delta# 新位置是三個領導狼決策的平均new_position = (X1 + X2 + X3) / 3# 轉換為二進制決策if random.random() < 1 / (1 + math.exp(-new_position)):new_wolf[pair] = 1else:new_wolf[pair] = 0return new_wolfdef optimize(self):# 初始化alpha, beta, deltaself.update_hierarchy()for iter in range(self.max_iter):# 線性遞減的a值a = 2 - iter * (2 / self.max_iter)# 更新每只狼的位置new_wolves = []for wolf in self.wolves:new_wolf = self.update_position(wolf, a)new_wolves.append(new_wolf)self.wolves = new_wolves# 更新等級self.update_hierarchy()print(f"Iteration {iter + 1}, Alpha Fitness: {self.alpha_fitness}")return self.alpha, self.alpha_fitness# 運行灰狼優化算法
gwo = GreyWolfOptimizer(n_wolves=30,valid_pairs=valid_pairs,residents=residents,vacants=vacants,b_k=b_k,c_ij=c_ij,m_threshold=m_threshold,max_iter=100
)best_solution, best_fitness = gwo.optimize()# 解析最優解
moves = [pair for pair, val in best_solution.items() if val > 0.5]# 計算騰空的院落
moved_residents = set(i for (i, j) in moves)
yard_residents = defaultdict(list)
for i in residents.index:yard_residents[residents.loc[i]['院落ID']].append(i)vacant_yards = []
for yard, residents_list in yard_residents.items():if all(r in moved_residents for r in residents_list):vacant_yards.append(yard)# 計算總收益和總成本
total_benefit = sum(b_k[yard] for yard in vacant_yards)
total_cost = sum(c_ij[pair] for pair in moves)print(f"\n騰空完整院落數:{len(vacant_yards)}")
print(f"騰空院落 ID 列表:{vacant_yards}")
print(f"\n總收益:{round(total_benefit, 2)} 萬元")
print(f"總成本:{round(total_cost, 2)} 萬元")
print(f"總體性價比 m:{round(total_benefit / total_cost, 2)}")