图分割算法之贪心算法

1 贪心算法的思想

        Linear Deterministic Greedy partitioning (LDG)考虑在分割的时候将邻居结点放置在一起,以减少切割边。它采用贪心算法将一个结点放置在包含其邻居最多的子图中,同时保证每个子图的结点负载均衡,整个算法流程图如下其中 C 表示每个分区的期望值,w(i)  表示当前子图在平衡状态下剩余容量,g(v,Pi)  表示再考虑负载的情况下结点 v 和子图 Pi 中结点邻居个数的交集,该打分函数作为将结点 v 分配到最大分数的子图中

2 代码设计

父类设计Partitioner

#ifndef PARTITION_H
#define PARTITION_H
#include <vector>
#include <algorithm>
#include <numeric>
#include <random>

class Partitioner 
{
public:
	/// <summary>
	/// 图分区的构造函数
	/// </summary>
	/// <param name="adjMatrix_">临界矩阵</param>
	Partitioner(std::vector<std::vector<int>> adjMatrix_);
	
	/// <summary>
	/// 图分割算法
	/// </summary>
	/// <param name="partNums">分区个数</param>
	virtual void execute(int partNums) = 0;

	/// <summary>
	/// 评估图分割算法
	/// </summary>
	virtual void evaluate() = 0;

	/// <summary>
	/// 返回分区结果
	/// </summary>
	std::vector<int> getResults() const;

	/// <summary>
	/// 获取顶点总数
	/// </summary>
	int getNumVertics() const;

	/// <summary>
	/// 获取图的便的总数
	/// </summary>
	int getNumEdges() const;

private:

protected:

	/// <summary>
	/// 邻接表存储的图数据
	/// </summary>
	std::vector<std::vector<int>> adjMatrix;
	/// <summary>
	/// 分区结果
	/// </summary>
	std::vector<int> partResults;

	int numVertices;

	int numEdges;

};

#endif // !PARTITION_H


#include "Partitioner.h"

Partitioner::Partitioner(std::vector<std::vector<int>> adjMatrix_) : adjMatrix(adjMatrix_)
{
    numVertices = adjMatrix_.size();
    numEdges = 0;
    std::for_each(adjMatrix_.begin(), adjMatrix_.end(), [&](const std::vector<int>& edges) {
        numEdges += edges.size();
        });
}

std::vector<int> Partitioner::getResults() const
{
    return partResults;
}

int Partitioner::getNumVertics() const
{
    return numVertices;
}

int Partitioner::getNumEdges() const
{
    return numEdges;
}

LDGPartitioner的设计

#ifndef LDG_PARTITIONER_H
#define LDG_PARTITIONER_H

#include "Partitioner.h"
#include <unordered_set>

class LDGPartitioner : public Partitioner
{
public:

	LDGPartitioner(std::vector<std::vector<int>> adjMatrix_) : Partitioner(adjMatrix_) {};

	void execute(int partNums) override;

	void evaluate() override;


private:
	/// <summary>
	/// 计算节点index的邻居和已分配的邻居相交的元素个数
	/// </summary>
	/// <param name="index">节点的下表</param>
	/// <param name="curVec">已分配的邻居</param>
	/// <returns></returns>
	int intersect(const int index, const std::unordered_set<int>& curVec);
	/// <summary>
	/// 已分配的集合
	/// </summary>
	std::vector<std::unordered_set<int>> curParts;
};

#endif // !LDG_PARTITIONER_H

#include "LDGPartitioner.h"

void LDGPartitioner::execute(int partNums)
{
	//初始化
	std::vector<int> order(numVertices); //节点id的集合
	curParts.resize(numVertices);
	partResults.resize(numVertices);

	// 随机打乱id
	std::iota(order.begin(), order.end(), 0);
	std::random_shuffle(order.begin(),order.end());

	//将前partNums的节点分配给每个分区作为第一个元素
	for (int i = 0; i < partNums; i++)
	{
		curParts[i].insert(order[i]);
		partResults[order[i]] = i;
	}
	// 每个分区的期望值
	double expectant = static_cast<double>(numVertices / partNums);

	//便利剩余的元素
	for (int ii = partNums; ii < numVertices; ii++)
	{
		//当前节点的id
		int vertex = order[ii];
		// 每个分区的得分
		std::vector<double> scores(partNums, 0);

		for (int jj = 0; jj < partNums; jj++) 
		{
			double curSize = curParts[jj].size();
			double weight = static_cast<double>(1 - (curSize / expectant));
			double neighbors = intersect(vertex, curParts[jj]);
			scores[jj] = neighbors * weight;
		}
		//节点需要分配给得分最高的节点
		int maxIndex = std::distance(scores.begin(), std::max_element(scores.begin(), scores.end()));
		curParts[maxIndex].insert(vertex);
		partResults[vertex] = maxIndex;

	}
}

