我有一个任务,我必须计算图形的色彩多项式。根据“基本约简定理”:
计算色彩多项式的递归方法基于边缘收缩:对于一对相邻顶点u和v,通过合并两个顶点并去除它们之间的边缘来获得图形Guv。然后色数多项式满足递推关系:
P(G,x)= P(G - uv,x) - P(Guv,x)
其中u和v是相邻顶点,G - uv是去除了边缘uv的图形。 同样,通过以下方式可以找到色彩多项式: 计算色彩多项式的递归方法基于边缘收缩:对于一对非相邻顶点u和v,通过合并两个顶点并在它们之间添加边缘来获得图形Guv。然后,色多项式满足递归关系
P(G,x)= P(G + uv,x)+ P(Guv,x)
其中u和v是相邻的顶点,G + uv是添加了边uv的图。
确定这个赋值当我们想要根据前面的公式制作空图时,图的边是< =(顶点数)*((顶点数-1)/ 4 )。这是确定是否更有效地转向空图或完整图表的“断点”。
另外,我有一个用于创建多项式的类。所以我不必发布两个类,我将在这里总结一下Polynomial类:
构造: Polynomial() - 创建一个常数多项式P(x)= 1。
多项式(int a) - 创建P(x)= x + a形式的线性多项式。
多项式(int a,int b) - 创建a * x ^ b形式的多项式。
int degree() - 返回多项式的次数。
多项式加(多项式b) - 返回此多项式和b的和,即c = this + b
多项式减(多项式b) - 返回该多项式的差值,即c = this-b
多项式次数(多项式b) - 返回此多项式的乘积和b,返回(此* b)
多项式复合(多项式b) - 返回此多项式和b的复合。返回此(b(x)) - 使用Horner的方法计算。
boolean equals(Polynomial b) - 只要这个多项式和b相同,就返回true。
int evaluate(int x) - 在x处计算此多项式。返回此(x)。
多项式微分() - 返回多项式的导数。
String toString() - 返回此多项式的文本表示。
以下是Graph类。它使用Bag数据结构数组,该数组使用链表实现。因此,例如,与顶点0相邻的所有顶点将位于Bag [0]处的Bag中。我需要帮助做递归部分,它计算色度多项式。我对chromaticPolynomial方法以及mergeVertices方法中的问题有一些评论。我不确定我在这两种方法中的想法是否正确,并希望得到任何人的帮助。提前致谢。
import java.util.Arrays;
public class Graph {
private final int V;
private int E;
private Bag<Integer>[] adj;
/**
* Create an empty graph with V vertices.
*/
public Graph(int V) {
if (V < 0) throw new RuntimeException("Number of vertices must be nonnegative");
this.V = V;
this.E = 0;
adj = (Bag<Integer>[]) new Bag[V];
for (int v = 0; v < V; v++) {
adj[v] = new Bag<Integer>();
}
}
/**
* Create a random graph with V vertices and E edges.
* Expected running time is proportional to V + E.
*/
public Graph(int V, int E) {
this(V);
if (E < 0) throw new RuntimeException("Number of edges must be nonnegative");
for (int i = 0; i < E; i++) {
int v = (int) (Math.random() * V);
int w = (int) (Math.random() * V);
addEdge(v, w);
}
}
/**
* Create a digraph from input stream.
*/
public Graph(In in) {
this(in.readInt());
int E = in.readInt();
for (int i = 0; i < E; i++) {
int v = in.readInt();
int w = in.readInt();
addEdge(v, w);
}
}
/**
* Copy constructor.
*/
public Graph(Graph G) {
this(G.V());
this.E = G.E();
for (int v = 0; v < G.V(); v++) {
// reverse so that adjacency list is in same order as original
Stack<Integer> reverse = new Stack<Integer>();
for (int w : G.adj[v]) {
reverse.push(w);
}
for (int w : reverse) {
adj[v].add(w);
}
}
}
/**
* Return the number of vertices in the graph.
*/
public int V() { return V; }
/**
* Return the number of edges in the graph.
*/
public int E() { return E; }
/**
* Add the edge v-w to graph.
*/
public void addEdge(int v, int w) {
E++;
adj[v].add(w);
adj[w].add(v);
}
/**
* Remove edge from v-w to graph.
*/
public void removeEdge(int v, int w){
E--;
adj[v].remove(w);
adj[w].remove(v);
}
public Polynomial chromaticPolynomial(Graph G){
// null graph is reached, return a polynomial that is G1.minus(G2)
if(G.V() == 0) return new Polynomial(); // how do I create a Chromatic Polynomial when this condition is reached?
// complete graph is reached, return a polynomial that is G1.plus(G2). If the number of vertices in a complete graph is n, then the number of edges is equal to n(n-1)/2.
if(G.E() == ((G.V() - (G.V() - 1))/2)) return new Polynomial(); // how do I create a Chromatic Polynomial when this condtion is reached?
// head toward a null graph.
if(G.E() <= G.V()*(G.V()-1/4)){
/**
for every vertex (u) and every edge (v) from that vertex, create a graph that has an edge removed (G1)
and a graph with merged vertices (G2), then recurse until a null graph is reached.
*/
for(int u = 0; u < G.V(); u++){
for(int v : adj[u]){
Graph G1 = new Graph(G);
Graph G2 = new Graph(G);
G1.removeEdge(u,v);
G2.mergeVertices(u,v);
chromaticPolynomial(G1);
chromaticPolynomial(G2);
// reutrn a polynomial here?
}
}
}
// head towards a complete graph.
else{
/**
for every vertex (u) and every edge (v) from that vertex, create a graph that has an edge added (G1) and
a graph with merged verticies (G2), then recures unitl all these graphs are a complete graph.
*/
for(int u = 0; u < G.V(); u++){
for(int v : adj[u]){
Graph G1 = new Graph(G);
Graph G2 = new Graph(G);
G1.addEdge(u,v);
G2.mergeVertices(u,v);
chromaticPolynomial(G1);
chromaticPolynomial(G2);
// return a polynomial here?
}
}
}
// return nothing. It didn't work.
return null;
}
public void mergeVertices(int vert1, int vert2){
// edge has already been removed between these two.
// just have to renumber the vertices so one is "removed"
/**
does this look correct?
*/
for(int u = 0; u < this.V(); u++){
for(int w: adj[u]){
if(w > vert1 || w > vert2) w--;
if(u > vert1 || u > vert2) u--;
}
}
}
/**
* Return the list of neighbors of vertex v as in Iterable.
*/
public Iterable<Integer> adj(int v) {
return adj[v];
}
/**
* Return a string representation of the graph.
*/
public String toString() {
StringBuilder s = new StringBuilder();
String NEWLINE = System.getProperty("line.separator");
s.append(V + " vertices, " + E + " edges " + NEWLINE);
for (int v = 0; v < V; v++) {
s.append(v + ": ");
for (int w : adj[v]) {
s.append(w + " ");
}
s.append(NEWLINE);
}
return s.toString();
}