Commit 4deaed8c authored by winterbloom's avatar winterbloom
Browse files

Reorganizes NodeGraph

parent 327a4559
1 merge request!1Updates
Pipeline #78059 canceled with stage
Showing with 95 additions and 34 deletions
+95 -34
...@@ -8,19 +8,29 @@ import edu.caltech.cs2.interfaces.ISet; ...@@ -8,19 +8,29 @@ import edu.caltech.cs2.interfaces.ISet;
public class NodeGraph { public class NodeGraph {
private final Node[] nodes;
/**
* Represents one node in the graph
*/
private static class Node { private static class Node {
public int name; public int name;
public int color; public int color;
public ISet<Node> neighbors; public ISet<Node> neighbors; // The names of this node's neighbors
public ISet<Integer> neighborColors; public ISet<Integer> neighborColors; // The colors which its neighbors use
public ISet<Integer> neighborsColored; public ISet<Integer> neighborsUncolored; // The names of its neighbors which aren't yet colored
public Node(int name, int color) { public Node(int name, int color) {
this.name = name; this.name = name;
this.color = color; this.color = color;
this.neighbors = new ChainingHashSet<>(); this.neighbors = new ChainingHashSet<>();
this.neighborColors = new ChainingHashSet<>(); this.neighborColors = new ChainingHashSet<>();
this.neighborsColored = new ChainingHashSet<>(); this.neighborsUncolored = new ChainingHashSet<>();
}
public void addNeighbor(Node neighbor) {
this.neighbors.add(neighbor);
this.neighborsUncolored.add(neighbor.name);
} }
@Override @Override
...@@ -41,8 +51,12 @@ public class NodeGraph { ...@@ -41,8 +51,12 @@ public class NodeGraph {
return this.name; return this.name;
} }
} }
private final Node[] nodes;
/**
* Creates a new graph
* @param n The (fixed) number of vertices for the graph to have. They will be
* "named" with the numbers 0 through n.
*/
public NodeGraph(int n) { public NodeGraph(int n) {
this.nodes = new Node[n]; this.nodes = new Node[n];
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
...@@ -50,70 +64,101 @@ public class NodeGraph { ...@@ -50,70 +64,101 @@ public class NodeGraph {
} }
} }
public int numberOfVertices() { /**
return this.nodes.length; * Whether or not a vertex is colored yet
} * @param n The name of the vertex
* @return True if the vertex has a color, false if it doesn't yet
*/
public boolean isColored(int n) { public boolean isColored(int n) {
return this.nodes[n].color != 0; return this.nodes[n].color != 0;
} }
/**
* Gets the color of a given vertex
* @param n The name of the vertex
* @return The vertex's color, or 0 if it doesn't have one yet
*/
public int getColor(int n) { public int getColor(int n) {
return this.nodes[n].color; return this.nodes[n].color;
} }
/**
* Sets the color of a vertex
* @param n The name of the vertex to set the color of
* @param color The color to set it to
*/
public void setColor(int n, int color) { public void setColor(int n, int color) {
if (this.isColored(n)) { if (this.isColored(n)) {
throw new IllegalArgumentException("" + n + " already has a color."); throw new IllegalArgumentException(n + " already has a color.");
} }
if (color <= 0) { if (color <= 0) {
throw new IllegalArgumentException("only numbers >= 1 are valid colors"); throw new IllegalArgumentException("Only numbers >= 1 are valid colors, not " + color);
} }
checkColoringIsValid(n, color); checkColoringIsValid(n, color);
this.nodes[n].color = color; this.nodes[n].color = color;
for (Node m : this.nodes[n].neighbors) { for (Node m : this.nodes[n].neighbors) {
m.neighborColors.add(color); m.neighborColors.add(color);
m.neighborsColored.add(n); m.neighborsUncolored.remove(n);
} }
} }
private void checkColoringIsValid(int n, int color) { /**
ISet<Integer> adjs = this.neighbors(n); * Gets a vertex's neighbors
for (int v : adjs) { * @param n The name of the vertex
if (this.nodes[v].color == color) { * @return A list of the names of that vertex's neighbors
throw new IllegalColoringException(); */
} public ISet<Integer> neighbors(int n) {
} ISet<Integer> adj = new ChainingHashSet<>();
ISet<Node> neighbors = this.nodes[n].neighbors;
for (Node neigh : neighbors) {
adj.add(neigh.name);
} }
return adj;
public void addEdge(int n, int m) {
this.nodes[n].neighbors.add(this.nodes[m]);
this.nodes[m].neighbors.add(this.nodes[n]);
} }
/**
* Gets the degree of saturation of a given vertex
* (ie: the number of unique colors across its neighbors)
* @param n The name of the vertex
* @return Its degree of saturation
*/
public int degreeOfSaturation(int n) { public int degreeOfSaturation(int n) {
return this.nodes[n].neighborColors.size(); return this.nodes[n].neighborColors.size();
} }
public int numNeighbors(int n) { /**
return this.nodes[n].neighbors.size() - this.nodes[n].neighborsColored.size(); * Gets the number of uncolored neighbors of a given vertex
* @param n The name of the vertex
* @return How many of its neighbors don't yet have colors
*/
public int numUncoloredNeighbors(int n) {
return this.nodes[n].neighborsUncolored.size();
} }
/**
* Gets the (fixed) number of vertices in the graph
* @return The total number of vertices
*/
public int numVertices() { public int numVertices() {
return this.nodes.length; return this.nodes.length;
} }
public ISet<Integer> neighbors(int n) { /**
ISet<Integer> adj = new ChainingHashSet<>(); * Adds an edge between two vertices
* @param n The name of one vertex
ISet<Node> neighbors = this.nodes[n].neighbors; * @param m The name of the other vertex
for (Node neigh : neighbors) { */
adj.add(neigh.name); public void addEdge(int n, int m) {
} this.nodes[n].addNeighbor(this.nodes[m]);
this.nodes[m].addNeighbor(this.nodes[n]);
return adj;
} }
/**
* Gets the current coloring of the graph
* @return A map between each vertex's name and its color
*/
public IDictionary<Integer, Integer> getColoring() { public IDictionary<Integer, Integer> getColoring() {
IDictionary<Integer, Integer> coloring = new ChainingHashDictionary<>(MoveToFrontDictionary::new); IDictionary<Integer, Integer> coloring = new ChainingHashDictionary<>(MoveToFrontDictionary::new);
for (Node n : this.nodes) { for (Node n : this.nodes) {
...@@ -122,6 +167,22 @@ public class NodeGraph { ...@@ -122,6 +167,22 @@ public class NodeGraph {
return coloring; return coloring;
} }
/**
* Checks if a vertex can validly be colored with a given color
* @param n The name of the vertex
* @param color The color for it to have
* @throws IllegalColoringException If this would cause an illegal coloring
*/
private void checkColoringIsValid(int n, int color) {
ISet<Integer> adjs = this.neighbors(n);
for (int v : adjs) {
if (this.nodes[v].color == color) {
throw new IllegalColoringException();
}
}
}
@Override @Override
public String toString() { public String toString() {
StringBuilder result = new StringBuilder("{"); StringBuilder result = new StringBuilder("{");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment