日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

图论解决复杂路口红绿灯安排,python语言实现

發布時間:2024/7/23 python 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图论解决复杂路口红绿灯安排,python语言实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 問題描述
    • 說明性描述
    • 操作性描述
      • 圖著色問題
      • 圖著色算法
  • 算法精化和python描述
    • 算法細節處理:
    • python實現
    • 討論

問題描述

說明性描述

說明性描述說明了需要解決的問題是什么,針對什么樣的問題,期望什么樣的解

這是一個5條路的交叉口,其中兩條是單行線。這個圖本身已經是實際問題的抽象,與行駛方向無關的因素如道路方位、寬度、車流量等都已被抽象去除。要求設計紅綠燈,按不同方向行駛的車輛不能相互沖突,依次通過;在此基礎上,要求紅綠燈輪轉次數最少。
現在基本想法是對行駛方向分組

  • 同屬一組的各個方向行駛的車輛,均可以同時行駛,不出現相互交錯的行駛路線
  • 所做的分組應該盡可能大

操作性描述

操作性描述說明通過怎樣的操作過程可以得到所要的解
采用圖來進一步抽象問題,其中頂點集VVV中的頂點元素表示所有可能可行方向,不難列出本例一共13個:AB, AC, AD, BA, BC, BD, DA, DB, DC, EA, EB, EC, ED。邊集EEE中的元素表示兩個頂點所代表的可行方向有沖突。

有了沖突圖,尋找安全分組的問題就可以換一種說法:為沖突圖中的頂點確定一種分組,保證屬于同一組的頂點互不鄰接。

要解決的問題進一步抽象為圖數據結構上的頂點分組。

圖著色問題

以非相鄰為條件的最佳頂點分組問題,其實對應于有名的圖最佳著色問題:把頂點看成區域,把相鄰看成兩個頂點有邊界,把不同分組看做給相鄰頂點以不同顏色著色。著名的四色問題表明,對于任一方式分割為區域的平面圖,只需要4種顏色著色,就能保證相鄰區域都具有不同顏色。

但是,從交叉路口構造出的沖突圖可能不是平面圖,因此完全可能需要更多的顏色。

圖著色算法

現有的最佳著色算法基本相當于枚舉所有可能的著色方案,從中選出使用顏色最少的方案。
下面考慮使用貪婪算法,或稱貪心法。其基本思想是根據當時掌握的信息,盡可能地向得到解的方向前進,直到不能繼續再換一個方向。這樣做通常不能得到最優解,但能找到“可接受的”解,即給出一種較好的算法。
算法梗概(偽代碼)如下:

輸入:圖G #記錄圖中的頂點連接關系 集合verts保存G中的所有頂點 #建立初始狀態 設置集合groups為空集 #記錄得到的分組,元素是頂點集合 while 存在未著色的頂點: #每次迭代用貪心法找一個新分組選一種顏色在未著色頂點中給盡量多的無互連邊的點著色(構建一個分組)記錄新分組的頂點組# 算法結束時,groups里記錄著一種分組方式 # 算法細節還需要進一步考慮

上面算法還有重要的細節要考慮:一種新顏色的著色處理。具體:

  • 圖G保存需著色圖中頂點的鄰接信息;
  • 集合verts是圖中所有尚未著色的頂點集合;
  • 用另一個變量new_group記錄正在構造的用當前新顏色著色的頂點(一個頂點),在上面算法的每次迭代中重新構造,每次重新分組時將這個集合重新設置為空集。
# 進一步整理著色問題。 new_group = 空集 for v in verts:if v與new_group中所有的頂點之間都沒有邊:從verts中去掉v把v加入new_group # 循環結束時,new_group中是可以用一種顏色著色的頂點集合。 # 用這段代碼代替前面程序框架中主循環體里的一部分。

檢查上面的算法,可以看到算法涉及一些集合操作圖操作

  • 構造空集
  • 從集合中刪除元素
  • 向集合中加入元素
  • 順序獲取集合里的各個元素(使用for循環)
  • 獲取圖中所有頂點
  • 判斷兩個頂點是否相鄰
  • 算法精化和python描述

    算法細節處理:

  • 如何表示顏色? 順序整數;
  • 如何記錄得到的分組?用集合表示分組,把構造好的分組(集合)加入groups作為元素;
  • 如何表示圖結構?
  • python的集合操作:
    10. 判斷集合vs是否空集:not vs
    11. 設置一個集合為空:vs = set()
    12. 從集合中去掉一個元素:vs.remove(v)
    13. 向集合中增加一個元素:vs.add(v)

    python的集合數據類型不支持遍歷,需要從當時的集合verts生成一個表,然后對表做遍歷。
    算法中需要的圖操作依賴于,如何在python中實現圖數據結構,這里假定兩個與圖有關的操作:

  • 函數vertices(G)得到G中所有頂點的集合;
  • 謂詞 not_adjacent_with_set(v, group, G)檢查頂點v與頂點集group中各頂點在圖G中是否有邊連接。
  • 有了以上假設,就可以寫程序:

    python實現

    def coloring(G): #做圖G的著色color = 0groups = set()verts = vertices(G) #取得G圖的所有頂點,依賴于圖的表示while verts:new_group = set()for v in list(verts):if not_adjacent_with_set(v, newgroup, G):new_group.add(v)verts.remove(v)group.add((color, new_group))color += 1return groups

    這個python函數能對任何一個圖算出頂點分組。其中欠缺的細節就是圖的表示,以及函數里設計的兩個圖操作

    討論

    對于給定的交叉路口實例,可行的分組可能不唯一。算法給出的解是確定的,依賴于算法中選擇頂點的具體策略,以及對圖中頂點的遍歷順序,即**list(verts)**給出的頂點序列中的順序。
    回顧前面從問題出發做出一個python程序的工作過程:

  • 有關工作開始于交叉路口的抽象圖示,首先枚舉出所有允許通行方向;
  • 根據通行方向和沖突的定義,畫出沖突圖;
  • 通行方向分組問題歸結為沖突圖中不相鄰頂點的劃分問題
  • 問題是,這樣的結果滿足原交叉路口實例的需要嗎?

    仔細分析,上面算法中采取的定義不統一:

    算法給出的結果是各分組互不相交,每個頂點只屬于一個分組;而工作實際是只要求同屬一組的頂點是互不沖突的,即允許頂點屬于不同分組的情況。

    需要將之前得到的分組盡可能擴充,加入與已有分組不沖突的方向,如何修改前面算法,使之能給出這樣分組?

    總結

    以上是生活随笔為你收集整理的图论解决复杂路口红绿灯安排,python语言实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。