国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

拓撲排序算法有什么作用

算法與數據結構 ? 來源:bigsai ? 作者:bigsai ? 2021-09-24 10:53 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

大家好,我是bigsai。

拓撲排序,很多人都可能聽說但是不了解的一種算法。不知者大多會提出這樣的疑問:

這是某種排序算法?這好像是一種圖論算法?圖也能排序?

非線性結構在傳統意義上確實不太好排序,而拓撲排序它是對有向圖的頂點排成一個線性序列。并且不一定唯一。

什么是拓撲排序?

對一個有向無環圖(Directed Acyclic Graph簡稱DAG)G進行拓撲排序,是將G中所有頂點排成一個線性序列,使得圖中任意一對頂點u和v,若邊∈E(G),則u在線性序列中出現在v之前。通常,這樣的線性序列稱為滿足拓撲次序(Topological Order)的序列,簡稱拓撲序列。簡單的說,由某個集合上的一個偏序得到該集合上的一個全序,這個操作稱之為拓撲排序。

拓撲排序有何作用?

拓撲排序的應用其實還是蠻多的,拓撲排序在一些工程有多道工序時候可以獲取一個有效的加工順序、還有些游戲里的任務成就必須滿足一個符合的拓撲排序才能解鎖下一關、還有一些項目或者環境的依賴關系集……

當然上面的例子可能不夠具體,離我們稍微近一點的就是課程學習上,比如你學習數據結構之前基本要學習C或者C++這門課,因為數據結構中需要懂和會用C++的代碼;學習操作系統、計算機網絡之前要學習數據結構這門課,因為里面涉及到很多數據結構和算法;學習Java Web開發前要學習JavaSE和HTML這兩門課;不同院校課程安排截然不同但均能很好的連接起來,就是因為安排的課程滿足一個拓撲排序。

拓撲排序還是不能理解?我舉個更詳細的例子,學習Java系列的教程部分,可能有下面這個順序:

ec4e533c-11e5-11ec-8fb8-12bb97331649.png

就比如學習Java系類(部分)從Java基礎,到JSP/Servlet,到SSM,到SpringBoot,SpringCloud等是個循序漸進、且有前提依賴的過程。在JSP學習要首先掌握Java基礎和HTML基礎。學習框架要掌握JSP/Servlet和JDBC之類才行。那么,這個學習過程即構成一個拓撲序列。當然這個序列也不唯一,你可以對不關聯的學科隨意選擇順序(比如Html和Java可以隨便先開始哪一個)。

那上述序列可以簡單表示為:

這五種均為可以選擇的學習方案,對課程安排可以有參考作用,這五個都是上面有向無環圖(DAG)的拓撲序列,只是小的選擇的策略不同(先學Java或者先學HTML不要緊,但是要滿足整個順序要求),不影響滿足規則順序!

對于拓撲排序,還有一些比較專業的名詞需要銘記:

DAG:有向無環圖

AOV網:數據在頂點,頂點表示活動,邊表示活動的先后關系,可以理解為一種面向對象。

AOE網:數據在邊上,頂點表示事件,有向邊表示活動,邊上的權值表示該活動持續的時間,可以理解為面向過程。

很多人不知道AOE網干啥用的,拓撲排序是解決一個工程能否順序進行的問題,但有時還需解決工程完成需要的最短時間。而AOE經常使用在求關鍵路徑中(這里就先不進行詳細介紹內容和算法了),圖片來源https://www.cnblogs.com/svod5306/p/14723338.html)。

我們今天講的拓撲排序就是在AOV中找到不破壞圖結構的序列,對于有向無環圖,需要注意一下圖中:若A在B前面,則不存在B在A前面的路徑(不能成環)。圖中兩個相鄰節點在拓撲序列中只需要滿足前后關系而不一定需要相鄰(節點只需滿足相對的前后關系,所以拓撲排序并不一定唯一)。

算法分析上面簡單的介紹了拓撲排序,下面詳細講講拓撲排序的求法。

正常步驟為(方法不一定唯一):

1.從DAG圖中找到一個沒有前驅的頂點輸出。可以遍歷入度為0的節點,也可以用優先隊列維護。

2.刪除以這個點為起點的邊。刪除一條邊,其指向節點的入度減1,這樣為了找到下個沒有前驅節點的頂點。

3.重復上述,直到最后一個頂點被輸出。如果還有頂點未被輸出,則說明有環!

對于上圖的簡單序列,可以簡單描述步驟為:

