貪心算法應用:最小反饋頂點集問題詳解

在這里插入圖片描述

貪心算法應用:最小反饋頂點集問題詳解

1. 問題定義與背景

1.1 反饋頂點集定義

反饋頂點集(Feedback Vertex Set, FVS)是指在一個有向圖中,刪除該集合中的所有頂點后,圖中將不再存在任何有向環。換句話說,反饋頂點集是破壞圖中所有環所需刪除的頂點集合。

1.2 最小反饋頂點集問題

最小反饋頂點集問題是指在一個給定的有向圖中,尋找一個最小的反饋頂點集,即包含頂點數量最少的反饋頂點集。這是一個經典的NP難問題,在實際應用中有著廣泛的需求。

1.3 應用場景

  • 死鎖檢測與預防:在操作系統中識別和打破進程間的循環等待
  • 電路設計:避免邏輯電路中的反饋循環
  • 生物信息學:分析基因調控網絡
  • 軟件工程:分析程序控制流圖中的循環結構

2. 貪心算法原理

2.1 貪心算法基本思想

貪心算法是一種在每一步選擇中都采取當前狀態下最優的選擇,從而希望導致結果是全局最優的算法策略。對于最小反饋頂點集問題,貪心算法的基本思路是:

  1. 識別圖中最有可能破壞多個環的頂點
  2. 將該頂點加入反饋頂點集
  3. 從圖中移除該頂點及其相關邊
  4. 重復上述過程直到圖中不再有環

2.2 貪心策略選擇

常見的貪心策略包括:

  • 最大度數優先:選擇當前圖中度數最大的頂點
  • 最大環參與度:選擇參與最多環的頂點
  • 權重策略:在有頂點權重的情況下,選擇權重與度數比最優的頂點

3. Java實現詳細解析

3.1 圖的數據結構表示

我們首先需要定義圖的表示方式。在Java中,可以使用鄰接表來表示有向圖。

import java.util.*;public class DirectedGraph {private Map<Integer, List<Integer>> adjacencyList;private Set<Integer> vertices;public DirectedGraph() {this.adjacencyList = new HashMap<>();this.vertices = new HashSet<>();}public void addVertex(int vertex) {vertices.add(vertex);adjacencyList.putIfAbsent(vertex, new ArrayList<>());}public void addEdge(int from, int to) {addVertex(from);addVertex(to);adjacencyList.get(from).add(to);}public List<Integer> getNeighbors(int vertex) {return adjacencyList.getOrDefault(vertex, new ArrayList<>());}public Set<Integer> getVertices() {return new HashSet<>(vertices);}public DirectedGraph copy() {DirectedGraph copy = new DirectedGraph();for (int v : vertices) {for (int neighbor : adjacencyList.get(v)) {copy.addEdge(v, neighbor);}}return copy;}public void removeVertex(int vertex) {vertices.remove(vertex);adjacencyList.remove(vertex);for (List<Integer> neighbors : adjacencyList.values()) {neighbors.removeIf(v -> v == vertex);}}
}

3.2 環檢測實現

在實現貪心算法前,我們需要能夠檢測圖中是否存在環。這里使用深度優先搜索(DFS)來實現環檢測。

public boolean hasCycle() {Set<Integer> visited = new HashSet<>();Set<Integer> recursionStack = new HashSet<>();for (int vertex : vertices) {if (!visited.contains(vertex) && hasCycleUtil(vertex, visited, recursionStack)) {return true;}}return false;
}private boolean hasCycleUtil(int vertex, Set<Integer> visited, Set<Integer> recursionStack) {visited.add(vertex);recursionStack.add(vertex);for (int neighbor : adjacencyList.getOrDefault(vertex, new ArrayList<>())) {if (!visited.contains(neighbor)) {if (hasCycleUtil(neighbor, visited, recursionStack)) {return true;}} else if (recursionStack.contains(neighbor)) {return true;}}recursionStack.remove(vertex);return false;
}

