Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.example.aziza.tourguide.TSP;
- import android.os.StrictMode;
- import android.util.Log;
- import com.example.aziza.tourguide.Attraction;
- import com.example.aziza.tourguide.DBHelper;
- import org.osmdroid.bonuspack.routing.GraphHopperRoadManager;
- import org.osmdroid.bonuspack.routing.RoadManager;
- import org.osmdroid.util.GeoPoint;
- import org.w3c.dom.Attr;
- import java.sql.Time;
- import java.text.DateFormat;
- import java.text.ParseException;
- import java.text.SimpleDateFormat;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Random;
- import java.util.concurrent.ThreadLocalRandom;
- import java.util.concurrent.TimeUnit;
- /**
- * Created by aziza on 2018-03-01.
- */
- public class TSP{
- GeoPoint startPoint;
- Date currentTime = null;
- Date endTime;
- RoadManager roadManager;
- ArrayList<GeoPoint> bestRoute = new ArrayList<GeoPoint>();
- ArrayList<GeoPoint> visitedPlaces = new ArrayList<GeoPoint>();
- ArrayList<Attraction> passedAttractions = new ArrayList<Attraction>();
- public HashMap<Double, ArrayList<GeoPoint>> possibleRoutes = new HashMap<Double, ArrayList<GeoPoint>>();
- public ArrayList<Double> distanceKeys = new ArrayList<Double>();
- double fastest = Double.MAX_VALUE;
- DBHelper mydb;
- public ArrayList<GeoPoint> findBestRoute(RoadManager roadManager, ArrayList<Attraction> attractions, Attraction start, DBHelper mydb) {
- this.mydb = mydb;
- passedAttractions = attractions;
- this.roadManager = roadManager;
- ArrayList<GeoPoint> waypoints = new ArrayList<GeoPoint>();
- for (int i = 0; i < attractions.size(); i++) {
- GeoPoint point = new GeoPoint(attractions.get(i).latitude, attractions.get(i).longitude);
- waypoints.add(point);
- }
- startPoint = new GeoPoint(start.latitude, start.longitude);
- waypoints.remove(startPoint);
- ArrayList<ArrayList<GeoPoint>> permutations = listPermutations(waypoints);
- for (ArrayList<GeoPoint> al : permutations) {
- al.add(0, startPoint);
- double roadLength = roadManager.getRoad(al).mDuration;
- // double roadLength = ThreadLocalRandom.current().nextInt(0, 10 + 1);
- possibleRoutes.put(roadLength, al);
- distanceKeys.add(roadLength);
- if (roadLength<fastest) {
- fastest = roadLength;
- }
- }
- Collections.sort(distanceKeys);
- return possibleRoutes.get(fastest);
- }
- /* TODO: run that first and tell them if they don't have enough time to visit all attractions
- that is even best case path
- Offer to reconsider points or time, alternatively build a path
- */
- public boolean enoughTime() {
- long minutesAvailable = mydb.timeDifference(mydb.parseTime(mydb.currentTimeTo), mydb.parseTime(mydb.currentTimeFrom), TimeUnit.MINUTES);
- double totalTime = TimeUnit.MINUTES.convert((long)fastest, TimeUnit.MILLISECONDS);;
- for (GeoPoint g : possibleRoutes.get(fastest)) {
- totalTime += Attraction.getAttractionByGeo(passedAttractions, g).time_to_spend;
- }
- if (minutesAvailable > totalTime) {
- return true;
- }
- return false;
- }
- /* TODO: implementation of route/time algorithm
- * grab fastest route and check if opening hours correlate with time available
- * if something is closing soon go to the closest one with least walking time ...
- * ### keep track of visited places ?
- * ### have some sorta table of distance n opening hours correlation?
- *
- * /* attraction start time should be before current time and
- * attraction end time should be after currentTime + travelling time + time at the place
- * * trip end time should be after current time
- * * rework it to be more specific, i.e. if we can make it to the place and
- * * spend at least 20 minutes there give an alert
- *
- * ######### Brain-storming ########
- * Best-case: the fastest tour fits in all criterions, keep running for loop updating current time, output it back
- * Average-case: one attraction is not open at the time of visit, so go the the other one
- * Example: 3 points, so possible routes are abc, acb, optimal is abc, going from a to b and b is not open yet but c is,
- * so go to c first, shift b down the priority queque.
- * Have a subarray of a different permutation array, if it contains all the points we visited before, i.e "a", then grab it and do its points
- * repeat for the next
- * do the same for close hours
- *
- *
- * */
- public void timeRouteAlgorithm() {
- // currentTime = mydb.parseTime(mydb.currentTimeFrom);
- // endTime = mydb.parseTime(mydb.currentTimeTo);
- ArrayList<GeoPoint> fastestRoute = possibleRoutes.get(fastest);
- int keepKeyIndex = 0;
- /*for testing purposes */
- SimpleDateFormat inFormat = new SimpleDateFormat("hh:mmaa");
- try {
- currentTime = inFormat.parse("02:00pm");
- endTime = inFormat.parse("5:01pm");
- } catch (Exception e) {
- e.printStackTrace();
- }
- fastestRoute = new ArrayList<GeoPoint>();
- fastestRoute.add(new GeoPoint(1.0, 1.0));
- fastestRoute.add(new GeoPoint(2.0, 2.0));
- fastestRoute.add(new GeoPoint(3.0, 3.0));
- // fastestRoute.add(new GeoPoint(4.0, 3.0));
- /* create permutation list for test purposes */
- ArrayList<GeoPoint> visitedPlaces = new ArrayList<GeoPoint>();
- ArrayList<GeoPoint> arrayToCopy = new ArrayList<GeoPoint>();
- arrayToCopy.addAll(fastestRoute);
- arrayToCopy.remove(arrayToCopy.get(0));
- ArrayList<ArrayList<GeoPoint>> allPermutations = listPermutations(arrayToCopy);
- distanceKeys.add(2.0);
- distanceKeys.add(3.0);
- allPermutations.get(0).add(0, (new GeoPoint(1.0, 1.0)));
- allPermutations.get(1).add(0, (new GeoPoint(1.0, 1.0)));
- possibleRoutes.put(2.0, allPermutations.get(0));
- possibleRoutes.put(3.0, allPermutations.get(1));
- for (int i=0;i< fastestRoute.size();i++) {
- Date attStartTime = null;
- try {
- if (i == 0) {
- attStartTime = inFormat.parse("01:30pm");
- }
- if (i == 1) {
- attStartTime = inFormat.parse("03:00pm");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- long differenceSeconds = currentTime.getTime() - attStartTime.getTime();
- long differenceMinutes = TimeUnit.MINUTES.convert(differenceSeconds, TimeUnit.MILLISECONDS);
- if (differenceMinutes > 0) {
- long summedTime = 0;
- System.out.println("The place is already open at the time of our visit");
- /*Make sure the place won't close on us */
- if (i > 0) {
- /*Caclucate walking time from previous spot to current */
- summedTime += 15;
- }
- Date attEndTime = null;
- try {
- attEndTime = inFormat.parse("03:25pm");
- } catch (Exception e) {
- e.printStackTrace();
- }
- /* i* 10 is the time we are gonna spend at the place */
- summedTime += TimeUnit.MINUTES.convert(currentTime.getTime(), TimeUnit.MILLISECONDS) + (i * 10 + 5);
- long makeBeforeOver = TimeUnit.MINUTES.convert(attEndTime.getTime(), TimeUnit.MILLISECONDS) - summedTime;
- if (makeBeforeOver > 0) {
- System.out.println("The place is open for the whole duration of the trip ");
- /* now check that we have enought time to finish the visit */
- long haveEnoughTime = TimeUnit.MINUTES.convert(endTime.getTime(), TimeUnit.MILLISECONDS) - summedTime;
- if (haveEnoughTime > 0) {
- System.out.println("We have enough time to finish visiting this place");
- /*update current time */
- currentTime = new Date(TimeUnit.MILLISECONDS.convert(summedTime, TimeUnit.MINUTES));
- visitedPlaces.add(fastestRoute.get(i));
- }
- /* tbh that should be a different case all together but keep it just in case */
- else {
- System.out.println("Unfortunately, we do not have enough time to finish visiting the place ");
- }
- } else {
- System.out.println("The place will close before we can finish our visit");
- }
- } else {
- System.out.println("The place is not yet open at the time of our visit");
- /* so check if we can go to a different place on the list */
- for (int d = 1; d < distanceKeys.size(); i++) {
- System.out.println("Visitied places size is " + visitedPlaces.size());
- List<GeoPoint> sublistOfPoints = possibleRoutes.get(distanceKeys.get(d)).subList(0, (visitedPlaces.size()));
- // for (GeoPoint g : sublistOfPoints) {
- // System.out.println(g);
- // }
- // for (GeoPoint a : visitedPlaces) {
- // System.out.println(a);
- // }
- if (sublistOfPoints.containsAll(visitedPlaces)) {
- // System.out.println("Second point in a sublist is " + possibleRoutes.get(distanceKeys.get(d)).get(1));
- attStartTime = null;
- List<GeoPoint> sublistToKeepGoing = possibleRoutes.get(distanceKeys.get(d)).subList(visitedPlaces.size(), possibleRoutes.get(distanceKeys.get(d)).size()-1);
- for (int q=0;q<sublistToKeepGoing.size();i++) {
- try {
- attStartTime = inFormat.parse("01:40pm");
- } catch (Exception e) {
- e.printStackTrace();
- }
- differenceSeconds = currentTime.getTime() - attStartTime.getTime();
- differenceMinutes = TimeUnit.MINUTES.convert(differenceSeconds, TimeUnit.MILLISECONDS);
- if (differenceMinutes > 0) {
- System.out.println("Keep doing your thing");
- }
- }
- }
- }
- }
- }
- // for (int i=0;i< fastestRoute.size();i++) {
- // Date attStartTime = mydb.parseTime(Attraction.getAttractionByGeo(passedAttractions, fastestRoute.get(i)).from_time_week);
- // long calcDifference = mydb.timeDifference(currentTime, attStartTime, TimeUnit.MINUTES);
- // if (calcDifference > 0) {
- // long summedTime = 0;
- // if (i>1) {
- // ArrayList<GeoPoint> distancebetweenTwo = new ArrayList<GeoPoint>();
- // distancebetweenTwo.add(fastestRoute.get(i));
- // distancebetweenTwo.add(fastestRoute.get(i-1));
- // summedTime += TimeUnit.MINUTES.convert((long) roadManager.getRoad(distancebetweenTwo).mDuration, TimeUnit.MILLISECONDS);
- // }
- // Date attEndTime = mydb.parseTime(Attraction.getAttractionByGeo(passedAttractions, fastestRoute.get(i)).to_time_week);
- // summedTime += TimeUnit.MINUTES.convert(currentTime.getTime(), TimeUnit.MILLISECONDS) + Attraction.getAttractionByGeo(passedAttractions, fastestRoute.get(i)).time_to_spend;
- // long makeBeforeOver = TimeUnit.MINUTES.convert(attEndTime.getTime(), TimeUnit.MILLISECONDS) - summedTime;
- // /*attraction won't close before we get there and spend time in there */
- // if (makeBeforeOver > 0) {
- // // Log.i("TSP", "We know tour is doable");
- // System.out.println("Tour is doable");
- // }
- // }
- }
- public void recursiveTRAlgorithm(List<GeoPoint> points) {
- boolean b = false;
- for (GeoPoint g : points) {
- if (true) {
- }
- else {
- for (int i = 1; i < distanceKeys.size(); i++) {
- recursiveTRAlgorithm(sublistToKeepGoing);
- }
- }
- }
- }
- /*Used for test purposes only */
- public void setUp() {
- ArrayList<GeoPoint> fastestRoute = new ArrayList<GeoPoint>();
- fastestRoute.add(new GeoPoint(1.0, 1.0));
- fastestRoute.add(new GeoPoint(2.0, 2.0));
- fastestRoute.add(new GeoPoint(3.0, 3.0));
- /* create permutation list for test purposes */
- ArrayList<GeoPoint> visitedPlaces = new ArrayList<GeoPoint>();
- ArrayList<GeoPoint> arrayToCopy = new ArrayList<GeoPoint>();
- arrayToCopy.addAll(fastestRoute);
- arrayToCopy.remove(arrayToCopy.get(0));
- ArrayList<ArrayList<GeoPoint>> allPermutations = listPermutations(arrayToCopy);
- distanceKeys.add(2.0);
- distanceKeys.add(3.0);
- allPermutations.get(0).add(0, (new GeoPoint(1.0, 1.0)));
- allPermutations.get(1).add(0, (new GeoPoint(1.0, 1.0)));
- possibleRoutes.put(2.0, allPermutations.get(0));
- possibleRoutes.put(3.0, allPermutations.get(1));
- }
- public ArrayList<ArrayList<GeoPoint>> listPermutations(ArrayList<GeoPoint> list) {
- if (list.size() == 0) {
- ArrayList<ArrayList<GeoPoint>> result = new ArrayList<ArrayList<GeoPoint>>();
- result.add(new ArrayList<GeoPoint>());
- return result;
- }
- ArrayList<ArrayList<GeoPoint>> returnMe = new ArrayList<ArrayList<GeoPoint>>();
- GeoPoint firstElement = list.remove(0);
- ArrayList<ArrayList<GeoPoint>> recursiveReturn = listPermutations(list);
- for (List<GeoPoint> li : recursiveReturn) {
- for (int index = 0; index <= li.size(); index++) {
- ArrayList<GeoPoint> temp = new ArrayList<GeoPoint>(li);
- temp.add(index, firstElement);
- returnMe.add(temp);
- }
- }
- return returnMe;
- }
- }
Add Comment
Please, Sign In to add comment