step1:刪除節點1(或者2)及其指向的邊,將節點輸出

step2:刪除節點2(或者3)及其指向的邊,將節點輸出

step2(這里進行兩步):刪除節點3(或者4)及其指向的邊,將節點輸出,緊接著刪除節點3(或者6)其指向的邊,將節點輸出。

step3:按照上述規則重復進行,直到所有節點都被刪除。

這樣就完成一次拓撲排序流程,得到一個拓撲序列,但是這個序列并不唯一,從算法執行過程中也看到有很多選擇方案,具體得到結果看你算法的設計了,但只要滿足DAG圖中前后相對關系。

另外觀察 1 2 4 3 6 5 7 8 這個序列滿足我們所說的有關系的節點指向的在前面,被指向的在后面。如果完全沒關系那不一定前后(例如1,2)

代碼實現對于拓撲排序,如何用代碼實現呢?

雖然在上面詳細介紹了思路和流程,也很通俗易懂,但是實際上代碼的實現還是很需要斟酌的,如何在空間和時間上能夠得到較好的平衡且取得較好的效率?

首先要考慮存儲,對于節點,是用鄰接矩陣還是鄰接表存儲呢,通常拓撲排序如果使用矩陣存儲都是比較稀疏的,比較浪費內存空間,這里還是使用鄰接表來存儲節點。

另外,如果圖中節點是1,2,3,4,5,6這樣的有序編號,我們可以直接用數組,但是如果遇到1,2,88,9999類似不連續跨度很大編號節點,也可以考慮用Map存儲映射一下位置。

那么我們具體的代碼思想為:

①新建node類,包含節點數值和它的指向節點集合(這里直接用List集合)

②初始化一個人node數組,輸入/枚舉節點之間關系,被指向的節點入度+1!(例如A—》C)那么C的入度+1;

③掃描所有node(這里掃描數組)。將所有入度為0的點加入一個容器棧(隊列)中。

④當棧(隊列)不空的時候,拋出其中任意一個node(只要入度為零可以隨便選擇順序)。將node輸出,并且node指向的所有節點入度減1。如果某個點的入度被減為0,那么就將它加入棧(隊列)。

⑤重復上述操作,直到棧(隊列)為空。

這里主要是利用棧或者隊列儲存入度只為0的節點,只需要初次掃描表將入度為0的放入棧(隊列)中。

因為節點之間是有相關性的,一個節點若想入度為零,那么它的前驅節點點肯定在它前入度為0,拆除關聯箭頭將自己入度減1,在一個有向無環圖中總會有大于等于1個入度為0的節點。

在具體實現上,方式是有多樣的,我的這個只是一個簡單的演示,效率不一定很高,大家參考一下即可。

具體實現代碼為:

import java.util.ArrayDeque;

import java.util.ArrayList;

import java.util.List;

import java.util.Queue;

import java.util.Stack;

public class tuopu {

static class node

{

int value;

List《Integer》 next;

public node(int value) {

this.value=value;

next=new ArrayList《Integer》();

}

public void setnext(List《Integer》list) {

this.next=list;

}

}

public static void main(String[] args) {

// TODO Auto-generated method stub

node []nodes=new node[9];//儲存節點

int a[]=new int[9];//儲存入度

List《Integer》list[]=new ArrayList[10];//臨時空間,為了存儲指向的集合

for(int i=1;i《9;i++)

{

nodes[i]=new node(i);

list[i]=new ArrayList《Integer》();

}

initmap(nodes,list,a);

//主要流程

//Queue《node》q1=new ArrayDeque《node》();

Stack《node》s1=new Stack《node》();

for(int i=1;i《9;i++)

{

//System.out.print(nodes[i].next.size()+“ 55 ”);

//System.out.println(a[i]);

if(a[i]==0) {s1.add(nodes[i]);}

}

while(!s1.isEmpty())

{

node n1=s1.pop();//拋出輸出

System.out.print(n1.value+“ ”);

List《Integer》next=n1.next;

for(int i=0;i《next.size();i++)

{

a[next.get(i)]--;//入度減一

if(a[next.get(i)]==0)//如果入度為0

{

s1.add(nodes[next.get(i)]);

}

}

}

}

private static void initmap(node[] nodes, List《Integer》[] list, int[] a) {

list[1].add(3);

nodes[1].setnext(list[1]);

a[3]++;

list[2].add(4);list[2].add(6);

nodes[2].setnext(list[2]);

a[4]++;a[6]++;

list[3].add(5);

nodes[3].setnext(list[3]);

a[5]++;

list[4].add(5);list[4].add(6);

nodes[4].setnext(list[4]);

a[5]++;a[6]++;

list[5].add(7);

nodes[5].setnext(list[5]);

a[7]++;

list[6].add(8);

nodes[6].setnext(list[6]);

a[8]++;

list[7].add(8);

nodes[7].setnext(list[7]);

a[8]++;

}

}

