基本的类 Graph
Graph
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace Graph
{
public struct Edge
{
public int from;
public int to;
public int edgeStyle;
public double weight;
public Edge(int _from,int _to,double _weight,int _edgeStyle)
{
from = _from;
to = _to;
edgeStyle = _edgeStyle;
weight = _weight;
}
public Edge(int _from, int _to, int _edgeStyle)
{
from = _from;
to = _to;
edgeStyle = _edgeStyle;
weight = double.MaxValue;
}
}
public partial class SimpleGraph
{
public const int MaxVertexCount = 1000;
public const int EdgeStyle_Undirected = 0;
public const int EdgeStyle_Directed = 1;
SortedList<int, int> vertices = new SortedList<int, int>(); // key and value are same
public int[,] vertexDegree = new int[MaxVertexCount, 3]; // 0 = total degree, 1 = out degree, 2= in degree
public List<int> Vertices
{
get
{
List<int> list = new List<int>();
for (int i = 0; i < vertices.Keys.Count; i++) list.Add(vertices.Keys[i]);
return list;
}
}
public bool VertexIn(int vertexNO)
{
return vertices.ContainsKey(vertexNO);
}
List<SortedList<int, Edge>> edges = new List<SortedList<int, Edge>>(); // key = to vertex NO,
public List<Edge> Edges
{
get
{
List<Edge> list = new List<Edge>();
List<int> vertex_list = Vertices;
for (int i = 0; i < vertex_list.Count; i++)
{
int from = vertex_list[i];
for (int j = 0; j < edges[from].Keys.Count; j++)
{
int to= edges[from].Keys[j];
Edge edge = edges[from][to];
list.Add(edge);
}
}
return list;
}
}
public bool EdgeIn(int from, int to)
{
return edges[from].ContainsKey(to);
}
public bool EdgeIn(Edge e)
{
return edges[e.from ].ContainsKey(e.to);
}
public Edge this[int from, int to]
{
get
{
if(edges[from].ContainsKey(to)) return edges[from][to];
return default(Edge);
}
}
public SimpleGraph()
{
for (int i = 0; i < MaxVertexCount; i++)
{
edges.Add(new SortedList<int, Edge>());
}
for (int i = 0; i < MaxVertexCount; i++)
{
vertexDegree[i, 0] = vertexDegree[i,1] = vertexDegree[i, 2] = 0;
}
}
public SimpleGraph Clone()
{
SimpleGraph graph = new SimpleGraph();
graph.AddVertex(this.Vertices);
List<Edge> edge_list = this.Edges;
for (int i = 0; i < edge_list.Count; i++)
{
graph.AddEdge(edge_list[i]);
}
return graph;
}
public void Clear()
{
vertices.Clear();
for (int i = 0; i < MaxVertexCount; i++) edges[i].Clear();
}
public void AddVertex(int vertexNO)
{
if (!vertices.ContainsKey(vertexNO)) vertices.Add(vertexNO, vertexNO);
}
public void RemoveVertex(int vertexNO)
{
vertices.Remove(vertexNO);
}
public void AddVertex(List<int> vertex_list)
{
for (int i = 0; i < vertex_list.Count; i++) AddVertex(vertex_list[i]);
}
public void RemoveVertex(List<int> vertex_list)
{
for (int i = 0; i < vertex_list.Count; i++) vertices.Remove(vertex_list[i]);
}
public virtual bool AddEdge(Edge e)
{
int from = e.from;
int to = e.to;
if (!vertices.ContainsKey(from)) vertices.Add(from, from);
if (!vertices.ContainsKey(to)) vertices.Add(to, to);
if (edges[from].ContainsKey(to)) return false; // there is a same edge , conflict
edges[from].Add(to,e);
vertexDegree[from, 0]++;
vertexDegree[from, 1]++;
vertexDegree[to, 0]++;
vertexDegree[to, 2]++;
if (e.edgeStyle == EdgeStyle_Undirected)
{
if (edges[to].ContainsKey(from)) return false; // there is a same edge , conflict
Edge e2 = new Edge(to, from, e.weight, e.edgeStyle);
edges[to].Add(from,e2);
vertexDegree[from, 2]++;
vertexDegree[to, 1]++;
}
return true;
}
public virtual bool AddEdge(int from,int to,double weight,int edgeStyle)
{
Edge e = new Edge(from, to, weight, edgeStyle);
return AddEdge(e);
}
public virtual bool AddEdge(int from, int to, int edgeStyle)
{
Edge e = new Edge(from, to, edgeStyle);
return AddEdge(e);
}
public bool RemoveEdge(int from, int to)
{
if (!edges[from].ContainsKey(to)) return false;
int edgeStyle=edges[from][to].edgeStyle;
edges[from].Remove(to);
vertexDegree[from, 0]--;
vertexDegree[from, 1]--;
vertexDegree[to, 0]--;
vertexDegree[to, 2]--;
if (edgeStyle == EdgeStyle_Undirected)
{
edges[to].Remove(from);
vertexDegree[from, 2]--;
vertexDegree[to, 1]--;
}
return true;
}
public bool RemoveEdge(Edge e)
{
return RemoveEdge(e.from, e.to);
}
public void RemoveEdgeAndZeroVertex(int from, int to)
{
RemoveEdge(from, to);
if (vertexDegree[from,0] == 0) vertices.Remove(from);
if (vertexDegree[to, 0] == 0) vertices.Remove(to);
}
public void RemoveEdgeAndZeroVertex(Edge e)
{
RemoveEdgeAndZeroVertex(e.from, e.to);
}
public List<Edge> NeighbourEdgesOfVertex(int vertexNO)
{
List<Edge> list = new List<Edge>();
int from = vertexNO;
for (int j = 0; j < edges[from].Keys.Count; j++)
{
int to = edges[from].Keys[j];
list.Add(edges[from][to]);
}
return list;
}
public List<int> NeighbourVerticesOfVertex(int vertexNO)
{
List<int> list = new List<int>();
for (int j = 0; j < edges[vertexNO].Keys.Count; j++)
{
list.Add(edges[vertexNO].Keys[j]);
}
return list;
}
public void RemoveVertexAndRelatedEdges(int vertexNO)
{
if (!vertices.ContainsKey(vertexNO)) return;
vertices.Remove(vertexNO);
List<int> list = NeighbourVerticesOfVertex(vertexNO);
for (int i = 0; i < list.Count; i++)
{
RemoveEdge(vertexNO, list[i]);
}
}
public void RemoveVertexAndRelatedEdges(List<int> vertex_list)
{
for (int i = 0; i < vertex_list.Count; i++)
{
RemoveVertexAndRelatedEdges(vertex_list[i]);
}
}
public void RemoveAllIsolatedVertex()
{
List<int> list = this.Vertices;
for (int i = 0; i < list.Count; i++)
{
if(vertexDegree[list[i],0]==0) RemoveVertex(list[i]);
}
}
public int CoverUndirectedEdgesCount(List<int> vertex_list)
{
SimpleGraph V = this.InducedSubgraph(vertex_list);
int count = 0;
for (int i = 0; i < vertex_list.Count; i++)
{
count+=this.vertexDegree[vertex_list[i],0];
}
return count - V.Edges.Count / 2;
}
public int CoverVerticesCount(List<int> vertex_list)
{
SimpleGraph V = this.Clone();
V.RemoveVertexAndRelatedEdges(vertex_list);
V.RemoveAllIsolatedVertex();
return this.Vertices.Count - V.Vertices.Count;
}
public SimpleGraph InducedSubgraph(List<int> vertex_list)
{
SimpleGraph graph = this.Clone();
SimpleGraph g = new SimpleGraph();
g.AddVertex(vertex_list);
SimpleGraph g2 = SimpleGraphOP.Graph_Vertex_Subtract(graph, g);
graph.RemoveVertexAndRelatedEdges(g2.Vertices);
return graph;
}
//----------------------file operation-------------------
#region file operation
//file formation : vertex={ 2,4,5} edge={ (1,2), (3,4,5) }
public bool Load_MyFormat(string filename)
{
try
{
if (!System.IO.File.Exists(filename)) return false;
StreamReader sr = new StreamReader(filename, System.Text.Encoding.Default);
string content = sr.ReadToEnd();
sr.Close();
#region load vertex
string vertexPattern=@"vertex(\s*)=(\s*){(?<vertexDescribe>[^}]*)}";
Match matchVertex = Regex.Match(content,vertexPattern);
string vertexDescribe = "";
if (matchVertex.Success) vertexDescribe = matchVertex.Groups["vertexDescribe"].Value;
if (vertexDescribe.Length > 0)
{
string[] order = vertexDescribe.Split(',');
for (int i = 0; i < order.Length; i++)
{
if (order[i].Trim().Length > 0)
{
AddVertex(int.Parse(order[i].Trim()));
}
}
}
#endregion
#region load edge
string edgePattern = @"edge(\s*)=(\s*){(?<edgeDescribe>[^}]*)}";
Match matchEdge = Regex.Match(content,edgePattern);
string edgeDescribe = "";
if (matchEdge.Success) edgeDescribe = matchEdge.Groups["edgeDescribe"].Value;
string pattern = @"(\u0028)(\s*)(?<from>[0-9]+)(\s*)(?<link>(->|-|,))(\s*)(?<to>[0-9]+)(\s*)([,\s]*)(?<weight>[0-9.]*)(\s*)(\u0029)";
MatchCollection matches = Regex.Matches(edgeDescribe, pattern);
for (int i = 0; i < matches.Count; i++)
{
int from = int.Parse(matches[i].Groups["from"].Value);
int to = int.Parse(matches[i].Groups["to"].Value);
double weight = double.MaxValue;
if (matches[i].Groups["weight"].Value.Length > 0) weight = double.Parse(matches[i].Groups["weight"].Value);
if (matches[i].Groups["link"].Value == "->")
AddEdge(from, to, weight, SimpleGraph.EdgeStyle_Directed);
else
AddEdge(from, to, weight, SimpleGraph.EdgeStyle_Undirected);
}
#endregion
return true;
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
return false;
}
}
public bool Save(string filename)
{
//设置字符编码很重要,否则会得到乱码
using (StreamWriter sw = new StreamWriter(filename, false, Encoding.Default))
{
List<int> vertex_list = Vertices;
//write vertex info
sw.WriteLine("vertex count="+vertex_list.Count);
sw.WriteLine("vertex=");
sw.WriteLine("{");
for (int i = 0; i < vertex_list.Count; i++)
{
sw.Write(vertex_list[i].ToString() + " ,");
}
sw.WriteLine();
sw.WriteLine("}");
sw.WriteLine();
sw.WriteLine();
// write edge info
sw.WriteLine("edge count=" + this.Edges.Count);
sw.WriteLine("edge=");
sw.WriteLine("{");
for (int i = 0; i < vertex_list.Count; i++)
{
int from = vertex_list[i];
for (int j = 0; j < edges[from].Keys.Count; j++)
{
int to = edges[from].Keys[j];
string edgeStyle = " - ";
if (edges[from][to].edgeStyle == SimpleGraph.EdgeStyle_Directed) edgeStyle = " -> ";
double weight = edges[from][to].weight;
if (weight != double.MaxValue)
sw.Write("(" + from.ToString() + edgeStyle + to.ToString() + " , " + weight.ToString() + " ) ");
else
sw.Write("(" + from.ToString() + edgeStyle + to.ToString() + " ) ");
}
sw.WriteLine();
}
sw.WriteLine("}");
sw.Close();
return true;
}
}
public bool Load(string filename)
{
if (filename.EndsWith("mis")) return Load_MisFile(filename);
return Load_MyFormat(filename);
}
public bool Load_MisFile(string filename)
{
try
{
if (!System.IO.File.Exists(filename)) return false;
StreamReader sr = new StreamReader(filename, System.Text.Encoding.Default);
string content = sr.ReadToEnd();
sr.Close();
#region load edge
string pattern = @"\be(\s*)(?<from>[0-9]+)(\s*)(?<to>[0-9]+)(\s*)";
MatchCollection matches = Regex.Matches(content, pattern);
for (int i = 0; i < matches.Count; i++)
{
int from = int.Parse(matches[i].Groups["from"].Value);
int to = int.Parse(matches[i].Groups["to"].Value);
double weight = double.MaxValue;
AddEdge(from, to, weight, SimpleGraph.EdgeStyle_Undirected);
}
#endregion
return true;
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
return false;
}
}
#endregion
}
}
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace Graph
{
public struct Edge
{
public int from;
public int to;
public int edgeStyle;
public double weight;
public Edge(int _from,int _to,double _weight,int _edgeStyle)
{
from = _from;
to = _to;
edgeStyle = _edgeStyle;
weight = _weight;
}
public Edge(int _from, int _to, int _edgeStyle)
{
from = _from;
to = _to;
edgeStyle = _edgeStyle;
weight = double.MaxValue;
}
}
public partial class SimpleGraph
{
public const int MaxVertexCount = 1000;
public const int EdgeStyle_Undirected = 0;
public const int EdgeStyle_Directed = 1;
SortedList<int, int> vertices = new SortedList<int, int>(); // key and value are same
public int[,] vertexDegree = new int[MaxVertexCount, 3]; // 0 = total degree, 1 = out degree, 2= in degree
public List<int> Vertices
{
get
{
List<int> list = new List<int>();
for (int i = 0; i < vertices.Keys.Count; i++) list.Add(vertices.Keys[i]);
return list;
}
}
public bool VertexIn(int vertexNO)
{
return vertices.ContainsKey(vertexNO);
}
List<SortedList<int, Edge>> edges = new List<SortedList<int, Edge>>(); // key = to vertex NO,
public List<Edge> Edges
{
get
{
List<Edge> list = new List<Edge>();
List<int> vertex_list = Vertices;
for (int i = 0; i < vertex_list.Count; i++)
{
int from = vertex_list[i];
for (int j = 0; j < edges[from].Keys.Count; j++)
{
int to= edges[from].Keys[j];
Edge edge = edges[from][to];
list.Add(edge);
}
}
return list;
}
}
public bool EdgeIn(int from, int to)
{
return edges[from].ContainsKey(to);
}
public bool EdgeIn(Edge e)
{
return edges[e.from ].ContainsKey(e.to);
}
public Edge this[int from, int to]
{
get
{
if(edges[from].ContainsKey(to)) return edges[from][to];
return default(Edge);
}
}
public SimpleGraph()
{
for (int i = 0; i < MaxVertexCount; i++)
{
edges.Add(new SortedList<int, Edge>());
}
for (int i = 0; i < MaxVertexCount; i++)
{
vertexDegree[i, 0] = vertexDegree[i,1] = vertexDegree[i, 2] = 0;
}
}
public SimpleGraph Clone()
{
SimpleGraph graph = new SimpleGraph();
graph.AddVertex(this.Vertices);
List<Edge> edge_list = this.Edges;
for (int i = 0; i < edge_list.Count; i++)
{
graph.AddEdge(edge_list[i]);
}
return graph;
}
public void Clear()
{
vertices.Clear();
for (int i = 0; i < MaxVertexCount; i++) edges[i].Clear();
}
public void AddVertex(int vertexNO)
{
if (!vertices.ContainsKey(vertexNO)) vertices.Add(vertexNO, vertexNO);
}
public void RemoveVertex(int vertexNO)
{
vertices.Remove(vertexNO);
}
public void AddVertex(List<int> vertex_list)
{
for (int i = 0; i < vertex_list.Count; i++) AddVertex(vertex_list[i]);
}
public void RemoveVertex(List<int> vertex_list)
{
for (int i = 0; i < vertex_list.Count; i++) vertices.Remove(vertex_list[i]);
}
public virtual bool AddEdge(Edge e)
{
int from = e.from;
int to = e.to;
if (!vertices.ContainsKey(from)) vertices.Add(from, from);
if (!vertices.ContainsKey(to)) vertices.Add(to, to);
if (edges[from].ContainsKey(to)) return false; // there is a same edge , conflict
edges[from].Add(to,e);
vertexDegree[from, 0]++;
vertexDegree[from, 1]++;
vertexDegree[to, 0]++;
vertexDegree[to, 2]++;
if (e.edgeStyle == EdgeStyle_Undirected)
{
if (edges[to].ContainsKey(from)) return false; // there is a same edge , conflict
Edge e2 = new Edge(to, from, e.weight, e.edgeStyle);
edges[to].Add(from,e2);
vertexDegree[from, 2]++;
vertexDegree[to, 1]++;
}
return true;
}
public virtual bool AddEdge(int from,int to,double weight,int edgeStyle)
{
Edge e = new Edge(from, to, weight, edgeStyle);
return AddEdge(e);
}
public virtual bool AddEdge(int from, int to, int edgeStyle)
{
Edge e = new Edge(from, to, edgeStyle);
return AddEdge(e);
}
public bool RemoveEdge(int from, int to)
{
if (!edges[from].ContainsKey(to)) return false;
int edgeStyle=edges[from][to].edgeStyle;
edges[from].Remove(to);
vertexDegree[from, 0]--;
vertexDegree[from, 1]--;
vertexDegree[to, 0]--;
vertexDegree[to, 2]--;
if (edgeStyle == EdgeStyle_Undirected)
{
edges[to].Remove(from);
vertexDegree[from, 2]--;
vertexDegree[to, 1]--;
}
return true;
}
public bool RemoveEdge(Edge e)
{
return RemoveEdge(e.from, e.to);
}
public void RemoveEdgeAndZeroVertex(int from, int to)
{
RemoveEdge(from, to);
if (vertexDegree[from,0] == 0) vertices.Remove(from);
if (vertexDegree[to, 0] == 0) vertices.Remove(to);
}
public void RemoveEdgeAndZeroVertex(Edge e)
{
RemoveEdgeAndZeroVertex(e.from, e.to);
}
public List<Edge> NeighbourEdgesOfVertex(int vertexNO)
{
List<Edge> list = new List<Edge>();
int from = vertexNO;
for (int j = 0; j < edges[from].Keys.Count; j++)
{
int to = edges[from].Keys[j];
list.Add(edges[from][to]);
}
return list;
}
public List<int> NeighbourVerticesOfVertex(int vertexNO)
{
List<int> list = new List<int>();
for (int j = 0; j < edges[vertexNO].Keys.Count; j++)
{
list.Add(edges[vertexNO].Keys[j]);
}
return list;
}
public void RemoveVertexAndRelatedEdges(int vertexNO)
{
if (!vertices.ContainsKey(vertexNO)) return;
vertices.Remove(vertexNO);
List<int> list = NeighbourVerticesOfVertex(vertexNO);
for (int i = 0; i < list.Count; i++)
{
RemoveEdge(vertexNO, list[i]);
}
}
public void RemoveVertexAndRelatedEdges(List<int> vertex_list)
{
for (int i = 0; i < vertex_list.Count; i++)
{
RemoveVertexAndRelatedEdges(vertex_list[i]);
}
}
public void RemoveAllIsolatedVertex()
{
List<int> list = this.Vertices;
for (int i = 0; i < list.Count; i++)
{
if(vertexDegree[list[i],0]==0) RemoveVertex(list[i]);
}
}
public int CoverUndirectedEdgesCount(List<int> vertex_list)
{
SimpleGraph V = this.InducedSubgraph(vertex_list);
int count = 0;
for (int i = 0; i < vertex_list.Count; i++)
{
count+=this.vertexDegree[vertex_list[i],0];
}
return count - V.Edges.Count / 2;
}
public int CoverVerticesCount(List<int> vertex_list)
{
SimpleGraph V = this.Clone();
V.RemoveVertexAndRelatedEdges(vertex_list);
V.RemoveAllIsolatedVertex();
return this.Vertices.Count - V.Vertices.Count;
}
public SimpleGraph InducedSubgraph(List<int> vertex_list)
{
SimpleGraph graph = this.Clone();
SimpleGraph g = new SimpleGraph();
g.AddVertex(vertex_list);
SimpleGraph g2 = SimpleGraphOP.Graph_Vertex_Subtract(graph, g);
graph.RemoveVertexAndRelatedEdges(g2.Vertices);
return graph;
}
//----------------------file operation-------------------
#region file operation
//file formation : vertex={ 2,4,5} edge={ (1,2), (3,4,5) }
public bool Load_MyFormat(string filename)
{
try
{
if (!System.IO.File.Exists(filename)) return false;
StreamReader sr = new StreamReader(filename, System.Text.Encoding.Default);
string content = sr.ReadToEnd();
sr.Close();
#region load vertex
string vertexPattern=@"vertex(\s*)=(\s*){(?<vertexDescribe>[^}]*)}";
Match matchVertex = Regex.Match(content,vertexPattern);
string vertexDescribe = "";
if (matchVertex.Success) vertexDescribe = matchVertex.Groups["vertexDescribe"].Value;
if (vertexDescribe.Length > 0)
{
string[] order = vertexDescribe.Split(',');
for (int i = 0; i < order.Length; i++)
{
if (order[i].Trim().Length > 0)
{
AddVertex(int.Parse(order[i].Trim()));
}
}
}
#endregion
#region load edge
string edgePattern = @"edge(\s*)=(\s*){(?<edgeDescribe>[^}]*)}";
Match matchEdge = Regex.Match(content,edgePattern);
string edgeDescribe = "";
if (matchEdge.Success) edgeDescribe = matchEdge.Groups["edgeDescribe"].Value;
string pattern = @"(\u0028)(\s*)(?<from>[0-9]+)(\s*)(?<link>(->|-|,))(\s*)(?<to>[0-9]+)(\s*)([,\s]*)(?<weight>[0-9.]*)(\s*)(\u0029)";
MatchCollection matches = Regex.Matches(edgeDescribe, pattern);
for (int i = 0; i < matches.Count; i++)
{
int from = int.Parse(matches[i].Groups["from"].Value);
int to = int.Parse(matches[i].Groups["to"].Value);
double weight = double.MaxValue;
if (matches[i].Groups["weight"].Value.Length > 0) weight = double.Parse(matches[i].Groups["weight"].Value);
if (matches[i].Groups["link"].Value == "->")
AddEdge(from, to, weight, SimpleGraph.EdgeStyle_Directed);
else
AddEdge(from, to, weight, SimpleGraph.EdgeStyle_Undirected);
}
#endregion
return true;
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
return false;
}
}
public bool Save(string filename)
{
//设置字符编码很重要,否则会得到乱码
using (StreamWriter sw = new StreamWriter(filename, false, Encoding.Default))
{
List<int> vertex_list = Vertices;
//write vertex info
sw.WriteLine("vertex count="+vertex_list.Count);
sw.WriteLine("vertex=");
sw.WriteLine("{");
for (int i = 0; i < vertex_list.Count; i++)
{
sw.Write(vertex_list[i].ToString() + " ,");
}
sw.WriteLine();
sw.WriteLine("}");
sw.WriteLine();
sw.WriteLine();
// write edge info
sw.WriteLine("edge count=" + this.Edges.Count);
sw.WriteLine("edge=");
sw.WriteLine("{");
for (int i = 0; i < vertex_list.Count; i++)
{
int from = vertex_list[i];
for (int j = 0; j < edges[from].Keys.Count; j++)
{
int to = edges[from].Keys[j];
string edgeStyle = " - ";
if (edges[from][to].edgeStyle == SimpleGraph.EdgeStyle_Directed) edgeStyle = " -> ";
double weight = edges[from][to].weight;
if (weight != double.MaxValue)
sw.Write("(" + from.ToString() + edgeStyle + to.ToString() + " , " + weight.ToString() + " ) ");
else
sw.Write("(" + from.ToString() + edgeStyle + to.ToString() + " ) ");
}
sw.WriteLine();
}
sw.WriteLine("}");
sw.Close();
return true;
}
}
public bool Load(string filename)
{
if (filename.EndsWith("mis")) return Load_MisFile(filename);
return Load_MyFormat(filename);
}
public bool Load_MisFile(string filename)
{
try
{
if (!System.IO.File.Exists(filename)) return false;
StreamReader sr = new StreamReader(filename, System.Text.Encoding.Default);
string content = sr.ReadToEnd();
sr.Close();
#region load edge
string pattern = @"\be(\s*)(?<from>[0-9]+)(\s*)(?<to>[0-9]+)(\s*)";
MatchCollection matches = Regex.Matches(content, pattern);
for (int i = 0; i < matches.Count; i++)
{
int from = int.Parse(matches[i].Groups["from"].Value);
int to = int.Parse(matches[i].Groups["to"].Value);
double weight = double.MaxValue;
AddEdge(from, to, weight, SimpleGraph.EdgeStyle_Undirected);
}
#endregion
return true;
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
return false;
}
}
#endregion
}
}
二分图
BipartiteGraph
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Graph
{
class BipartiteGraph : SimpleGraph
{
public const int VertexStyle_Left = 1;
public const int VertexStyle_Right = 2;
int[] vertex_kind = new int[SimpleGraph.MaxVertexCount];
public List<int> LeftVertices
{
get
{
List<int> list = new List<int>();
List<int> allVertex = Vertices;
for (int i = 0; i < allVertex.Count; i++)
{
if (vertex_kind[allVertex[i]] == VertexStyle_Left) list.Add(allVertex[i]);
}
return list;
}
}
public List<int> RightVertices
{
get
{
List<int> list = new List<int>();
List<int> allVertex = Vertices;
for (int i = 0; i < allVertex.Count; i++)
{
if (vertex_kind[allVertex[i]] == VertexStyle_Right) list.Add(allVertex[i]);
}
return list;
}
}
public override bool AddEdge(Edge e)
{
int from=e.from;
int to=e.to;
if ((vertex_kind[from] == VertexStyle_Right) || (vertex_kind[to] == VertexStyle_Left))
{
//MessageBox.Show("bipartite vertext conflict " + from.ToString() + " " + to.ToString());
return false;
}
vertex_kind[from] = VertexStyle_Left;
vertex_kind[to] = VertexStyle_Right;
return base.AddEdge(e);
}
public SimpleGraph FindOneMinimumVertexCovering( )
{
SimpleGraph match = FindOneMaxMatch();
return FindOneMinimumVertexCovering(match);
}
public SimpleGraph FindOneMinimumVertexCovering(SimpleGraph match)
{
SimpleGraph unmatched = SimpleGraphOP.Graph_Edge_Subtract(this, match);
SimpleGraph X = new SimpleGraph();
X.AddVertex(this.LeftVertices);
SimpleGraph label_X = SimpleGraphOP.Graph_Vertex_Subtract(X, match);
SimpleGraph lable_Y = SimpleGraphOP.Graph_ReachVerticesByEdge(label_X.Vertices, unmatched.Edges);
SimpleGraph lable_X_New = SimpleGraphOP.Graph_ReachVerticesByEdge(lable_Y.Vertices, match.Edges);
lable_X_New.RemoveVertex(label_X.Vertices);
while (lable_X_New.Vertices.Count>0)
{
label_X.AddVertex(lable_X_New.Vertices);
SimpleGraph lable_Y_New = SimpleGraphOP.Graph_ReachVerticesByEdge(lable_X_New.Vertices, unmatched.Edges);
lable_Y.AddVertex(lable_Y_New.Vertices);
lable_X_New = SimpleGraphOP.Graph_ReachVerticesByEdge(lable_Y.Vertices, match.Edges);
lable_X_New.RemoveVertex(label_X.Vertices);
}
SimpleGraph MVC = new SimpleGraph();
MVC.AddVertex(X.Vertices);
MVC.RemoveVertex(label_X.Vertices);
MVC.AddVertex(lable_Y.Vertices);
return MVC;
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Graph
{
class BipartiteGraph : SimpleGraph
{
public const int VertexStyle_Left = 1;
public const int VertexStyle_Right = 2;
int[] vertex_kind = new int[SimpleGraph.MaxVertexCount];
public List<int> LeftVertices
{
get
{
List<int> list = new List<int>();
List<int> allVertex = Vertices;
for (int i = 0; i < allVertex.Count; i++)
{
if (vertex_kind[allVertex[i]] == VertexStyle_Left) list.Add(allVertex[i]);
}
return list;
}
}
public List<int> RightVertices
{
get
{
List<int> list = new List<int>();
List<int> allVertex = Vertices;
for (int i = 0; i < allVertex.Count; i++)
{
if (vertex_kind[allVertex[i]] == VertexStyle_Right) list.Add(allVertex[i]);
}
return list;
}
}
public override bool AddEdge(Edge e)
{
int from=e.from;
int to=e.to;
if ((vertex_kind[from] == VertexStyle_Right) || (vertex_kind[to] == VertexStyle_Left))
{
//MessageBox.Show("bipartite vertext conflict " + from.ToString() + " " + to.ToString());
return false;
}
vertex_kind[from] = VertexStyle_Left;
vertex_kind[to] = VertexStyle_Right;
return base.AddEdge(e);
}
public SimpleGraph FindOneMinimumVertexCovering( )
{
SimpleGraph match = FindOneMaxMatch();
return FindOneMinimumVertexCovering(match);
}
public SimpleGraph FindOneMinimumVertexCovering(SimpleGraph match)
{
SimpleGraph unmatched = SimpleGraphOP.Graph_Edge_Subtract(this, match);
SimpleGraph X = new SimpleGraph();
X.AddVertex(this.LeftVertices);
SimpleGraph label_X = SimpleGraphOP.Graph_Vertex_Subtract(X, match);
SimpleGraph lable_Y = SimpleGraphOP.Graph_ReachVerticesByEdge(label_X.Vertices, unmatched.Edges);
SimpleGraph lable_X_New = SimpleGraphOP.Graph_ReachVerticesByEdge(lable_Y.Vertices, match.Edges);
lable_X_New.RemoveVertex(label_X.Vertices);
while (lable_X_New.Vertices.Count>0)
{
label_X.AddVertex(lable_X_New.Vertices);
SimpleGraph lable_Y_New = SimpleGraphOP.Graph_ReachVerticesByEdge(lable_X_New.Vertices, unmatched.Edges);
lable_Y.AddVertex(lable_Y_New.Vertices);
lable_X_New = SimpleGraphOP.Graph_ReachVerticesByEdge(lable_Y.Vertices, match.Edges);
lable_X_New.RemoveVertex(label_X.Vertices);
}
SimpleGraph MVC = new SimpleGraph();
MVC.AddVertex(X.Vertices);
MVC.RemoveVertex(label_X.Vertices);
MVC.AddVertex(lable_Y.Vertices);
return MVC;
}
}
}
对Graph操作的类
SimpleGraphOP
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Graph
{
class SimpleGraphOP
{
public static SimpleGraph Graph_Edge_Union(SimpleGraph graph1, SimpleGraph graph2)
{
List<Edge> edge1_list = graph1.Edges;
List<Edge> edge2_list = graph2.Edges;
SimpleGraph graph = new SimpleGraph();
for (int i = 0; i < edge1_list.Count; i++)
{
graph.AddEdge(edge1_list[i]);
}
for (int i = 0; i < edge2_list.Count; i++)
{
graph.AddEdge(edge2_list[i]);
}
return graph;
}
public static SimpleGraph Graph_Edge_Subtract(SimpleGraph graph1, SimpleGraph graph2)
{
List<Edge> edge1_list = graph1.Edges;
List<Edge> edge2_list = graph2.Edges;
SimpleGraph graph = new SimpleGraph();
for (int i = 0; i < edge1_list.Count; i++)
{
graph.AddEdge(edge1_list[i]);
}
for (int i = 0; i < edge2_list.Count; i++)
{
graph.RemoveEdgeAndZeroVertex(edge2_list[i]);
}
return graph;
}
public static SimpleGraph Graph_Edge_SymmetricDifference(SimpleGraph graph1, SimpleGraph graph2)
{
List<Edge> edge1_list = graph1.Edges;
List<Edge> edge2_list = graph2.Edges;
SimpleGraph graph = new SimpleGraph();
for (int i = 0; i < edge1_list.Count; i++)
{
if (!graph2.EdgeIn(edge1_list[i]))
graph.AddEdge(edge1_list[i]);
}
for (int i = 0; i < edge2_list.Count; i++)
{
if (!graph1.EdgeIn(edge2_list[i]))
graph.AddEdge(edge2_list[i]);
}
return graph;
}
public static SimpleGraph Graph_Vertex_Union(SimpleGraph graph1, SimpleGraph graph2)
{
SimpleGraph graph = new SimpleGraph();
graph.AddVertex(graph1.Vertices);
graph.AddVertex(graph2.Vertices);
return graph;
}
public static SimpleGraph Graph_Vertex_Subtract(List<int> vertex_list1, List<int> vertex_list2)
{
SimpleGraph graph = new SimpleGraph();
graph.AddVertex(vertex_list1);
graph.RemoveVertex(vertex_list2);
return graph;
}
public static SimpleGraph Graph_Vertex_Subtract(SimpleGraph graph1, List<int> vertex_list)
{
return Graph_Vertex_Subtract(graph1.Vertices, vertex_list);
}
public static SimpleGraph Graph_Vertex_Subtract(SimpleGraph graph1, SimpleGraph graph2)
{
return Graph_Vertex_Subtract(graph1.Vertices,graph2.Vertices);
}
public static SimpleGraph Graph_ReachVerticesByEdge(int vertex, List<Edge> edge_list)
{
SimpleGraph graph = new SimpleGraph();
for (int i = 0; i < edge_list.Count; i++)
{
graph.AddEdge(edge_list[i]);
}
SimpleGraph reachVertexGraph = new SimpleGraph();
reachVertexGraph.AddVertex(graph.NeighbourVerticesOfVertex(vertex));
return reachVertexGraph;
}
public static SimpleGraph Graph_ReachVerticesByEdge(List<int> vertex_list, List<Edge> edge_list)
{
SimpleGraph graph = new SimpleGraph();
for (int i = 0; i < edge_list.Count; i++)
{
graph.AddEdge(edge_list[i]);
}
SimpleGraph reachVertexGraph = new SimpleGraph();
for (int i = 0; i < vertex_list.Count; i++)
{
reachVertexGraph.AddVertex(graph.NeighbourVerticesOfVertex(vertex_list[i]));
}
return reachVertexGraph;
}
public static SimpleGraph Graph_RemoveVertexAndRelatedEdges(SimpleGraph graph, int vertex)
{
SimpleGraph g = graph.Clone();
g.RemoveVertexAndRelatedEdges(vertex);
return g;
}
public static SimpleGraph Graph_RemoveVertexAndRelatedEdges(SimpleGraph graph, List<int> vertex_list)
{
SimpleGraph g = graph.Clone();
g.RemoveVertexAndRelatedEdges(vertex_list);
return g;
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Graph
{
class SimpleGraphOP
{
public static SimpleGraph Graph_Edge_Union(SimpleGraph graph1, SimpleGraph graph2)
{
List<Edge> edge1_list = graph1.Edges;
List<Edge> edge2_list = graph2.Edges;
SimpleGraph graph = new SimpleGraph();
for (int i = 0; i < edge1_list.Count; i++)
{
graph.AddEdge(edge1_list[i]);
}
for (int i = 0; i < edge2_list.Count; i++)
{
graph.AddEdge(edge2_list[i]);
}
return graph;
}
public static SimpleGraph Graph_Edge_Subtract(SimpleGraph graph1, SimpleGraph graph2)
{
List<Edge> edge1_list = graph1.Edges;
List<Edge> edge2_list = graph2.Edges;
SimpleGraph graph = new SimpleGraph();
for (int i = 0; i < edge1_list.Count; i++)
{
graph.AddEdge(edge1_list[i]);
}
for (int i = 0; i < edge2_list.Count; i++)
{
graph.RemoveEdgeAndZeroVertex(edge2_list[i]);
}
return graph;
}
public static SimpleGraph Graph_Edge_SymmetricDifference(SimpleGraph graph1, SimpleGraph graph2)
{
List<Edge> edge1_list = graph1.Edges;
List<Edge> edge2_list = graph2.Edges;
SimpleGraph graph = new SimpleGraph();
for (int i = 0; i < edge1_list.Count; i++)
{
if (!graph2.EdgeIn(edge1_list[i]))
graph.AddEdge(edge1_list[i]);
}
for (int i = 0; i < edge2_list.Count; i++)
{
if (!graph1.EdgeIn(edge2_list[i]))
graph.AddEdge(edge2_list[i]);
}
return graph;
}
public static SimpleGraph Graph_Vertex_Union(SimpleGraph graph1, SimpleGraph graph2)
{
SimpleGraph graph = new SimpleGraph();
graph.AddVertex(graph1.Vertices);
graph.AddVertex(graph2.Vertices);
return graph;
}
public static SimpleGraph Graph_Vertex_Subtract(List<int> vertex_list1, List<int> vertex_list2)
{
SimpleGraph graph = new SimpleGraph();
graph.AddVertex(vertex_list1);
graph.RemoveVertex(vertex_list2);
return graph;
}
public static SimpleGraph Graph_Vertex_Subtract(SimpleGraph graph1, List<int> vertex_list)
{
return Graph_Vertex_Subtract(graph1.Vertices, vertex_list);
}
public static SimpleGraph Graph_Vertex_Subtract(SimpleGraph graph1, SimpleGraph graph2)
{
return Graph_Vertex_Subtract(graph1.Vertices,graph2.Vertices);
}
public static SimpleGraph Graph_ReachVerticesByEdge(int vertex, List<Edge> edge_list)
{
SimpleGraph graph = new SimpleGraph();
for (int i = 0; i < edge_list.Count; i++)
{
graph.AddEdge(edge_list[i]);
}
SimpleGraph reachVertexGraph = new SimpleGraph();
reachVertexGraph.AddVertex(graph.NeighbourVerticesOfVertex(vertex));
return reachVertexGraph;
}
public static SimpleGraph Graph_ReachVerticesByEdge(List<int> vertex_list, List<Edge> edge_list)
{
SimpleGraph graph = new SimpleGraph();
for (int i = 0; i < edge_list.Count; i++)
{
graph.AddEdge(edge_list[i]);
}
SimpleGraph reachVertexGraph = new SimpleGraph();
for (int i = 0; i < vertex_list.Count; i++)
{
reachVertexGraph.AddVertex(graph.NeighbourVerticesOfVertex(vertex_list[i]));
}
return reachVertexGraph;
}
public static SimpleGraph Graph_RemoveVertexAndRelatedEdges(SimpleGraph graph, int vertex)
{
SimpleGraph g = graph.Clone();
g.RemoveVertexAndRelatedEdges(vertex);
return g;
}
public static SimpleGraph Graph_RemoveVertexAndRelatedEdges(SimpleGraph graph, List<int> vertex_list)
{
SimpleGraph g = graph.Clone();
g.RemoveVertexAndRelatedEdges(vertex_list);
return g;
}
}
}
图论算法 大家可添加自己的类 完成不同的算法
例如我写的几个类
寻找最大匹配
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Graph
{
public partial class SimpleGraph
{
public SimpleGraph FindAugmentPath(int from, SimpleGraph augmentPath, SimpleGraph matchGraph)
{
List<int> linkToVertices = NeighbourVerticesOfVertex(from);
for (int j = 0; j < linkToVertices.Count; j++)
{
int to = linkToVertices[j];
if (augmentPath.VertexIn(to)) continue; // vertex should not be in augment path
if (!matchGraph.VertexIn(to)) // find a unmatched edge, augment path
{
augmentPath.AddEdge(from, to, SimpleGraph.EdgeStyle_Undirected);
return augmentPath;
}
else // find a matched edge
{
List<int> list = matchGraph.NeighbourVerticesOfVertex(to);
if (list.Count > 0)
{
augmentPath.AddEdge(from, to, SimpleGraph.EdgeStyle_Undirected);
augmentPath.AddEdge(to, list[0], EdgeStyle_Undirected);
SimpleGraph result = FindAugmentPath(list[0], augmentPath, matchGraph);
if (result != null)
{
return SimpleGraphOP.Graph_Edge_Union(augmentPath, result);
}
else // restore augment path for next search
{
augmentPath.RemoveEdge(from, to);
augmentPath.RemoveEdge(to, list[0]);
augmentPath.RemoveAllIsolatedVertex();
}
}
}
}
return null;
}
public SimpleGraph FindOneMaxMatch()
{
SimpleGraph matchGraph = new SimpleGraph();
for (int i = 0; i < Vertices.Count; i++)
{
if (!matchGraph.VertexIn(Vertices[i])) // if it is marked vertex, find next vertex
{
SimpleGraph path = new SimpleGraph();
SimpleGraph augmentPath = FindAugmentPath(Vertices[i], path, matchGraph);
if (augmentPath != null)
{
matchGraph = SimpleGraphOP.Graph_Edge_SymmetricDifference(matchGraph, augmentPath);
}
}
}
return matchGraph;
}
// not correct
//public SimpleGraph FindOneMinimumVertexCovering(SimpleGraph match)
//{
// SimpleGraph Z0 = SimpleGraphOP.Graph_Vertex_Subtract(this, match);
// SimpleGraph Z1 = SimpleGraphOP.Graph_ReachVerticesByEdge(Z0.Vertices, this.Edges); // these must be in minimum vertex covering
// SimpleGraph Z21 = SimpleGraphOP.Graph_RemoveVertexAndRelatedEdges(match, Z1.Vertices);
// Z21.RemoveAllIsolatedVertex();
// SimpleGraph left = new SimpleGraph();
// while (Z21.Vertices.Count > 0)
// {
// int vertex = Z21.Vertices[0];
// left.AddVertex(vertex);
// Z21.RemoveVertexAndRelatedEdges(vertex);
// Z21.RemoveAllIsolatedVertex();
// }
// SimpleGraph MVC = SimpleGraphOP.Graph_Vertex_Union(Z1, left);
// return MVC;
//}
//void IterateFindLocalMaxMatch(SimpleGraph graph, SimpleGraph match, List<SimpleGraph> simpleGraph_localMaxMatch_list)
//{
// List<int[]> edge_list = graph.Edges;
// if (edge_list.Count == 0)
// {
// simpleGraph_localMaxMatch_list.Add(match);
// }
// else
// {
// for (int i = 0; i < edge_list.Count; i++)
// {
// SimpleGraph g = SimpleGraphOP.Graph_RemoveVertexAndRelatedEdges(graph, edge_list[i][0]);
// g = SimpleGraphOP.Graph_RemoveVertexAndRelatedEdges(g, edge_list[i][1]);
// g.RemoveAllIsolatedVertex();
// SimpleGraph newMatch = match.Clone();
// newMatch.AddEdge(edge_list[i]);
// IterateFindLocalMaxMatch(g, newMatch, simpleGraph_localMaxMatch_list);
// }
// }
//}
//public List<SimpleGraph> FindAllMatch()
//{
// List<SimpleGraph> simpleGraph_localMaxMatch_list = new List<SimpleGraph>();
// SimpleGraph g = this.Clone();
// SimpleGraph match = new SimpleGraph();
// IterateFindLocalMaxMatch(g, match, simpleGraph_localMaxMatch_list);
// return simpleGraph_localMaxMatch_list;
//}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Graph
{
public partial class SimpleGraph
{
public SimpleGraph FindAugmentPath(int from, SimpleGraph augmentPath, SimpleGraph matchGraph)
{
List<int> linkToVertices = NeighbourVerticesOfVertex(from);
for (int j = 0; j < linkToVertices.Count; j++)
{
int to = linkToVertices[j];
if (augmentPath.VertexIn(to)) continue; // vertex should not be in augment path
if (!matchGraph.VertexIn(to)) // find a unmatched edge, augment path
{
augmentPath.AddEdge(from, to, SimpleGraph.EdgeStyle_Undirected);
return augmentPath;
}
else // find a matched edge
{
List<int> list = matchGraph.NeighbourVerticesOfVertex(to);
if (list.Count > 0)
{
augmentPath.AddEdge(from, to, SimpleGraph.EdgeStyle_Undirected);
augmentPath.AddEdge(to, list[0], EdgeStyle_Undirected);
SimpleGraph result = FindAugmentPath(list[0], augmentPath, matchGraph);
if (result != null)
{
return SimpleGraphOP.Graph_Edge_Union(augmentPath, result);
}
else // restore augment path for next search
{
augmentPath.RemoveEdge(from, to);
augmentPath.RemoveEdge(to, list[0]);
augmentPath.RemoveAllIsolatedVertex();
}
}
}
}
return null;
}
public SimpleGraph FindOneMaxMatch()
{
SimpleGraph matchGraph = new SimpleGraph();
for (int i = 0; i < Vertices.Count; i++)
{
if (!matchGraph.VertexIn(Vertices[i])) // if it is marked vertex, find next vertex
{
SimpleGraph path = new SimpleGraph();
SimpleGraph augmentPath = FindAugmentPath(Vertices[i], path, matchGraph);
if (augmentPath != null)
{
matchGraph = SimpleGraphOP.Graph_Edge_SymmetricDifference(matchGraph, augmentPath);
}
}
}
return matchGraph;
}
// not correct
//public SimpleGraph FindOneMinimumVertexCovering(SimpleGraph match)
//{
// SimpleGraph Z0 = SimpleGraphOP.Graph_Vertex_Subtract(this, match);
// SimpleGraph Z1 = SimpleGraphOP.Graph_ReachVerticesByEdge(Z0.Vertices, this.Edges); // these must be in minimum vertex covering
// SimpleGraph Z21 = SimpleGraphOP.Graph_RemoveVertexAndRelatedEdges(match, Z1.Vertices);
// Z21.RemoveAllIsolatedVertex();
// SimpleGraph left = new SimpleGraph();
// while (Z21.Vertices.Count > 0)
// {
// int vertex = Z21.Vertices[0];
// left.AddVertex(vertex);
// Z21.RemoveVertexAndRelatedEdges(vertex);
// Z21.RemoveAllIsolatedVertex();
// }
// SimpleGraph MVC = SimpleGraphOP.Graph_Vertex_Union(Z1, left);
// return MVC;
//}
//void IterateFindLocalMaxMatch(SimpleGraph graph, SimpleGraph match, List<SimpleGraph> simpleGraph_localMaxMatch_list)
//{
// List<int[]> edge_list = graph.Edges;
// if (edge_list.Count == 0)
// {
// simpleGraph_localMaxMatch_list.Add(match);
// }
// else
// {
// for (int i = 0; i < edge_list.Count; i++)
// {
// SimpleGraph g = SimpleGraphOP.Graph_RemoveVertexAndRelatedEdges(graph, edge_list[i][0]);
// g = SimpleGraphOP.Graph_RemoveVertexAndRelatedEdges(g, edge_list[i][1]);
// g.RemoveAllIsolatedVertex();
// SimpleGraph newMatch = match.Clone();
// newMatch.AddEdge(edge_list[i]);
// IterateFindLocalMaxMatch(g, newMatch, simpleGraph_localMaxMatch_list);
// }
// }
//}
//public List<SimpleGraph> FindAllMatch()
//{
// List<SimpleGraph> simpleGraph_localMaxMatch_list = new List<SimpleGraph>();
// SimpleGraph g = this.Clone();
// SimpleGraph match = new SimpleGraph();
// IterateFindLocalMaxMatch(g, match, simpleGraph_localMaxMatch_list);
// return simpleGraph_localMaxMatch_list;
//}
}
}
去皇冠
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Graph
{
class CrownReduce
{
public const int Boundary = SimpleGraph.MaxVertexCount / 2;
public static SimpleGraph[] NT_Reduce(SimpleGraph graph)
{
BipartiteGraph BG = new BipartiteGraph(); // right vertices NO add Bound
List<Edge> edge_list = graph.Edges;
for (int i = 0; i < edge_list.Count; i++)
{
Edge e = edge_list[i];
Edge e2 = new Edge(e.from, e.to + Boundary, e.weight, e.edgeStyle);
BG.AddEdge(e2);
}
SimpleGraph mvc = BG.FindOneMinimumVertexCovering();
SimpleGraph V0 = new SimpleGraph();
SimpleGraph V1 = new SimpleGraph();
for (int i = 0; i < graph.Vertices.Count; i++)
{
int vertex = graph.Vertices[i];
if (mvc.VertexIn(vertex) && mvc.VertexIn(vertex + Boundary)) V1.AddVertex(vertex);
if ((!mvc.VertexIn(vertex)) && (!mvc.VertexIn(vertex + Boundary))) V0.AddVertex(vertex);
}
SimpleGraph V12 = SimpleGraphOP.Graph_Vertex_Subtract(graph, V0);
V12 = SimpleGraphOP.Graph_Vertex_Subtract(V12, V1);
V12 = graph.InducedSubgraph(V12.Vertices);
return new SimpleGraph[] { V0, V1 ,V12};
}
public static SimpleGraph Crown_NT_Reduce_All(SimpleGraph graph)
{
SimpleGraph g = graph.Clone();
while (true)
{
int count = g.Vertices.Count;
SimpleGraph[] graphes = NT_Reduce(g);
g = graphes[2];
if (count == g.Vertices.Count) break;
}
return g;
}
public static SimpleGraph Crown_Faisal_Reduce_All(SimpleGraph graph)
{
SimpleGraph g = graph.Clone();
while (true)
{
int count = g.Vertices.Count;
SimpleGraph[] graphes = Find_Crown_Faisal(g);
g = graphes[2];
if (count == g.Vertices.Count) break;
}
return g;
}
public static SimpleGraph[] Find_Crown_Faisal(SimpleGraph graph)
{
SimpleGraph g = graph.Clone();
SimpleGraph match=g.FindOneMaxMatch();
SimpleGraph unmatched = SimpleGraphOP.Graph_Vertex_Subtract(g, match);
SimpleGraph neighbour = SimpleGraphOP.Graph_ReachVerticesByEdge(unmatched.Vertices, g.Edges);
SimpleGraph u = SimpleGraphOP.Graph_Vertex_Union(unmatched, neighbour);
SimpleGraph subgraph = g.InducedSubgraph(u.Vertices);
SimpleGraph match2 = subgraph.FindOneMaxMatch();
SimpleGraph I0 = SimpleGraphOP.Graph_Vertex_Subtract(unmatched, match2); // unmatched.Clone();//
SimpleGraph NI = SimpleGraphOP.Graph_ReachVerticesByEdge(I0.Vertices, g.Edges);
SimpleGraph In = SimpleGraphOP.Graph_ReachVerticesByEdge(NI.Vertices, match2.Edges);
while (true)
{
int count = I0.Vertices.Count;
I0 = SimpleGraphOP.Graph_Vertex_Union(I0, In);
if (count == I0.Vertices.Count) break;
NI = SimpleGraphOP.Graph_ReachVerticesByEdge(I0.Vertices, g.Edges);
In = SimpleGraphOP.Graph_ReachVerticesByEdge(NI.Vertices, match2.Edges);
}
SimpleGraph Left = SimpleGraphOP.Graph_Vertex_Subtract(graph, I0);
Left = SimpleGraphOP.Graph_Vertex_Subtract(Left, NI);
Left = graph.InducedSubgraph(Left.Vertices);
return new SimpleGraph[] { I0, NI, Left };
}
//public static SimpleGraph[] Find_Crown_Faisal_test(SimpleGraph graph)
//{
// SimpleGraph g = graph.Clone();
// SimpleGraph match = g.FindOneMaxMatch();
// SimpleGraph I0 = SimpleGraphOP.Graph_Vertex_Subtract(g, match);
// SimpleGraph NI = SimpleGraphOP.Graph_ReachVerticesByEdge(I0.Vertices, g.Edges);
// SimpleGraph In = SimpleGraphOP.Graph_ReachVerticesByEdge(NI.Vertices, match.Edges);
// while (true)
// {
// int count = I0.Vertices.Count;
// I0 = SimpleGraphOP.Graph_Vertex_Union(I0, In);
// if (count == I0.Vertices.Count) break;
// NI = SimpleGraphOP.Graph_ReachVerticesByEdge(I0.Vertices, g.Edges);
// In = SimpleGraphOP.Graph_ReachVerticesByEdge(NI.Vertices, match.Edges);
// }
// return new SimpleGraph[] { I0, NI };
//}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Graph
{
class CrownReduce
{
public const int Boundary = SimpleGraph.MaxVertexCount / 2;
public static SimpleGraph[] NT_Reduce(SimpleGraph graph)
{
BipartiteGraph BG = new BipartiteGraph(); // right vertices NO add Bound
List<Edge> edge_list = graph.Edges;
for (int i = 0; i < edge_list.Count; i++)
{
Edge e = edge_list[i];
Edge e2 = new Edge(e.from, e.to + Boundary, e.weight, e.edgeStyle);
BG.AddEdge(e2);
}
SimpleGraph mvc = BG.FindOneMinimumVertexCovering();
SimpleGraph V0 = new SimpleGraph();
SimpleGraph V1 = new SimpleGraph();
for (int i = 0; i < graph.Vertices.Count; i++)
{
int vertex = graph.Vertices[i];
if (mvc.VertexIn(vertex) && mvc.VertexIn(vertex + Boundary)) V1.AddVertex(vertex);
if ((!mvc.VertexIn(vertex)) && (!mvc.VertexIn(vertex + Boundary))) V0.AddVertex(vertex);
}
SimpleGraph V12 = SimpleGraphOP.Graph_Vertex_Subtract(graph, V0);
V12 = SimpleGraphOP.Graph_Vertex_Subtract(V12, V1);
V12 = graph.InducedSubgraph(V12.Vertices);
return new SimpleGraph[] { V0, V1 ,V12};
}
public static SimpleGraph Crown_NT_Reduce_All(SimpleGraph graph)
{
SimpleGraph g = graph.Clone();
while (true)
{
int count = g.Vertices.Count;
SimpleGraph[] graphes = NT_Reduce(g);
g = graphes[2];
if (count == g.Vertices.Count) break;
}
return g;
}
public static SimpleGraph Crown_Faisal_Reduce_All(SimpleGraph graph)
{
SimpleGraph g = graph.Clone();
while (true)
{
int count = g.Vertices.Count;
SimpleGraph[] graphes = Find_Crown_Faisal(g);
g = graphes[2];
if (count == g.Vertices.Count) break;
}
return g;
}
public static SimpleGraph[] Find_Crown_Faisal(SimpleGraph graph)
{
SimpleGraph g = graph.Clone();
SimpleGraph match=g.FindOneMaxMatch();
SimpleGraph unmatched = SimpleGraphOP.Graph_Vertex_Subtract(g, match);
SimpleGraph neighbour = SimpleGraphOP.Graph_ReachVerticesByEdge(unmatched.Vertices, g.Edges);
SimpleGraph u = SimpleGraphOP.Graph_Vertex_Union(unmatched, neighbour);
SimpleGraph subgraph = g.InducedSubgraph(u.Vertices);
SimpleGraph match2 = subgraph.FindOneMaxMatch();
SimpleGraph I0 = SimpleGraphOP.Graph_Vertex_Subtract(unmatched, match2); // unmatched.Clone();//
SimpleGraph NI = SimpleGraphOP.Graph_ReachVerticesByEdge(I0.Vertices, g.Edges);
SimpleGraph In = SimpleGraphOP.Graph_ReachVerticesByEdge(NI.Vertices, match2.Edges);
while (true)
{
int count = I0.Vertices.Count;
I0 = SimpleGraphOP.Graph_Vertex_Union(I0, In);
if (count == I0.Vertices.Count) break;
NI = SimpleGraphOP.Graph_ReachVerticesByEdge(I0.Vertices, g.Edges);
In = SimpleGraphOP.Graph_ReachVerticesByEdge(NI.Vertices, match2.Edges);
}
SimpleGraph Left = SimpleGraphOP.Graph_Vertex_Subtract(graph, I0);
Left = SimpleGraphOP.Graph_Vertex_Subtract(Left, NI);
Left = graph.InducedSubgraph(Left.Vertices);
return new SimpleGraph[] { I0, NI, Left };
}
//public static SimpleGraph[] Find_Crown_Faisal_test(SimpleGraph graph)
//{
// SimpleGraph g = graph.Clone();
// SimpleGraph match = g.FindOneMaxMatch();
// SimpleGraph I0 = SimpleGraphOP.Graph_Vertex_Subtract(g, match);
// SimpleGraph NI = SimpleGraphOP.Graph_ReachVerticesByEdge(I0.Vertices, g.Edges);
// SimpleGraph In = SimpleGraphOP.Graph_ReachVerticesByEdge(NI.Vertices, match.Edges);
// while (true)
// {
// int count = I0.Vertices.Count;
// I0 = SimpleGraphOP.Graph_Vertex_Union(I0, In);
// if (count == I0.Vertices.Count) break;
// NI = SimpleGraphOP.Graph_ReachVerticesByEdge(I0.Vertices, g.Edges);
// In = SimpleGraphOP.Graph_ReachVerticesByEdge(NI.Vertices, match.Edges);
// }
// return new SimpleGraph[] { I0, NI };
//}
}
}
算法讨论 加QQ群 8508536 要代码的以及一进来就让别人讲算法或代码的 就不要进来了 本群是讨论群 加入条件是 有一定基础