All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.andyshao.arithmetic.GraphAlg Maven / Gradle / Ivy

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