輸出結果

2 4 6 1 3 5 7 8

當然,上面說過用棧和隊列都可以!如果使用隊列就會得到1 2 3 4 5 6 7 8 的拓撲序列

至于圖的構造,因為沒有條件可能效率并不高,算法也可能不太完美,如有優化錯誤還請大佬指正!

拓撲排序找環前面說到,拓撲排序需要在有向無環圖中才能得到一個拓撲序列,但是如果給定一個有向圖,怎么知道它是否可以形成一個拓撲序列呢?

當然是在拓撲排序算法上進行改動,我們在進行拓撲排序會刪除所有入度為0的節點,但是如有有環那么刪除節點個數就小于所有節點個數,在具體實現上,我們只需要在棧或者隊列拋出時候通過一個計數器統計數字即可。

當然這個問題力扣207有原題可以看看自己代碼是否能夠ac,問題描述:

你這個學期必須選修 numCourses 門課程,記為 0 到 numCourses - 1 。

在選修某些課程之前需要一些先修課程。先修課程按數組 prerequisites 給出,其中 prerequisites[i] = [ai, bi] ,表示如果要學習課程 ai 則 必須 先學習課程 bi 。

例如,先修課程對 [0, 1] 表示:想要學習課程 0 ,你需要先完成課程 1 。

請你判斷是否可能完成所有課程的學習?如果可以,返回 true ;否則,返回 false 。

分析上面已經給出,不過在具體實現代碼的時候比較靈活,不一定非得創建node類,思路上理的清即可。

實現代碼:

class Solution {

public boolean canFinish(int numCourses, int[][] prerequisites) {

int indegree[]=new int[numCourses];

List《Integer》 next[]=new ArrayList[numCourses];

for(int i=0;i《numCourses;i++){

next[i]=new ArrayList();

}

for(int i=0;i《prerequisites.length;i++) {

int preid=prerequisites[i][1];

int courseid=prerequisites[i][0];

indegree[courseid]++;//入度加一

next[preid].add(courseid);//next指向

}

Queue《Integer》queue=new ArrayDeque《》();

for(int i=0;i《numCourses;i++) {//加入入度為0的節點

if(indegree[i]==0){

queue.add(i);

}

}

int nodeNum=0;//判斷刪除節點數量 入度為0刪除 如果刪除所有那么返回true

while (!queue.isEmpty())

{

nodeNum++;

int nodeId=queue.poll();

for(int i=0;i《next[nodeId].size();i++)

{

int nodeIndex=next[nodeId].get(i);

indegree[nodeIndex]--;

if(indegree[nodeIndex]==0) {

queue.add(nodeIndex);

}

}

}

if(nodeNum==numCourses)

return true;

return false;

}

}

好了,到這里拓撲排序內容講解完畢!

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • JAVA
    +關注

    關注

    20

    文章

    3001

    瀏覽量

    116421
  • 拓撲結構
    +關注

    關注

    6

    文章

    332

    瀏覽量

    41082
  • 代碼
    +關注

    關注

    30

    文章

    4967

    瀏覽量

    73958

原文標題:排個課表學會了拓撲排序!有點意思

