/app/controllers/GraphAlgorithmController.java
https://gitlab.com/flytosky/climate-service-backend · Java · 222 lines · 192 code · 27 blank · 3 comment · 36 complexity · 3e7ede5455c9fd6dc5d099dd11b57244 MD5 · raw file
- package controllers;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import javax.inject.Inject;
- import javax.inject.Named;
- import javax.inject.Singleton;
- import org.jgrapht.GraphPath;
- import org.jgrapht.WeightedGraph;
- import org.jgrapht.alg.DijkstraShortestPath;
- import org.jgrapht.alg.KShortestPaths;
- import org.jgrapht.graph.DefaultWeightedEdge;
- import org.jgrapht.graph.SimpleWeightedGraph;
- import models.ClimateService;
- import models.ClimateServiceRepository;
- import models.Dataset;
- import models.DatasetAndUser;
- import models.DatasetAndUserRepository;
- import models.DatasetRepository;
- import models.ServiceAndDataset;
- import models.ServiceAndDatasetRepository;
- import models.ServiceAndUser;
- import models.ServiceAndUserRepository;
- import models.User;
- import models.UserRepository;
- import play.mvc.Controller;
- import play.mvc.Result;
- import util.HashMapUtil;
- import util.Matrix;
- import com.fasterxml.jackson.databind.JsonNode;
- import com.google.gson.Gson;
- @Named
- @Singleton
- public class GraphAlgorithmController extends Controller {
- private final DatasetAndUserRepository datasetAndUserRepository;
- private final ServiceAndUserRepository serviceAndUserRepository;
- private final ServiceAndDatasetRepository serviceAndDatasetRepository;
- private final UserRepository userRepository;
- private final DatasetRepository datasetRepository;
- private final ClimateServiceRepository serviceRepository;
- @Inject
- public GraphAlgorithmController(
- DatasetAndUserRepository datasetAndUserRepository,
- ServiceAndUserRepository serviceAndUserRepository,
- ServiceAndDatasetRepository serviceAndDatasetRepository,
- UserRepository userRepository, DatasetRepository datasetRepository,
- ClimateServiceRepository serviceRepository) {
- this.datasetAndUserRepository = datasetAndUserRepository;
- this.serviceAndUserRepository = serviceAndUserRepository;
- this.serviceAndDatasetRepository = serviceAndDatasetRepository;
- this.userRepository = userRepository;
- this.datasetRepository = datasetRepository;
- this.serviceRepository = serviceRepository;
- }
-
- public Result getShortestPath(int source, int target, String format) {
-
- try {
- Iterable<DatasetAndUser> userDatasets = datasetAndUserRepository
- .findAll();
- if (userDatasets == null) {
- System.out.println("User and Dataset: cannot be found!");
- return notFound("User and Dataset: cannot be found!");
- }
- List<Map<String, Object>> nodes = new ArrayList<Map<String, Object>>();
- List<Map<String, Object>> rels = new ArrayList<Map<String, Object>>();
- WeightedGraph<Integer, DefaultWeightedEdge> graph = createGraph(userDatasets, nodes, rels);
- Map<String, Object> map = new HashMap<>();
-
- List<Map<String, Object>> node = new ArrayList<Map<String, Object>>();
- List<Map<String, Object>> rel = new ArrayList<Map<String, Object>>();
-
- List<DefaultWeightedEdge> path =
- DijkstraShortestPath.findPathBetween(graph, source, target);
- for(DefaultWeightedEdge p : path) {
- int v1 = graph.getEdgeSource(p);
- int v2 = graph.getEdgeTarget(p);
- if(!node.contains(nodes.get(v1-1)))
- node.add(nodes.get(v1-1));
- if(!node.contains(nodes.get(v2-1)))
- node.add(nodes.get(v2-1));
- for(Map<String, Object> one : rels) {
- if((int)one.get("from") == v1 && (int)one.get("to") == v2) {
- rel.add(one);
- }
- }
- }
-
- map = HashMapUtil.map("nodes", node, "edges", rel);
-
- String result = new String();
- if (format.equals("json")) {
- result = new Gson().toJson(map);
- }
- return ok(result);
- } catch (Exception e) {
- return badRequest(e.getMessage());
- }
- }
-
- public Result getKShortestPath(int source, int target, int k, String format) {
-
- try {
- Iterable<DatasetAndUser> userDatasets = datasetAndUserRepository
- .findAll();
- if (userDatasets == null) {
- System.out.println("User and Dataset: cannot be found!");
- return notFound("User and Dataset: cannot be found!");
- }
- List<Map<String, Object>> nodes = new ArrayList<Map<String, Object>>();
- List<Map<String, Object>> rels = new ArrayList<Map<String, Object>>();
- WeightedGraph<Integer, DefaultWeightedEdge> graph = createGraph(userDatasets, nodes, rels);
- // return this map list
- List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
- KShortestPaths kPaths = new KShortestPaths(graph, source, k);
- List<GraphPath> paths = kPaths.getPaths(target);
-
- for(GraphPath p : paths) {
- List<Map<String, Object>> node = new ArrayList<Map<String, Object>>();
- List<Map<String, Object>> rel = new ArrayList<Map<String, Object>>();
- for (Object edge : p.getEdgeList()) {
- int v1 = graph.getEdgeSource((DefaultWeightedEdge)edge);
- int v2 = graph.getEdgeTarget((DefaultWeightedEdge)edge);
- if(!node.contains(nodes.get(v1-1)))
- node.add(nodes.get(v1-1));
- if(!node.contains(nodes.get(v2-1)))
- node.add(nodes.get(v2-1));
- for (Map<String, Object> one : rels) {
- if((int)one.get("from") == v1 && (int)one.get("to") == v2) {
- rel.add(one);
- }
- }
- }
- mapList.add(HashMapUtil.map("nodes", node, "edges", rel));
- }
-
- String result = new String();
- if (format.equals("json")) {
- result = new Gson().toJson(mapList);
- }
- return ok(result);
- } catch (Exception e) {
- return badRequest(e.getMessage());
- }
- }
-
- public WeightedGraph<Integer, DefaultWeightedEdge> createGraph(Iterable<DatasetAndUser> userDatasets,
- List<Map<String, Object>> nodes, List<Map<String, Object>> rels) {
- WeightedGraph<Integer, DefaultWeightedEdge> g =
- new SimpleWeightedGraph<Integer, DefaultWeightedEdge>(DefaultWeightedEdge.class);
- int i = 1;
- long edgeId = 1;
- for (DatasetAndUser userDataset : userDatasets) {
- int source = 0;
- int target = 0;
- // Check whether the current user has already existed
- for (int j = 0; j < nodes.size(); j++) {
- if (nodes.get(j).get("group").equals("user")
- && (long) nodes.get(j).get("userId") == userDataset
- .getUser().getId()) {
- source = (int) nodes.get(j).get("id");
- nodes.get(j).put("value", (int)nodes.get(j).get("value") + 1);
- break;
- }
- }
- if (source == 0) {
- String realName = userDataset.getUser().getFirstName() + " "
- + userDataset.getUser().getLastName();
- nodes.add(HashMapUtil.map7("id", i, "title", realName, "label", userDataset
- .getUser().getUserName(), "cluster", "1", "value", 1,
- "group", "user", "userId", userDataset.getUser()
- .getId()));
- source = i;
- g.addVertex(source);
- i++;
- }
- // Check whether the current dataset has already existed
- for (int j = 0; j < nodes.size(); j++) {
- if (nodes.get(j).get("group").equals("dataset")
- && (long) nodes.get(j).get("datasetId") == userDataset
- .getDataset().getId()) {
- target = (int) nodes.get(j).get("id");
- nodes.get(j).put("value", (int)nodes.get(j).get("value") + 1);
- break;
- }
- }
- if (target == 0) {
- nodes.add(HashMapUtil.map7("id", i, "title", userDataset.getDataset()
- .getName(), "label",
- userDataset.getDataset().getName(), "cluster", "2",
- "value", 25, "group", "dataset", "datasetId",
- userDataset.getDataset().getId()));
- target = i;
- g.addVertex(target);
- i++;
- }
- rels.add(HashMapUtil.map5("from", source, "to", target, "title", "USE",
- "id", edgeId, "weight", userDataset.getCount()));
- g.addEdge(source, target);
- g.setEdgeWeight(g.getEdge(source, target), userDataset.getCount());
- edgeId++;
- }
- return g;
- }
- }