void LDGPartitioner::evaluate()
{
}

int LDGPartitioner::intersect(const int index,const std::unordered_set<int>& curVec)
{
	int count = 0;

	for (const auto& element : adjMatrix[index])
	{
		if (curVec.count(element))
			count++;
	}
	return count;
}

主函数测试:

#include <iostream>
#include <vector>
#include <list>
#include <algorithm>


#include <memory>

#include "LDGPartitioner.h"

using namespace std;

// 定义图的邻接表类型
typedef vector<vector<int>> AdjacencyList;


int main() {
    // 构造示例图的邻接表
    AdjacencyList graph = {
        {1, 2, 4},
        {0, 2, 4},
        {0, 1, 3},
        {2, 4},
        {0, 1, 3}
    };
    //Partitioner* ptr = new LDGPartitioner(graph);
    unique_ptr<Partitioner> ptr = make_unique<LDGPartitioner>(graph);

    ptr->execute(3);

    
    // 初始化划分
    vector<int> partition = ptr->getResults();



    // 输出划分结果
    for (int i = 0; i < partition.size(); i++) {
        cout << "Vertex " << i << " belongs to Partition " << partition[i] << endl;
    }

    return 0;
}

3 执行结果

        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/276231.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于人工势场法的航线规划

MATLAB2016b可以运行 基于人工势场法的航线规划资源-CSDN文库

C# OpenCvSharp读取rtsp流录制mp4可分段保存

软件界面&#xff1a; 测试环境&#xff1a; VS2019 .NET Framework 4.7.2 OpencvSharp4.8.0 输入RTSP流地址即可拉取RTSP流&#xff0c;支持抓拍和录制RTSP流视频&#xff0c;且支持支持按固定时间保存&#xff0c;比如我想5分钟保存一个视频&#xff0c;设置保存间隔为30…

边缘检测——PidiNet网络训练自己数据集并优化推理测试(详细图文教程)

PiDiNet 是一种用于边缘检测的算法&#xff0c;它提出了一种简单、轻量级但有效的架构。PiDiNet 采用了新 颖的像素差卷积&#xff0c;将传统的边缘检测算子集成到现代 CNN 中流行的卷积运算中&#xff0c;以增强任务性能。 在 BSDS500、NYUD 和 Multicue 上进行了大量的实验…

联营商自述被坑惨,加盟库迪没有未来?

撰稿 | 多客 来源 | 贝多财经 近日&#xff0c;库迪联营商在社交平台不约而同发出了致库迪咖啡管理层的公开信&#xff0c;两封公开信可谓字字珠玑&#xff0c;没有一句废话&#xff0c;揭开了库迪咖啡在细节、运营、扩张、培训等方方面面的“背后真相”。 两封公开信 折射库…

大数据技术16:数据湖和湖仓一体

前言&#xff1a;近几年大数据概念很多&#xff0c;数据库和数据仓库还没搞清楚&#xff0c;就又出了数据湖&#xff0c;现在又开始流行湖仓一体。互联网公司拼命造高大上概念来忽略小白买单的能力还是可以的。 1、数据库 数据库是结构化信息或数据的有序集合&#xff0c;一般以…

24、Qt使用QCustomPlot

一、下载文件 进入官网&#xff0c;选择“Download”、QCustomPlot.tar.gz Qt Plotting Widget QCustomPlot - Download 二、创建项目 创建一个"Qt Widget Application"项目&#xff0c;基类选择“QMainWindow”&#xff0c;把刚才下载的压缩包里的“qcustomplot.…

给零基础朋友的编程课08 - 代码

给零基础朋友的编程课08 - 旋转、圆弧、初识模块化编程。_哔哩哔哩_bilibili Code: / // 彩色案例 艺术仿制品3 // /// 色表 // // 奶白 215,214,160 // 金黄 187,176,112 // 赭石 96,56,20 // 橙色 218,114,53// 项目设定 size(1000,1000); background(215,214,160); stroke…

vue3-13

token可以是后端api的访问依据&#xff0c;一般绝大多数时候&#xff0c;前端要访问后端的api,后端都要求前端请求需要携带一个有效的token,这个token用于用户的身份校验&#xff0c;通过了校验&#xff0c;后端才会向前端返回数据&#xff0c;进行相应的操作&#xff0c;如果没…

c++ / day01