文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數據結構】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    MAX16050/MAX16051:電壓監測與排序電路的理想選擇

    MAX16050/MAX16051:電壓監測與排序電路的理想選擇 在電子設計領域,對于電壓監測和電源排序的需求日益增長,特別是在服務器、工作站、網絡系統等復雜設備中。今天,我們就來深入探討
    的頭像 發表于 03-02 09:15 ?57次閱讀

    ADM1066:多功能電源監控與排序芯片的深度解析

    ADM1066:多功能電源監控與排序芯片的深度解析 在電子設備的設計中,電源的監控與排序是確保系統穩定運行的關鍵環節。ADM1066作為一款功能強大的電源監控與排序芯片,為多電源系統提供了全面
    的頭像 發表于 02-28 14:05 ?73次閱讀

    ADM1169:多電源系統的監控與排序解決方案

    ADM1169:多電源系統的監控與排序解決方案 在電子工程師的日常工作中,多電源系統的監控與排序是一個關鍵且復雜的問題。今天要為大家介紹的Analog Devices的ADM1169 Super
    的頭像 發表于 02-28 11:10 ?125次閱讀

    ADM1166:多電源系統監控與排序的理想解決方案

    ADM1166:多電源系統監控與排序的理想解決方案 在多電源系統的設計中,對電源的監控和排序是至關重要的環節。ADM1166作為一款可配置的監控/排序設備,為多電源系統的電源監控和排序
    的頭像 發表于 02-28 11:10 ?129次閱讀

    探索LM3880:三軌簡單電源排序器的卓越性能與應用

    探索LM3880:三軌簡單電源排序器的卓越性能與應用 在電子設計領域,電源管理是一個至關重要的環節。今天,我們將深入探討德州儀器(TI)推出的LM3880三軌簡單電源排序器,它為多電壓軌的電源排序
    的頭像 發表于 02-26 17:20 ?493次閱讀

    MAX16050/MAX16051:具備反向排序功能的電壓監控與排序電路

    MAX16050/MAX16051:具備反向排序功能的電壓監控與排序電路 在電子系統設計中,對電源電壓的精確監控和有序控制至關重要。Maxim Integrated推出的MAX16050
    的頭像 發表于 01-31 17:15 ?780次閱讀

    C語言插入排序算法和代碼

    插入排序排序算法的一種,它不改變原有的序列(數組),而是創建一個新的序列,在新序列上進行操作。   這里以從小到大排序為例進行講解。   基本思想及舉例說明   插入
    發表于 01-15 06:44

    光纖線芯都是按照什么顏色排序

    多次朋友留言問到,光纖熔接顏色如何排序,這個在實際應用中還是比較多的,那么今天我們就不講原理了,直接用圖文簡單明了講光纖熔接色譜,大家可以了解下。 一、常規排序 1、4芯的排序:藍、
    的頭像 發表于 12-19 11:02 ?1371次閱讀

    C語言的常見算法

    # C語言常見算法 C語言中常用的算法可以分為以下幾大類: ## 1. 排序算法 ### 冒泡排序 (Bubble Sort) ```
    發表于 11-24 08:29

    PPEC Workbench 平臺拓撲全覆蓋,滿足各類電源開發需求

    ) 智能化拓撲開發工具 ▌拓撲參數預配置: 針對選定拓撲,自動生成初始參數范圍(如電感 / 電容值、開關頻率等),減少基礎參數計算的工作量。 ▌算法自定義支持: AI 智能助手可輔助
    發表于 10-23 11:44

    結合AI算法的邊緣計算服務器,在城市管理場景什么作用

    桿塔安家落戶,日夜守護城市平安和高效運轉。以國內資深安防硬件廠家廣東天波的AI邊緣計算服務器為例,可以適配云天勵飛的AI算法,在城市管理場景中發揮大作用:1、井蓋異常:邊緣計算服務器
    的頭像 發表于 10-17 15:31 ?428次閱讀
    結合AI<b class='flag-5'>算法</b>的邊緣計算服務器,在城市管理場景<b class='flag-5'>有</b>什么<b class='flag-5'>作用</b>?

    PPEC電源DIY套件:圖形化算法編程,解鎖電力電子底層算法實踐

    開關電源拓撲的搭建與驗證。 2、進階調試與優化 ▌電源參數可調: 通過PPEC Workbnch 電力電子智能化設計平臺調節輸出電壓、電流、開關頻率等,實現恒壓/恒流模式切換。 ▌底層算法可視化自定義
    發表于 08-14 11:30

    開關電源功率變換器拓撲與設計

    詳細講解開關電源功率變換器的各種拓撲電路,通過實例詳細講解。 共分為12章,包括功率變換器的主要拓撲介紹和工程設計指南兩大部分內容。其中,拓撲部分主要包括正激、反激、對稱驅動橋式、隔離Boost
    發表于 05-19 16:26

    開關電源拓撲結構介紹

    一 、緒論開關電源電路拓撲是指功率器件和電磁元件連接在電路中的方式,而磁性元件設計、閉環補償電路以及所有其他電路元件的設計都依賴于拓撲拓撲可分為:開關型和非開關型兩大類。其中開關型拓撲
    發表于 05-12 16:04

    智慧路燈哪些功能和作用

    智慧路燈哪些功能和作用 智慧燈桿屏
    的頭像 發表于 03-20 17:00 ?1214次閱讀
    智慧路燈<b class='flag-5'>有</b>哪些功能和<b class='flag-5'>作用</b>