随机收缩算法
来源:互联网 发布:死神方便知乎 编辑:程序博客网 时间:2024/05/18 00:58
随机收缩算法
- 随机收缩算法
- 一些基本定义
- 图graph
- 割cut
- 连接边crossing edge
- 最小割问题
- Random Contraction Algorithm
- 算法实现
- 数据结构设计
- coding
- 一些基本定义
最近学习Tim Roughgarden 的Algorithm课程,就写一下笔记吧。
一些基本定义
图(graph)
一个图由两部分组成:顶点(vertex)和边(edge)。顶点集用V表示,边集用E表示。
图可以分为有向图和无向图。
割(cut)
一个图(V,E)的割指的是对图(V,E)的顶点集的一个分割,使得顶点集V分为两个非空子集A和B。
一个连通图的割的数量为
连接边(crossing edge)
- 对无向图来说,连接边指的是边的两个顶点分别在A或B中。
- 对有向图来说,连接边指的是头在B中,尾在A中。
最小割问题
输入:一个无向图G=(V,E).
输出:图的一种割法,使得连接边的数量最少。
Random Contraction Algorithm
如其名,这是一个随机算法,由Karger在上世纪90年代初提出。其基本思想如下:
While there more than 2 vertices:
- pick a remaining edge (u,v) uniformly at random
- merge u and v into a single vertex
- remove self-loops
return cut represented by final 2 vertices.
算法实现
数据结构设计
每个顶点有2个属性:顶点的“名字”和顶点的邻接顶点。初始化时,每个顶点的“名字”都是它自己,但是随着收缩步骤的进行,顶点的名字会随之改变。如顶点2和顶点3合并后,将会由一个新“名字”:顶点23。顶点23和顶点34合并后,新顶点名字为234而不是2334,因为我们不需要重复。为了除重,我将顶点“名字”设计为集合类型。顶点的邻接顶点用一个列表表示。
顶点类的设计如下:
public class Vertice{ private HashSet<Integer> m_verticeInx;//vertex name private ArrayList<Integer> m_adjacentNodes;}
整个图可以用可以用一个Vertice的List表示。
这个算法实际上思路是很简单的,就分析到这了。
coding
用java实现。
MinCutTest类。
/** * A implementation of random contraction algorithm for computing * the minimum cut of a undirected connected graph. * * @author chenshiyang * */public class MinCutTest{ private ArrayList<Vertice> m_graph; private ArrayList<Vertice> m_backGraph; private int m_minCutMin = 1000; private int m_nodeCount = 0; public void recoverGraph(){ m_nodeCount = m_backGraph.size(); m_graph = new ArrayList<Vertice>(); for(int i = 0; i < m_backGraph.size(); i ++){ m_graph.add(new Vertice(m_backGraph.get(i))); } } public void getGraphData(String fName) throws Exception{ BufferedReader reader = new BufferedReader(new FileReader(fName)); String lineString = ""; m_graph = new ArrayList<Vertice>(); m_backGraph = new ArrayList<Vertice>(); int verticeInx = 1; while((lineString = reader.readLine()) != null){ String[] sarry = lineString.split("\t"); ArrayList<Integer> nodes = new ArrayList<Integer>(); for(int i = 1; i < sarry.length; i ++){ nodes.add(Integer.parseInt(sarry[i].trim())); } Vertice vertice = new Vertice(); HashSet<Integer> verticeName = new HashSet<Integer>(); verticeName.add(verticeInx); vertice.setVerticeInx(verticeName); vertice.setAdjacentNodes(nodes); m_graph.add(vertice); Vertice backupVertice = new Vertice(vertice); m_backGraph.add(backupVertice); verticeInx ++; } m_nodeCount = m_graph.size();// m_minCutMin = m_graph.get(0).getAdjacentNodes().size(); reader.close();/* System.out.println(m_graph.size()); for(int i = 0; i < m_graph.size(); i ++){ System.out.println(m_graph.get(i).getAdjacentNodes().size()); }*/ } public void randomContraction(int seed){ Random rand = new Random(seed); while(m_graph.size() > 2){ int currentSize = m_graph.size(); // randomly choose first vertice int firstNodeIndex = rand.nextInt(currentSize); /***************method one ********************* * 遍历第一个点的邻接点 * 如果这个点出现在graph里的其他点中,则返回*/ int secondNodeIndex = -1; int secondNodeIndexInFirst = rand.nextInt(m_graph.get(firstNodeIndex).getAdjacentNodes().size()); int vertexNum = m_graph.get(firstNodeIndex).getAdjacentNodes().get(secondNodeIndexInFirst); for(int i = 0; i < m_graph.size(); i ++){ if(i == firstNodeIndex) continue; if(m_graph.get(i).getVerticeInx().contains(vertexNum)){ secondNodeIndex = i; break; } } /***************method two ********************** * 遍历graph里的点。 * 对graph里的一个点 * 如果第一个点的邻接点点包含它则返回*//* int secondNodeIndex = rand.nextInt(currentSize); Iterator<Integer> iterator; //indicates if second node is contained in the first node's adjacent nodes. boolean contain = false; while(!contain){ //randomly choose second node. secondNodeIndex = rand.nextInt(currentSize); //if the second node is not the first node's adjacent node, regenerate it. while(secondNodeIndex == firstNodeIndex){ secondNodeIndex = rand.nextInt(currentSize); } iterator = m_graph.get(secondNodeIndex).getVerticeInx().iterator(); while(iterator.hasNext()){ int temp = iterator.next(); if(m_graph.get(firstNodeIndex).getAdjacentNodes().contains(temp)){ contain = true; break; } } }*/ //merge the two vertice m_graph.get(firstNodeIndex).getAdjacentNodes().addAll(m_graph.get(secondNodeIndex).getAdjacentNodes()); //change the vertice name m_graph.get(firstNodeIndex).getVerticeInx().addAll(m_graph.get(secondNodeIndex).getVerticeInx()); //remove self loop m_graph.get(firstNodeIndex).getAdjacentNodes().removeAll(m_graph.get(firstNodeIndex).getVerticeInx()); //remove the second vertice m_graph.remove(secondNodeIndex); } int currentMinCutCount = m_graph.get(0).getAdjacentNodes().size(); if(currentMinCutCount < m_minCutMin) m_minCutMin = currentMinCutCount;// System.out.println("Cut Number: " + m_minCutMin); } public void randomContractionAlgorithm(String fName) throws Exception{ getGraphData(fName); int loopCount = (int)(Math.log(m_nodeCount) * Math.pow(m_nodeCount, 2)); for(int i = 0; i < loopCount; i ++){ randomContraction(i); recoverGraph();// System.out.println("node Count:" + m_nodeCount); } }}
Vertice 类
public class Vertice{ private HashSet<Integer> m_verticeInx; private ArrayList<Integer> m_adjacentNodes; public Vertice(){ } public Vertice(Vertice vertix){ this.m_verticeInx = new HashSet<Integer>(); Iterator<Integer> iterator = vertix.m_verticeInx.iterator(); while(iterator.hasNext()){ m_verticeInx.add(iterator.next()); } this.m_adjacentNodes = new ArrayList<Integer>(); iterator = vertix.m_adjacentNodes.iterator(); while(iterator.hasNext()){ this.m_adjacentNodes.add(iterator.next()); } } public HashSet<Integer> getVerticeInx() { return m_verticeInx; } public void setVerticeInx(HashSet<Integer> verticeInx) { this.m_verticeInx = verticeInx; } public ArrayList<Integer> getAdjacentNodes() { return m_adjacentNodes; } public void setAdjacentNodes(ArrayList<Integer> adjacentNodes) { this.m_adjacentNodes = adjacentNodes; }}
博客真不好写,先写到这吧,慢慢加油。
0 0
- 随机收缩算法
- 随机算法
- 随机算法
- 随机算法
- 随机算法
- 随机算法
- 随机算法
- 随机算法
- 随机算法
- 随机算法
- 随机算法
- 随机算法
- 随机算法之随机选择
- 算法_9:随机算法
- [算法] 洗牌算法&随机算法
- 随机洗牌算法和随机选择算法
- 随机组卷算法
- 得到随机字符串算法
- ZJUTOJ 1217 大数乘法
- MySQL出现“错误1067:进程意外终止”
- 股票学习(技术指标)
- 判断回文数
- [LeetCode]Evaluate Reverse Polish Notation
- 随机收缩算法
- Leetcode 6 ZigZag Conversion
- Bootstrap全局CSS样式之栅格系统
- 数据库.创建表
- Visual Studio 2015 社区版.专业版.企业版[含安装密钥Pro&Ent]
- 杭电 HDU ACM 2795 Billboard(线段树伪装版)
- 第三天学习笔记2
- 03-类加载器
- D - Data Center-2014-2015 ACM-ICPC, NEERC, Southern Subregional Contest