com.github.andyshao.arithmetic.GraphAlg Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Gear Show documentation
Show all versions of Gear Show documentation
Enhance and formating the coding of JDK
The newest version!
package com.github.andyshao.arithmetic;
import com.github.andyshao.data.structure.CycleLinkedElmt;
import com.github.andyshao.data.structure.Graph;
import com.github.andyshao.data.structure.Graph.AdjList;
import com.github.andyshao.data.structure.Graph.VertexColor;
import com.github.andyshao.data.structure.SingleLinked;
import com.github.andyshao.data.structure.Stack;
import java.util.*;
/**
*
* Title:
* Descript:图算法
* Copyright: Copryright(c) Mar 15, 2015
* Encoding:UNIX UTF-8
*
* @author Andy.Shao
*
*/
public final class GraphAlg {
/**
* MstVertex
* @param data type
*/
public static class MstVertex {
/**
* set untoward endge
* @param graph {@link Graph}
* @param one {@link MstVertex}
* @param two {@link MstVertex}
* @param weight weight
* @param data type
*/
public static final void setUntowardEdge(Graph> graph , MstVertex one , MstVertex two , double weight) {
Graph.addUntowardEdge(graph , one , two);
MstVertex.setUntowardWeight(one , two , weight);
}
/**
* set untoward weight
* @param one {@link MstVertex}
* @param two {@link MstVertex}
* @param weight weight
* @param data type
*/
public static final void setUntowardWeight(MstVertex one , MstVertex two , double weight) {
one.weight.put(two , weight);
two.weight.put(one , weight);
}
/**color*/
public VertexColor color;
/**data*/
public DATA data;
/**key*/
public double key;
/**parent {@link MstVertex}*/
public MstVertex parent;
/**weight map*/
public final Map , Double> weight = new HashMap<>();
}
/**
* Path vertex
* @param data type
*/
public static class PathVertex {
/**
* set double edge
* @param graph {@link Graph}
* @param one {@link PathVertex}
* @param two {@link PathVertex}
* @param one2two one to two
* @param two2one two to one
* @param data type
*/
public static final void setDoubleEdge(Graph> graph , PathVertex one , PathVertex two , double one2two , double two2one) {
Graph.addUntowardEdge(graph , one , two);
one.weight.put(two , one2two);
two.weight.put(one , two2one);
}
/**
* set edge
* @param graph {@link Graph}
* @param start start point
* @param end end point
* @param weight weight
* @param data type
*/
public static final void setEdge(Graph> graph , PathVertex start , PathVertex end , double weight) {
graph.insEdge(start , end);
start.weight.put(end , weight);
}
/**color*/
public VertexColor color;
/**double*/
public double d;
/**data*/
public DATA data;
/**parent vertex*/
public PathVertex parent;
/**weight map*/
public final Map , Double> weight = new HashMap<>();
}
/**
* Tsp vertex
* @param data type
*/
public static class TspVertex {
/**color*/
public VertexColor color;
/**data*/
public DATA data;
/**x*/
public double x , /**y*/y;
}
/**
* (最短路径)
* all of the answer will store in 'result'. the parent note of the start
* note of 'result''s is null. the others' parent note is the previous
* position in 'result'.
*
* @param graph {@link Graph} is a toward graph
* @param start the start vertex
* @param result the collection which should return to.
* @param comparator {@link Comparator}
* @param data type
* @return result
*/
static final Collection>
findShortest(Graph> graph , PathVertex start , final Collection> result , Comparator> comparator) {
//Initialize all of the vertices in the graph.
{
boolean found = false;
for (AdjList> element : graph.adjlists()) {
PathVertex pth_vertex = element.vertex();
if (comparator.compare(pth_vertex , start) == 0) {
//Initialize the start vertex.
pth_vertex.color = VertexColor.WHITE;
pth_vertex.d = 0;
pth_vertex.parent = null;
found = true;
} else {
//Initialize vertices other than the start vertex.
pth_vertex.color = VertexColor.WHITE;
pth_vertex.d = Double.MAX_VALUE;
pth_vertex.parent = null;
}
}
if (!found) throw new GraphAlgException("The start point doesn't exist in graph!");
}
for (int i = 0 ; i < graph.vcount() ; i++) {
AdjList> adjlist = null;
//Select the white vertex with the smallest shortest-path estimate.
{
double minimum = Double.MAX_VALUE;
for (AdjList> element : graph.adjlists()) {
PathVertex pth_vertex = element.vertex();
if (pth_vertex.color == VertexColor.WHITE && pth_vertex.d < minimum) {
minimum = pth_vertex.d;
adjlist = element;
}
}
}
//Color the selected vertex black.
adjlist.vertex().color = VertexColor.BLACK;
result.add(adjlist.vertex());
//Traverse each vertex adjacent to the selected vertex.
for (PathVertex adj_vertex : adjlist.adjacent()) {
PathVertex u = adjlist.vertex();
double weight1 = adjlist.vertex().weight.get(adj_vertex);
//Relax an edge between two vertices u and v.
if (adj_vertex.d > u.d + weight1) {
adj_vertex.d = u.d + weight1;
adj_vertex.parent = u;
}
}
}
return result;
}
/**
* (最小生成树)
* all the answers will store in the 'result'.In the 'result', the root note
* of 'result' is the 'start' which has a parent note is null.the
* other notes' parent is the previous note of 'result'.
*
* @param graph {@link Graph} is a untoward graph
* @param start start vertex
* @param result the structure of mst vertex
* @param comparator {@link Comparator}
* @param data type
* @return the 'result'
*/
public static final Collection>
mst(Graph> graph , MstVertex start , final Collection> result , Comparator> comparator) {
//Initialize all of the vertices in the graph.
{
boolean found = false;
for (AdjList> element : graph.adjlists()) {
MstVertex mst_vertex = element.vertex();
if (comparator.compare(mst_vertex , start) == 0) {
//Initialize the start vertex.
mst_vertex.color = VertexColor.WHITE;
mst_vertex.key = 0;
mst_vertex.parent = null;
found = true;
} else {
//Initialize vertices other than the start vertex.
mst_vertex.color = VertexColor.WHITE;
mst_vertex.key = Double.MAX_VALUE;
mst_vertex.parent = null;
}
}
//Return if the start vertex was not found.
if (!found) throw new GraphAlgException("Can't find out the " + start);
}
//Use prim's algorithm to compute a minimum spanning tree.
for (int i = 0 ; i < graph.vcount() ; i++) {
AdjList> adjlist = null;
//Select the white vertex with the smallest key value.
double minimum = Double.MAX_VALUE;
for (AdjList> element : graph.adjlists()) {
MstVertex mst_vertex = element.vertex();
if (mst_vertex.color == VertexColor.WHITE && mst_vertex.key < minimum) {
minimum = mst_vertex.key;
adjlist = element;
}
}
//Color the selected vertex black.
adjlist.vertex().color = VertexColor.BLACK;
result.add(adjlist.vertex());
//Traverse each vertex adjacent to the selected vertex.
for (MstVertex adj_vertex : adjlist.adjacent())
if (adj_vertex.color == VertexColor.WHITE && adj_vertex.weight.get(adjlist.vertex()) < adj_vertex.key) {
adj_vertex.key = adj_vertex.weight.get(adjlist.vertex());
adj_vertex.parent = adjlist.vertex();
}
}
return result;
}
/**
* (最短路径)
* all of the answer will store in 'result'. the parent note of the start
* note of 'result''s is null. the others' parent note is the previous
* position in 'result'.
*
* @param graph {@link Graph} is a toward graph
* @param start the start vertex
* @param ends the end lists
* @param result the answer which should be returned
* @param comparator {@link Comparator}
* @param data type
* @return {@link Map}
*/
public static final Map , Collection>> shortest(
Graph> graph , PathVertex start , Collection> ends , final Map , Collection>> result ,
Comparator> comparator) {
final List> answer = new ArrayList<>();
GraphAlg.findShortest(graph , start , answer , comparator);
for (PathVertex end : ends) {
final Stack> temp = Stack.defaultStack(SingleLinked.defaultSingleLinked((data) -> CycleLinkedElmt.defaultElmt(data)));
temp.add(end);
{
PathVertex target = end;
int index = answer.size() - 1;
{
boolean found = false;
while (index >= 0)
if (comparator.compare(answer.get(index--) , target) == 0) {
found = true;
break;
}
if (!found) throw new GraphAlgException();
}
while (index >= 0) {
PathVertex parent = answer.get(index--);
VERTEX: for (PathVertex vertex : parent.weight.keySet())
if (comparator.compare(vertex , target) == 0) {
temp.add(parent);
target = parent;
break VERTEX;
}
}
}
result.put(end , temp);
}
return result;
}
/**
* (旅行商问题)
* Can't find out the best solution of these questions
*
* @param vertices vertex
* @param start start position
* @param result result lists
* @param comparator {@link Comparator}
* @param data type
* @return result
*/
public static final Collection>
tsp(Collection> vertices , TspVertex start , final Collection> result , Comparator> comparator) {
TspVertex tsp_start = null;
double x = 0 , y = 0;
{
boolean found = false;
for (TspVertex tsp_vertex : vertices)
if (comparator.compare(tsp_vertex , start) == 0) {
result.add(tsp_vertex);
//Save the start vertex and its coordinates.
tsp_start = tsp_vertex;
x = tsp_vertex.x;
y = tsp_vertex.y;
//Color the start vertex black.
tsp_vertex.color = VertexColor.BLACK;
found = true;
} else tsp_vertex.color = VertexColor.WHITE;//Color all other vertices white.
if (!found) throw new GraphAlgException();
}
for (int i = 0 ; i < vertices.size() - 1 ; i++) {
//Select the white vertex closest to the previous vertex in the tour.
double minimum = Double.MAX_VALUE;
TspVertex selection = null;
for (TspVertex tsp_vertex : vertices)
if (tsp_vertex.color == VertexColor.WHITE) {
double distance = Math.sqrt(Math.pow(tsp_vertex.x - x , 2.0) + Math.pow(tsp_vertex.y - y , 2.0));
if (distance < minimum) {
minimum = distance;
selection = tsp_vertex;
}
}
//Save the coordinates of the selected vertex.
x = selection.x;
y = selection.y;
//Color the selected vertex black.
selection.color = VertexColor.BLACK;
//Insert the selected vertex into the tour.
result.add(selection);
}
//Insert the start vertex again to complete the tour.
result.add(tsp_start);
return result;
}
private GraphAlg() {
throw new AssertionError("No " + GraphAlg.class + " for you!");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy