Java 程序用于在图中查找最佳反馈顶点集

javaobject oriented programmingprogramming更新于 2024/11/3 7:40:17

Java 程序指向图表中的最佳输入顶点集。输入顶点集可以是图表中的一组顶点,从而在非循环图表中移除这些顶点及其出现边缘。该程序使用算法方法来识别保持图表基本属性的小输入顶点集。通过迭代选择具有高度的顶点并在其出现边缘处移除它们,程序找到假定的排列。这允许熟练地识别导致图表中循环的关键顶点。接下来的预测顶点集对于不同的应用非常有用,例如组织分析和优化。

使用的方法

  • 近似算法

  • 强力方法

近似算法

在 Java 程序中,在图表中查找输入顶点集时,预测算法是一种确保在理想排列的某个计算范围内排列的方法。该算法首先迭代地选择具有最高度数的顶点并将其与出现边一起驱逐。无论如何,与贪婪算法不同,如果这会对中断循环产生影响,该方法还会考虑驱逐具有较低度数的顶点。通过迭代地删除顶点,计算点形成非循环图,所选顶点构成判定顶点集。考虑到计算效率,猜测算法给出了一个相当好的解决方案。

算法

  • 初始化清除集S来存储所选顶点。

  • 当G包含边时,

  • a. 找到G中度数最高的顶点v。

  • b. 将v添加到S。

  • c. 从G中删除v及其出现边。

  • d.重复步骤 a–c,直到 G 变得无边。

  • 对于 G 中每个剩余顶点 u:

  • a. 如果您与 S 中的任何顶点相邻,则将您从 G 中移除。

  • 返回 S 作为不精确的输入顶点集。

示例

#include <iostream>
#include <vector>
#include <set>
#include <algorithm> // 包含 sort 函数的算法标头

using namespace std;

// 用于在图中查找良好反馈顶点集的函数
set<int> findFeedbackVertexSet(vector<vector<int>>& graph) {
    int n = graph.size();
    vector<pair<int, int>> degrees;
    
    // 计算每个顶点的度数
    for (int i = 0; i < n; ++i) {
    degrees.push_back({graph[i].size(), i});
    }
    
    // 按度数降序对顶点进行排序
    sort(degrees.rbegin(), degrees.rend());
    
    set<int> feedbackVertexSet;
    
    // 贪婪地选择度数最高的顶点
    for (int i = 0; i < n; ++i) {
      int vertex = degrees[i].second;

      // Check if adding this vertex forms a cycle
      bool formsCycle = false;
      for (int neighbor : graph[vertex]) {
         if (feedbackVertexSet.count(neighbor) > 0) {
            formsCycle = true;
            break;
         }
      }

      // 如果添加此顶点不形成循环,则将其添加到反馈顶点集中
      if (!formsCycle) {
         feedbackVertexSet.insert(vertex);
      }
   }

   return feedbackVertexSet;
}

// 测试函数
int main() {
   // Create a sample graph
   vector<vector<int>> graph = {
      {1, 2, 3},
      {0, 3},
      {0, 3},
      {0, 1, 2}
   };

    // 找到一个好的反馈顶点集
    set<int> feedbackSet = findFeedbackVertexSet(graph);
    
    // 打印反馈顶点集中的顶点
    cout << "反馈顶点集: ";
   for (int vertex : feedbackSet) {
      cout << vertex << " ";
   }
   cout << endl;

   return 0;
}

输出

反馈顶点集:3

强力方法

在图表中找到最佳反馈顶点集的场景中,强力方法包括彻底检查所有可能的顶点组合,以确定打破所有循环的最小集合。它有效地创建所有顶点子集,并检查清除这些顶点是否会使图表非循环。这种方法确保找到理想的安排,但由于其指数时间复杂度,对于扩展图表来说变得不合逻辑。强力方法包括遍历所有可能的顶点组合,将它们从图表中移除,并检查非循环性,直到找到最小的批评顶点集。

算法

  • 初始化一个变量来存储输入顶点集的最小值。

  • 生成图中所有可能的顶点子集。

  • 对于每个子集,从图表中扩展顶点并检查即将到来的图表是否是非循环的。

  • 如果图表是非循环的,则计算当前子集的值。

  • 如果当前子集的值小于最小值,则增加最小值。

  • 对所有子集重复步骤 3-5创建的子集。

  • 返回输入顶点集的最小估计值。

示例

#include <iostream>
#include <vector>
#include <set>

using namespace std;

// 函数用于检查给定的顶点是否形成反馈顶点集
bool isFeedbackVertexSet(const vector<vector<int>>& graph, const set<int>& vertices) {
   // 检查集合中的每个顶点是否打破了循环
   for (int vertex : vertices) {
      for (int neighbor : graph[vertex]) {
         if (vertices.find(neighbor) == vertices.end()) {
            return false; // 存在循环,因此不是反馈顶点集
         }
      }
   }
   return true; // 未发现任何循环,因此它是一个反馈顶点集
}

// 递归函数用于查找所有可能的反馈顶点集
void findAllFeedbackVertexSets(const vector<vector<int>>& graph, set<int>& currentSet, int vertex, vector<set<int>>& allSets) {
   // 基本情况:到达图的末尾
   if (vertex == graph.size()) {
      if (isFeedbackVertexSet(graph, currentSet)) {
         allSets.push_back(currentSet);
      }
      return;
   }

   // 递归情况:包括当前顶点或排除它
   currentSet.insert(vertex);
   findAllFeedbackVertexSets(graph, currentSet, vertex + 1, allSets);
   currentSet.erase(vertex);
   findAllFeedbackVertexSets(graph, currentSet, vertex + 1, allSets);
}

// 函数用于在图中找到一个好的反馈顶点集
set<int> findGoodFeedbackVertexSet(const vector<vector<int>>& graph) {
   vector<set<int>> allSets;
   set<int> currentSet;

    // 查找所有可能的反馈顶点集
    findAllFeedbackVertexSets(graph, currentSet, 0, allSets);
    
    // 查找最小的反馈顶点集
    set<int> minimalSet;
    size_t minimalSize = graph.size() + 1;

   for (const set<int>& vertices : allSets) {
      if (vertices.size() < smallestSize) {
         smallestSize = vertices.size();
         smallestSet = vertices;
      }
   }

   return smallestSet;
}

int main() {
    // 将图定义为邻接表
    vector<vector<int>> graph = {
    {1, 2},
    {0, 2, 3},
    {0, 1, 3, 4},
    {1, 2, 4},
    {2, 3}
    };
    
    // 在图中查找良好的反馈顶点集
    set<int> feedbackVertexSet = findGoodFeedbackVertexSet(graph);

   // 打印结果
   cout << "Feedback Vertex Set: ";
   if (!feedbackVertexSet.empty()) {
      for (int vertex : feedbackVertexSet) {
         cout << vertex << " ";
      }
   } else {
         cout << "No feedback vertex set found.";
   }
   cout << endl;

   return 0;
}

输出

Feedback Vertex Set: No feedback vertex set found.

结论

本文阐明了在确定是否可以分配满足给定关系的值的环境中限制满足和限制生成的概念。它图解了所涉及的算法过程,并给出了 C++ 中的代码示例。本文阐明了在确定是否可以分配满足给定关系的值的环境中限制满足和限制生成的概念。它图解了所涉及的算法过程,并给出了 C++ 中的代码示例。

命令式满足包括确定是否可以向满足给定限制的元素分配值,而限制生成则迭代地应用规则以根据关系减少可能的值。本文说明了如何使用这些过程来阐明满足元素之间关系的问题,强调了有效搜索空间和消除冲突任务的重要性。


相关文章


有用资源