1. 整理思维导图 2. 定义自己的命名空间myspace&#xff0c;并在myspace中定义一个字符串&#xff0c;实现求字符串大小的函数。 代码 #include <iostream>using namespace std;namespace myns {unsigned long long strlen(string s){return s.length();}}int main() {…

算法导论复习(七) 动态规划

动态规划一般用来求解最优化问题 设计一个动态规划算法一般有以下四步&#xff1a; 描述一个最优解的结构特征。递归地定义最优解的值。计算最优解的值&#xff0c;通常采用自底向上的方法。利用计算出的信息构造出一个最优解。 钢条切割问题 体现了动态规划的一个重要性质&a…

获取b站合集视频时长最新可用代码(2023.12.28)小白也能用

在网上搜索获取b站分集视频时长的代码&#xff0c;发现大部分都过时了 原链接&#xff1a;已过时代码链接 我对原代码做出了部分修改&#xff0c;以下代码于2023.12.28测试&#xff08;Edge浏览器&#xff09; javascript: (function() {var hour 0;var minute 0;var secon…

Leetcode—1572.矩阵对角线元素的和【简单】

2023每日刷题&#xff08;七十三&#xff09; Leetcode—1572.矩阵对角线元素的和 实现代码 class Solution { public:int diagonalSum(vector<vector<int>>& mat) {int n mat.size();if(n 1) {return mat[0][0];}int sum 0;int i 0, j n - 1;while(i &…

低信噪比环境下的语音端点检测

端点检测技术 是 语音信号处理 的关键技术之一为提高低信噪比环境下端点检测的准确率和稳健性&#xff0c;提出了一种非平稳噪声抑制和调制域谱减结合功率 归一化 倒谱距离的端点检测算法 1 端点检测 1-1 定义 定义&#xff1a;在 存在背景噪声 的情况下检测出 语音的起始点和…

Android中_Service生命周期和AMS流程的创建

Service生命周期可以结合Android生命周期分析。 Service生命周期可以从两种启动Service的模式开始讲起&#xff0c;分别是context.startService()和context.bindService()。 Service的生命周期与启动和绑定状态相关。当调用startService()方法启动服务时&#xff0c;会执行onS…

“踩坑”经验分享:Swift语言落地实践

作者 | 路涛、艳红 导读 Swift 是一种适用于iOS/macOS应用开发、服务器端的编程语言。自2014年苹果发布 Swift 语言以来&#xff0c;Swift5 实现了 ABI 稳定性、Module 稳定性和Library Evolution&#xff0c;与Objective-C&#xff08;下文简称“OC”&#xff09;相比&#xf…

QLabelQPushButton和QLineEdit

QLabel 设置文件格式字体颜色背景 源码 设置图片 源码 设置gif 设置文本 源码 富文本 (Rich Text): 格式化选项&#xff1a;富文本支持各种格式化选项&#xff0c;如字体样式&#xff08;粗体、斜体&#xff09;、字体大小、颜色、超链接、图片插入、列表、表格等。文件格式&a…

pybullet安装时出现fatal error C1083: 无法打开包括文件: “string.h”: No such file or directory

pybullet安装时出现fatal error C1083: 无法打开包括文件: “string.h”: No such file or directory 报错原文&#xff1a; -----CloneTreeCreator.cppD:\Program_Professional\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.38.33130\include\cstring(11): fat…

机器环境无法访问GitHub情况下linux安装OpenCV执行cmake无法下载ADE文件v0.1.1f.zip

☞ ░ 前往老猿Python博客 ░ https://blog.csdn.net/LaoYuanPython 一、引言 在CSDN的博文《构建VisualStudio2019OpenCV4.3的C windows编译环境》中&#xff0c;老猿介绍了opencv版本的下载方法的方法&#xff0c;该方法下载OpenCV的代码不要上GitHub&#xff0c;国内可以直…

记edusrc一处信息泄露登录统一平台

目录 前言 测试思路 本文由掌控安全学院 - sbhglqy 投稿 前言 我们都知道像大学之类的各种平台的登录账号基本上是学号&#xff0c;初始登录密码基本上是学生身份证的后6位再拼接上一些带有学校缩写的英文字母。所以我们在找漏洞的时候可以换一种思路&#xff0c;先通过去找…

辅助工具

本章将会通过以下几个角度&#xff0c;简要介绍几款渗透测试的辅助工具。 ● 工具的功能&#xff1b; ● 如果这款工具没有被Kali Linux 收录&#xff0c;本文也会介绍其安装过程&#xff1b; ● 应用案例。 稍后介绍的部分工具确实没有被 Kali Linux 收录。要使用这些软件…