selection

package amazonOnsite;

import java.util.*;
import java.util.Map.Entry;

import test.Test;
import amazonOnsite.Scheduler2.TimeNode;
import amazonOnsite.Scheduler2.Type;


public class Selection {

    private static final int NUMBER_OF_AREAS = 6;
    
    public static void select(List<ScheduleRequest> scheduleRequests, List<Integer> selectionRequests) {
        List<ScheduleRequest> selected = new ArrayList<>(NUMBER_OF_AREAS);
        List<String> locations = getLocations(scheduleRequests);
        //TODO what to do with empty selected contents
        Map<Integer, List<ScheduleRequest>> candidates = getCandidates(scheduleRequests, selectionRequests);
        //put commercials into lists
        for (Integer request : candidates.keySet()) {
            Map<String, ScheduleRequest> selectedContents = selectContents(getCommercialsByArea(candidates.get(request), locations));
            Test.print(selectedContents);
        }
    }
    
    private static List<String> getLocations(List<ScheduleRequest> scheduleRequests) {
        // TODO
        Set<String> locationSet = new HashSet<>();
        for (ScheduleRequest scheduleRequest : scheduleRequests) {
            if (!locationSet.contains(scheduleRequest.locationId)) {
                locationSet.add(scheduleRequest.locationId);
            }
        }
        List<String> locationList = new ArrayList<>();
        locationList.addAll(locationSet);
        //TODO sort this list by it's frequency
        return locationList;
    }

    private static Map<Integer, List<ScheduleRequest>> getCandidates(List<ScheduleRequest> scheduleRequests, List<Integer> requests) {
        List<TimeNode> timeNodes = getTimeNodes(scheduleRequests);
        Map<Integer, List<ScheduleRequest>> result = new HashMap<Integer, List<ScheduleRequest>>();
        Collections.sort(timeNodes, TimeNode.timeComparator);
        Collections.sort(requests);
        //node Index
        int nodeIndex = 0;
        //request Index
        int reqIndex = 0;
        //scan the requests
        Set<ScheduleRequest> overlappedCommercials = new HashSet<>();
        while (reqIndex < requests.size() && nodeIndex < timeNodes.size()) {
            TimeNode node = timeNodes.get(nodeIndex);
            while (reqIndex < requests.size() && node.getTime() >= requests.get(reqIndex)) {
                List<ScheduleRequest> newCommercials = new ArrayList<>(overlappedCommercials.size());
                newCommercials.addAll(overlappedCommercials);
                result.put(requests.get(reqIndex), newCommercials);
                reqIndex++;
            }
            if (node.getType() == Type.start) {
                overlappedCommercials.add(scheduleRequests.get(node.getIndex()));
            }
            if (node.getType() == Type.end) {
                overlappedCommercials.remove(scheduleRequests.get(node.getIndex()));
            }
            nodeIndex++;
        }
        if (reqIndex != requests.size()) {
            while (reqIndex < requests.size()) {
                result.put(requests.get(reqIndex), new ArrayList<ScheduleRequest>());
            }
        }
        return result;
    }
    
    private static List<TimeNode> getTimeNodes(List<ScheduleRequest> scheduleRequests) {
        List<TimeNode> timeNodes = new ArrayList<TimeNode>(scheduleRequests.size() * 2);
        for (int i = 0; i < scheduleRequests.size(); i++) {
            timeNodes.addAll(TimeNode.constructNodes(scheduleRequests.get(i), i));
        }
        return timeNodes;
    }
    
    
    private static Map<String, List<ScheduleRequest>> getCommercialsByArea(List<ScheduleRequest> scheduleRequests, List<String> locations) {
        Map<String, List<ScheduleRequest>> commercialsByArea = new HashMap<>();
        for (ScheduleRequest scheduleRequest : scheduleRequests) {
            if (!commercialsByArea.containsKey(scheduleRequest.locationId)) {
                commercialsByArea.put(scheduleRequest.locationId, new ArrayList<ScheduleRequest>());
            }
            commercialsByArea.get(scheduleRequest.locationId).add(scheduleRequest);
        }
        for (String location : locations) {
            if (!commercialsByArea.containsKey(location)) {
                //TODO sort by value
                //TODO deal with empty list
                commercialsByArea.put(location, new ArrayList<ScheduleRequest>());
            }
            commercialsByArea.get(location).add(new ScheduleRequest(location, location, 0, 0, 0));
        }
        return commercialsByArea;
    }
    
    private static Map<String, ScheduleRequest> selectContents(Map<String, List<ScheduleRequest>> candidates) {
        //TODO edge cases??
        currentMaxValue = Integer.MIN_VALUE;
        currentMaxSelected = new ArrayList<ScheduleRequest>(candidates.keySet().size());
        List<String> locations = new ArrayList<>(candidates.keySet().size());
        locations.addAll(candidates.keySet());
        helper(new ArrayList<ScheduleRequest>(candidates.keySet().size()), candidates, 0, locations);
        Map<String, ScheduleRequest> result = new HashMap<>();
        for (int i = 0; i < locations.size(); i++) {
            result.put(locations.get(i), currentMaxSelected.get(i));
        }
        return result;
    }
    
    private static int currentMaxValue = 0;
    private static List<ScheduleRequest> currentMaxSelected = null;
    
    /*
     * This function is for...
     * For example
     * 1 c1 c3
     * 2 c2 c4
     * c1
     * c1 c2
     * c1 c4
     * c3
     * c3 c2
     * c3 c4
     * 
     * List<ScheduleRequest> selected : dddddddd
     * ......
     * 
     * 
     */
    
    
    private static void helper(
        List<ScheduleRequest> selected, 
        Map<String, List<ScheduleRequest>> candidates, 
        int indexOfLevel, 
        List<String> locations) {
        
        if (selected.size() == locations.size()) {
            int currentValue = sumValue(selected);
            if (currentValue > currentMaxValue) {
                currentMaxSelected = new ArrayList<>(selected);
                currentMaxValue = currentValue;
            }
            return;
        }
        for (ScheduleRequest scheduleRequest : candidates.get(locations.get(indexOfLevel))) {
            if (selected.contains(scheduleRequest)) {
                continue;
            }
            selected.add(scheduleRequest);
            helper(selected, candidates, indexOfLevel++, locations);
            selected.remove(selected.size() - 1);
        }
    }
    
    private static int sumValue(List<ScheduleRequest> scheduleRequests) {
        // TODO
        return 0;
    }
    
    
}

 

posted @ 2016-02-05 23:23  王大匹夫  阅读(151)  评论(0)    收藏  举报