3.3 貪心算法實現

基于最大度數優先策略的貪心算法實現:

public Set<Integer> greedyFVS() {Set<Integer> fvs = new HashSet<>();DirectedGraph graphCopy = this.copy();while (graphCopy.hasCycle()) {// 選擇當前圖中度數最大的頂點int vertexToRemove = selectVertexWithMaxDegree(graphCopy);// 添加到反饋頂點集fvs.add(vertexToRemove);// 從圖中移除該頂點graphCopy.removeVertex(vertexToRemove);}return fvs;
}private int selectVertexWithMaxDegree(DirectedGraph graph) {int maxDegree = -1;int selectedVertex = -1;for (int vertex : graph.getVertices()) {int outDegree = graph.getNeighbors(vertex).size();int inDegree = 0;// 計算入度for (int v : graph.getVertices()) {if (graph.getNeighbors(v).contains(vertex)) {inDegree++;}}int totalDegree = outDegree + inDegree;if (totalDegree > maxDegree) {maxDegree = totalDegree;selectedVertex = vertex;}}return selectedVertex;
}

3.4 改進的貪心策略實現

更復雜的貪心策略可以考慮頂點參與環的數量:

public Set<Integer> improvedGreedyFVS() {Set<Integer> fvs = new HashSet<>();DirectedGraph graphCopy = this.copy();while (graphCopy.hasCycle()) {// 選擇參與最多環的頂點int vertexToRemove = selectVertexInMostCycles(graphCopy);fvs.add(vertexToRemove);graphCopy.removeVertex(vertexToRemove);}return fvs;
}private int selectVertexInMostCycles(DirectedGraph graph) {Map<Integer, Integer> cycleCount = new HashMap<>();// 初始化所有頂點的環計數for (int vertex : graph.getVertices()) {cycleCount.put(vertex, 0);}// 使用DFS檢測環并計數for (int vertex : graph.getVertices()) {Set<Integer> visited = new HashSet<>();Stack<Integer> path = new Stack<>();countCyclesUtil(graph, vertex, visited, path, cycleCount);}// 選擇參與最多環的頂點return Collections.max(cycleCount.entrySet(), Map.Entry.comparingByValue()).getKey();
}private void countCyclesUtil(DirectedGraph graph, int vertex, Set<Integer> visited, Stack<Integer> path, Map<Integer, Integer> cycleCount) {if (path.contains(vertex)) {// 發現環,增加路徑上所有頂點的計數int index = path.indexOf(vertex);for (int i = index; i < path.size(); i++) {int v = path.get(i);cycleCount.put(v, cycleCount.get(v) + 1);}return;}if (visited.contains(vertex)) {return;}visited.add(vertex);path.push(vertex);for (int neighbor : graph.getNeighbors(vertex)) {countCyclesUtil(graph, neighbor, visited, path, cycleCount);}path.pop();
}

4. 算法分析與優化

4.1 時間復雜度分析

  • 基本貪心算法:

    • 每次環檢測:O(V+E)
    • 每次選擇頂點:O(V^2)(因為要計算每個頂點的度數)
    • 最壞情況下需要移除O(V)個頂點
    • 總時間復雜度:O(V^3 + V*E)
  • 改進的貪心算法:

    • 環計數實現較為復雜,最壞情況下為指數時間
    • 實際應用中通常需要限制DFS的深度或使用近似方法

4.2 近似比分析

貪心算法提供的是一種近似解法。對于最小反饋頂點集問題:

  • 基本貪心算法的近似比為O(log n log log n)
  • 更復雜的貪心策略可以達到O(log n)近似比
  • 在特殊類型的圖中可能有更好的近似比

4.3 優化策略

  1. 局部搜索優化:在貪心算法得到的解基礎上進行局部優化
  2. 混合策略:結合多種貪心策略,選擇最優解
  3. 并行計算:并行計算各頂點的環參與度
  4. 啟發式剪枝:限制DFS深度或使用隨機游走估計環參與度

5. 完整Java實現示例

import java.util.*;
import java.util.stream.Collectors;public class FeedbackVertexSet {public static void main(String[] args) {// 創建示例圖DirectedGraph graph = new DirectedGraph();graph.addEdge(1, 2);graph.addEdge(2, 3);graph.addEdge(3, 4);graph.addEdge(4, 1); // 形成環1-2-3-4-1graph.addEdge(2, 5);graph.addEdge(5, 6);graph.addEdge(6, 2); // 形成環2-5-6-2graph.addEdge(7, 8);graph.addEdge(8, 7); // 形成環7-8-7System.out.println("原始圖是否有環: " + graph.hasCycle());// 使用基本貪心算法Set<Integer> basicFVS = graph.greedyFVS();System.out.println("基本貪心算法找到的FVS: " + basicFVS);System.out.println("大小: " + basicFVS.size());// 使用改進貪心算法Set<Integer> improvedFVS = graph.improvedGreedyFVS();System.out.println("改進貪心算法找到的FVS: " + improvedFVS);System.out.println("大小: " + improvedFVS.size());// 驗證解的正確性DirectedGraph testGraph = graph.copy();for (int v : improvedFVS) {testGraph.removeVertex(v);}System.out.println("移除FVS后圖是否有環: " + testGraph.hasCycle());}
}class DirectedGraph {// ... 前面的圖實現代碼 ...// 添加一個更高效的貪心算法實現public Set<Integer> efficientGreedyFVS() {Set<Integer> fvs = new HashSet<>();DirectedGraph graphCopy = this.copy();// 使用優先隊列來高效獲取最大度數頂點PriorityQueue<Map.Entry<Integer, Integer>> maxHeap = new PriorityQueue<>((a, b) -> b.getValue() - a.getValue());// 初始化度數表Map<Integer, Integer> degreeMap = new HashMap<>();for (int v : graphCopy.getVertices()) {int degree = graphCopy.getNeighbors(v).size();// 計算入度int inDegree = 0;for (int u : graphCopy.getVertices()) {if (graphCopy.getNeighbors(u).contains(v)) {inDegree++;}}degreeMap.put(v, degree + inDegree);}maxHeap.addAll(degreeMap.entrySet());while (graphCopy.hasCycle()) {if (maxHeap.isEmpty()) break;Map.Entry<Integer, Integer> entry = maxHeap.poll();int vertex = entry.getKey();int currentDegree = degreeMap.getOrDefault(vertex, 0);// 檢查度數是否最新(因為圖可能已經改變)int actualDegree = graphCopy.getNeighbors(vertex).size();int actualInDegree = 0;for (int u : graphCopy.getVertices()) {if (graphCopy.getNeighbors(u).contains(vertex)) {actualInDegree++;}}int totalDegree = actualDegree + actualInDegree;if (totalDegree < currentDegree) {// 度數已變化,重新插入entry.setValue(totalDegree);maxHeap.add(entry);continue;}// 添加到FVSfvs.add(vertex);// 更新鄰居的度數for (int neighbor : graphCopy.getNeighbors(vertex)) {if (degreeMap.containsKey(neighbor)) {degreeMap.put(neighbor, degreeMap.get(neighbor) - 1);}}// 更新指向該頂點的鄰居for (int u : graphCopy.getVertices()) {if (graphCopy.getNeighbors(u).contains(vertex)) {if (degreeMap.containsKey(u)) {degreeMap.put(u, degreeMap.get(u) - 1);}}}// 從圖中移除頂點graphCopy.removeVertex(vertex);degreeMap.remove(vertex);}return fvs;}// 添加一個基于隨機游走的近似環計數方法private int selectVertexInMostCyclesApprox(DirectedGraph graph, int walks, int steps) {Map<Integer, Integer> cycleCount = new HashMap<>();Random random = new Random();List<Integer> vertices = new ArrayList<>(graph.getVertices());for (int v : graph.getVertices()) {cycleCount.put(v, 0);}for (int i = 0; i < walks; i++) {int startVertex = vertices.get(random.nextInt(vertices.size()));int currentVertex = startVertex;Set<Integer> visitedInWalk = new HashSet<>();List<Integer> path = new ArrayList<>();for (int step = 0; step < steps; step++) {List<Integer> neighbors = graph.getNeighbors(currentVertex);if (neighbors.isEmpty()) break;int nextVertex = neighbors.get(random.nextInt(neighbors.size()));if (path.contains(nextVertex)) {// 發現環int index = path.indexOf(nextVertex);for (int j = index; j < path.size(); j++) {int v = path.get(j);cycleCount.put(v, cycleCount.get(v) + 1);}break;}path.add(nextVertex);currentVertex = nextVertex;}}return Collections.max(cycleCount.entrySet(), Map.Entry.comparingByValue()).getKey();}
}

6. 測試與驗證

6.1 測試用例設計

為了驗證算法的正確性和效率,我們需要設計多種測試用例:

  1. 簡單環圖:單個環或多個不相交的環
  2. 復雜環圖:多個相交的環
  3. 無環圖:驗證算法不會返回不必要的頂點
  4. 完全圖:所有頂點之間都有邊
  5. 隨機圖:隨機生成的有向圖

6.2 驗證方法

  1. 移除返回的反饋頂點集后,檢查圖中是否確實無環
  2. 比較不同算法得到的解的大小
  3. 測量算法運行時間

6.3 性能測試示例

public class PerformanceTest {public static void main(String[] args) {int[] sizes = {10, 50, 100, 200, 500};for (int size : sizes) {System.out.println("\n測試圖大小: " + size);DirectedGraph graph = generateRandomGraph(size, size * 2);long start, end;start = System.currentTimeMillis();Set<Integer> basicFVS = graph.greedyFVS();end = System.currentTimeMillis();System.out.printf("基本貪心算法: %d 頂點, 耗時 %d ms%n", basicFVS.size(), end - start);start = System.currentTimeMillis();Set<Integer> efficientFVS = graph.efficientGreedyFVS();end = System.currentTimeMillis();System.out.printf("高效貪心算法: %d 頂點, 耗時 %d ms%n", efficientFVS.size(), end - start);// 對于大圖,改進算法可能太慢,可以跳過if (size <= 100) {start = System.currentTimeMillis();Set<Integer> improvedFVS = graph.improvedGreedyFVS();end = System.currentTimeMillis();System.out.printf("改進貪心算法: %d 頂點, 耗時 %d ms%n", improvedFVS.size(), end - start);}}}private static DirectedGraph generateRandomGraph(int vertexCount, int edgeCount) {DirectedGraph graph = new DirectedGraph();Random random = new Random();for (int i = 0; i < vertexCount; i++) {graph.addVertex(i);}for (int i = 0; i < edgeCount; i++) {int from = random.nextInt(vertexCount);int to = random.nextInt(vertexCount);if (from != to) {graph.addEdge(from, to);}}return graph;}
}

7. 實際應用與擴展

7.1 加權反饋頂點集

在實際應用中,頂點可能有不同的權重,我們需要尋找權重和最小的反饋頂點集:

public Set<Integer> weightedGreedyFVS(Map<Integer, Integer> vertexWeights) {Set<Integer> fvs = new HashSet<>();DirectedGraph graphCopy = this.copy();while (graphCopy.hasCycle()) {// 選擇(度數/權重)最大的頂點int vertexToRemove = -1;double maxRatio = -1;for (int vertex : graphCopy.getVertices()) {int outDegree = graphCopy.getNeighbors(vertex).size();int inDegree = 0;for (int v : graphCopy.getVertices()) {if (graphCopy.getNeighbors(v).contains(vertex)) {inDegree++;}}double ratio = (outDegree + inDegree) / (double) vertexWeights.get(vertex);if (ratio > maxRatio) {maxRatio = ratio;vertexToRemove = vertex;}}fvs.add(vertexToRemove);graphCopy.removeVertex(vertexToRemove);}return fvs;
}

7.2 并行化實現

對于大型圖,可以并行計算各頂點的環參與度:

public Set<Integer> parallelGreedyFVS() {Set<Integer> fvs = new HashSet<>();DirectedGraph graphCopy = this.copy();ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());while (graphCopy.hasCycle()) {List<Future<VertexCycleCount>> futures = new ArrayList<>();for (int vertex : graphCopy.getVertices()) {futures.add(executor.submit(() -> {int count = countCyclesForVertex(graphCopy, vertex);return new VertexCycleCount(vertex, count);}));}VertexCycleCount best = new VertexCycleCount(-1, -1);for (Future<VertexCycleCount> future : futures) {try {VertexCycleCount current = future.get();if (current.count > best.count) {best = current;}} catch (Exception e) {e.printStackTrace();}}if (best.vertex != -1) {fvs.add(best.vertex);graphCopy.removeVertex(best.vertex);}}executor.shutdown();return fvs;
}private static class VertexCycleCount {int vertex;int count;VertexCycleCount(int vertex, int count) {this.vertex = vertex;this.count = count;}
}private int countCyclesForVertex(DirectedGraph graph, int vertex) {// 簡化的環計數實現int count = 0;Set<Integer> visited = new HashSet<>();Stack<Integer> path = new Stack<>();return countCyclesUtil(graph, vertex, visited, path);
}private int countCyclesUtil(DirectedGraph graph, int vertex, Set<Integer> visited, Stack<Integer> path) {if (path.contains(vertex)) {return 1;}if (visited.contains(vertex)) {return 0;}visited.add(vertex);path.push(vertex);int total = 0;for (int neighbor : graph.getNeighbors(vertex)) {total += countCyclesUtil(graph, neighbor, visited, path);}path.pop();return total;
}

8. 總結

最小反饋頂點集問題是一個具有挑戰性的NP難問題,貪心算法提供了一種有效的近似解決方案。本文詳細介紹了:

  1. 問題的定義和應用背景
  2. 貪心算法的基本原理和多種策略
  3. 完整的Java實現,包括基礎和改進版本
  4. 時間復雜度分析和優化策略
  5. 測試驗證方法和性能考慮
  6. 實際應用擴展和并行化實現

貪心算法雖然不能保證得到最優解,但在實際應用中通常能提供令人滿意的近似解,特別是在處理大規模圖數據時。通過選擇合適的貪心策略和優化技巧,可以在解的質量和計算效率之間取得良好的平衡。

對于需要更高精度解的場景,可以考慮將貪心算法與其他技術如分支限界、動態規劃或元啟發式算法結合使用。

更多資源:

https://www.kdocs.cn/l/cvk0eoGYucWA

本文發表于【紀元A夢】!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/83719.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/83719.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/83719.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

BiliNote部署實踐

? 開源地址&#xff1a; https://github.com/JefferyHcool/BiliNote &#x1f680; 快速開始 1. 克隆倉庫 git clone https://github.com/JefferyHcool/BiliNote.git cd BiliNote mv .env.example .env2. 啟動后端&#xff08;FastAPI&#xff09; cd backend pip insta…

用go從零構建寫一個RPC(4)--gonet網絡框架重構+聚集發包

在追求高性能的分布式系統中&#xff0c;RPC 框架的底層網絡能力和數據傳輸效率起著決定性作用。經過幾輪迭代優化&#xff0c;我完成了第四版本的 RPC 框架。相比以往版本&#xff0c;這一版本的最大亮點在于 重寫了底層網絡框架 和 實現了發送端的數據聚集機制&#xff0c;這…

MySQL 高可用基石 - 復制監控與常見 HA 方案

MySQL 高可用基石 - 復制監控與常見 HA 方案 MySQL 復制核心原理 MySQL 復制允許數據從一個 MySQL 數據庫服務器(稱為主庫 - Primary,舊稱 Master)復制到一個或多個其他的 MySQL 服務器(稱為從庫 - Replica,舊稱 Slave)。 復制的主要目的: 高可用性 (High Availability…

微信小程序(uniapp)自定義 TabBar

微信小程序&#xff08;uniapp&#xff09;自定義 TabBar 實現指南 在微信小程序開發中&#xff0c;TabBar 是底部導航欄的重要組件&#xff0c;但官方提供的 TabBar 樣式和功能較為基礎&#xff0c;無法滿足所有項目的需求。本文將詳細介紹如何在 uniapp 中實現自定義 TabBar…

MLP實戰二:MLP 實現圖像數字多分類

任務 實戰&#xff08;二&#xff09;&#xff1a;MLP 實現圖像多分類 基于 mnist 數據集&#xff0c;建立 mlp 模型&#xff0c;實現 0-9 數字的十分類 task: 1、實現 mnist 數據載入&#xff0c;可視化圖形數字&#xff1b; 2、完成數據預處理&#xff1a;圖像數據維度轉換與…

BUUCTF[HCTF 2018]WarmUp 1題解

BUUCTF[HCTF 2018]WarmUp 1題解 分析解題過程代碼審計主體函數CHECK函數&#xff1a; 構造payload 總結 分析 啟動靶機&#xff0c;進入網址&#xff0c;是一張滑稽的表情包&#xff1a; 程序化F12查看源碼&#xff1a; 發現注釋內容&#xff0c;訪問 url:/source.php得到…

大陸4D毫米波雷達ARS548調試

本文介紹了大陸ARS548毫米波雷達的調試與測試流程&#xff0c;主要包括以下內容&#xff1a; 設備參數&#xff1a;最大檢測距離301m&#xff08;可調93-1514m&#xff09;&#xff0c;支持gPTP時間同步。 接線調試&#xff1a; Windows需使用USB-RJ45轉換器 Linux可直接連接網…

TDengine 的 AI 應用實戰——運維異常檢測

作者&#xff1a; derekchen Demo數據集準備 我們使用公開的 NAB數據集 里亞馬遜 AWS 東海岸數據中心一次 API 網關故障中&#xff0c;某個服務器上的 CPU 使用率數據。數據的頻率為 5min&#xff0c;單位為占用率。由于 API 網關的故障&#xff0c;會導致服務器上的相關應用…

并發編程 - go版

1.并發編程基礎概念 進程和線程 A. 進程是程序在操作系統中的一次執行過程&#xff0c;系統進行資源分配和調度的一個獨立單位。B. 線程是進程的一個執行實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位。C.一個進程可以創建和撤銷多個線程;同一個進程中…

《一生一芯》數字實驗三:加法器與ALU

1. 實驗目標 設計一個能實現如下功能的4位帶符號位的 補碼 ALU&#xff1a; Table 4 ALU 功能列表 ? 功能選擇 功能 操作 000 加法 AB 001 減法 A-B 010 取反 Not A 011 與 A and B 100 或 A or B 101 異或 A xor B 110 比較大小 If A<B then out1…

解讀《網絡安全法》最新修訂,把握網絡安全新趨勢

《網絡安全法》自2017年施行以來&#xff0c;在維護網絡空間安全方面發揮了重要作用。但隨著網絡環境的日益復雜&#xff0c;網絡攻擊、數據泄露等事件頻發&#xff0c;現行法律已難以完全適應新的風險挑戰。 2025年3月28日&#xff0c;國家網信辦會同相關部門起草了《網絡安全…

Java并發編程實戰 Day 10:原子操作類詳解

【Java并發編程實戰 Day 10】原子操作類詳解 開篇 這是“Java并發編程實戰”系列的第10天&#xff0c;我們將深入探討原子操作類的核心技術——CAS原理、ABA問題以及原子類的實現機制。通過理論結合代碼實踐的方式&#xff0c;幫助讀者理解并掌握如何在實際工作中高效使用原子…

瀚文機械鍵盤固件開發詳解:HWKeyboard.h文件解析與應用

【手把手教程】從零開始的機械鍵盤固件開發&#xff1a;HWKeyboard.h詳解 前言 大家好&#xff0c;我是鍵盤DIY愛好者Despacito0o&#xff01;今天想和大家分享我開發的機械鍵盤固件核心頭文件HWKeyboard.h的設計思路和技術要點。這個項目是我多年來對鍵盤固件研究的心血結晶…

2048游戲的技術實現分析-完全Java和Processing版

目錄 簡介Processing庫基礎項目構建指南項目結構核心數據結構游戲核心機制圖形界面實現性能優化代碼詳解設計模式分析測試策略總結與展望簡介 2048是一款由Gabriele Cirulli開發的經典益智游戲。本文將深入分析其Java實現版本的技術細節。該實現使用了Processing庫來創建圖形界…

Spring Boot + Elasticsearch + HBase 構建海量數據搜索系統

Spring Boot Elasticsearch HBase 構建海量數據搜索系統 &#x1f4d6; 目錄 1. 系統需求分析2. 系統架構設計3. Elasticsearch 與 HBase 集成方案4. Spring Boot 項目實現5. 大規模搜索系統最佳實踐 項目概述 本文檔提供了基于 Spring Boot、Elasticsearch 和 HBase 構建…

【iOS】YYModel源碼解析

YYModel源碼解析 文章目錄 YYModel源碼解析前言YYModel性能優勢YYModel簡介YYClassInfo解析YYClassIvarInfo && objc_ivarYYClassMethodInfo && objc_methodYYClassPropertyInfo && property_tYYClassInfo && objc_class YYClassInfo的初始化細…

宇樹科技更名“股份有限公司”深度解析:機器人企業IPO前奏與資本化路徑

從技術落地到資本躍遷&#xff0c;拆解股改背后的上市邏輯與行業啟示 核心事件&#xff1a;股改釋放的上市信號 2025年5月28日&#xff0c;杭州宇樹科技有限公司正式更名“杭州宇樹科技股份有限公司”&#xff0c;市場主體類型變更為“股份有限公司”。盡管官方稱為常規運營調…

Android Native 內存泄漏檢測全解析:從原理到工具的深度實踐

引言 Android應用的內存泄漏不僅發生在Java/Kotlin層&#xff0c;Native&#xff08;C/C&#xff09;層的泄漏同樣普遍且隱蔽。由于Native內存不受Java虛擬機&#xff08;JVM&#xff09;管理&#xff0c;泄漏的內存無法通過GC自動回收&#xff0c;長期積累會導致應用內存占用…

Vortex GPGPU的github流程跑通與功能模塊波形探索(四)

文章目錄 前言一、demo的輸入文件二、trace_csv三、2個值得注意的點3.1 csv指令表格里面的tmask&#xff1f;3.2 rtlsim和simx的log文件&#xff1f; 總結 前言 跟著前面那篇最后留下的幾個問題接著把輸出波形文件和csv文件的輸入、輸出搞明白&#xff01; 一、demo的輸入文件…

UnityPSD文件轉UI插件Psd2UnityuGUIPro3.4.0u2017.4.2介紹:Unity UI設計的高效助手

UnityPSD文件轉UI插件Psd2UnityuGUIPro3.4.0u2017.4.2介紹&#xff1a;Unity UI設計的高效助手 【下載地址】UnityPSD文件轉UI插件Psd2UnityuGUIPro3.4.0u2017.4.2介紹 這款開源插件將PSD文件無縫轉換為Unity的UI元素&#xff0c;極大提升開發效率。它支持一鍵轉換&#xff0c;…