Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何按最近值对列表排序_Java_Android_Sorting - Fatal编程技术网

Java 如何按最近值对列表排序

Java 如何按最近值对列表排序,java,android,sorting,Java,Android,Sorting,因此,我有一个小列表,如下所示,代表仓库位置: 30 09 05 30 04 05 30 02 01 31 07 05 31 07 04 31 03 05 31 03 06 31 09 05 31 02 05 第一列表示位置行,第二列表示位置高度,第三列表示位置位置(向前) 我需要计算叉车操作员根据不同位置检索不同物品的最佳路径(行、位置、高度) 为此,我使用Collection.sort首先按行对列表进行排序,然后按位置(向前),最后按高度对列表进行排序 行是成对分组的,因为操

因此,我有一个小列表,如下所示,代表仓库位置:

30 09 05
30 04 05
30 02 01 
31 07 05 
31 07 04 
31 03 05 
31 03 06 
31 09 05 
31 02 05 
第一列表示位置行,第二列表示位置高度,第三列表示位置位置(向前)

我需要计算叉车操作员根据不同位置检索不同物品的最佳路径(行、位置、高度)

为此,我使用Collection.sort首先按行对列表进行排序,然后按位置(向前),最后按高度对列表进行排序

行是成对分组的,因为操作员可以在不移动叉车位置和高度的情况下从偶数行(操作员左)和奇数行(操作员右)检索项目

我就快到了,我只需要一只手,当pos向前移动时,我需要保持相同的高度并获得最近的高度,而不是从底部开始,这会使操作员失去上下移动的时间

代码如下:

Collections.sort(unoptimizedLocations, new Comparator<ItemOrderLocation>() {
    @Override
    public int compare(ItemOrderLocation item1, ItemOrderLocation item2) {

        int rowCmp = item1.row.compareTo(item2.row);
        int heightCmp = item1.height.compareTo(item2.height);
        int posCmp = item1.pos.compareTo(item2.pos);

        int item1Row = Integer.parseInt(item1.row);
        int item2Row = Integer.parseInt(item2.row);

        boolean onForkLiftPath = false;

        if (item1Row == (item2Row + 1) && (item2Row % 2 == 0)) {
            onForkLiftPath = true;
        }

        if (!onForkLiftPath && rowCmp != 0) {
            //Two differents rows which are not on Fork Lift Path
            return rowCmp;
        }

        //If are on forklift path we compare the position
        if (posCmp != 0) {
            return posCmp;
        }

        //Lastly if row is on forklift path and we are on same position we need to sort by nearest height
        return heightCmp;
    }
});
public class ForkLiftOperator {

public static void main(String[] args) {
    new ForkLiftOperator().start();
}

private void start() {

    List<Location> locations = new ArrayList<Location>();
    locations.add(new Location(30, 9, 5));
    locations.add(new Location(30, 4, 5));
    locations.add(new Location(30, 2, 1));
    locations.add(new Location(31, 7, 5));
    locations.add(new Location(31, 7, 4));
    locations.add(new Location(31, 3, 5));
    locations.add(new Location(31, 3, 6));
    locations.add(new Location(31, 9, 5));
    locations.add(new Location(31, 2, 5));
    locations.add(new Location(32, 2, 5));  // Extra to simulate additional row/pair

    List<Location> solution = solve(locations);
    System.out.println(solution);
}


private List<Location> solve(List<Location> locations) {

    List<Location> shortestPath = new ArrayList<Location>();
    int activeRow, activePosition, activeHeight;
    while ((activeRow = getNextRow(locations)) != 0) {
        System.out.println("Working on row="+activeRow);
        List<Location> activeLocations = getLocationsByRowPair(activeRow, locations);
        activePosition = 0;
        activeHeight = 0;
        while ((activePosition = getNextPos(activePosition, activeLocations)) != 0) {
            System.out.println("Working on pos="+activePosition);
            List<Location> activePositionLocations = getLocationsForRowAndPosition(activeRow, activePosition, activeLocations);
            shortestPath.addAll(minimizeHeight(activeHeight, activePositionLocations));
            activeHeight = shortestPath.get(shortestPath.size()-1).height;
        }
    }


    return shortestPath;
}

enum Direction { UP, DOWN }
/**
 * For the given locations (which are guaranteed to be at the same row/position), minimize the total height change
 * @param activePositionLocations The locations at this row/pair and location (they will only differ in height)
 * @return The order will minimize the height change
 */
private List<Location> minimizeHeight(int currentHeight, List<Location> activePositionLocations) {
    List<Location> optimizedHeightLocations = new ArrayList<Location>();
    System.out.println("Processing locations="+activePositionLocations);
    int minHeight = activePositionLocations.stream().mapToInt(location -> location.height).min().getAsInt();
    int maxHeight = activePositionLocations.stream().mapToInt(location -> location.height).max().getAsInt();
    /*
     * There are only two options to minimize (if the current height falls between min and max):
     * 1)  Travel down then up
     * 2)  Travel up then down
     */
    // First determine the first direction to go
    Direction direction;
    if (currentHeight == minHeight)
        direction = Direction.UP;
    else if (currentHeight == maxHeight)
        direction = Direction.DOWN;
    else {
        int distanceUp = maxHeight-currentHeight;
        int distanceDown = currentHeight-minHeight;
        direction = distanceUp < distanceDown ? Direction.UP : Direction.DOWN;
    }
    // Now travel in that direction (must sort the correct way first
    List<Location> sortedAscending = activePositionLocations.stream().sorted((l1, l2) -> Integer.compare(l1.height, l2.height)).collect(Collectors.toList());
    List<Location> sortedDescending = activePositionLocations.stream().sorted((l1, l2) -> Integer.compare(l2.height, l1.height)).collect(Collectors.toList());
    if (direction == Direction.UP) {
        optimizedHeightLocations.addAll(sortedAscending.stream().filter(location -> location.height >= currentHeight).collect(Collectors.toList()));
        optimizedHeightLocations.addAll(sortedDescending.stream().filter(location -> location.height < currentHeight).collect(Collectors.toList()));
    } else {    // Direction = DOWN
        optimizedHeightLocations.addAll(sortedDescending.stream().filter(location -> location.height <= currentHeight).collect(Collectors.toList()));
        optimizedHeightLocations.addAll(sortedAscending.stream().filter(location -> location.height > currentHeight).collect(Collectors.toList()));
    }

    return optimizedHeightLocations;
}

/**
 * Determine all the locations for this current row/pair and position
 * @param activeRow The current row/pair
 * @param activePos The current position
 * @param locations The locations for this row/pair
 * @return The locations at this exact row/pair and position
 */
private List<Location> getLocationsForRowAndPosition(int activeRow, int activePos,
        List<Location> locations) {
    int minRow = activeRow;
    int maxRow = ((activeRow & 1) == 0) ? activeRow + 1 : activeRow;    // If even, then pair includes the next higher row
    return locations.stream().filter(location -> location.row >= minRow && location.row <= maxRow && location.position == activePos)
            .collect(Collectors.toList());
}

/**
 * Determine the next position, given the current position
 * @param currentPosition Where the operator is currently
 * @param locations The locations for this row/pair
 * @return The next closest, or zero if they are at the end
 */
private int getNextPos(int currentPosition, List<Location> locations) {
    if (locations.isEmpty())
        return 0;
    OptionalInt min = locations.stream().filter(location -> location.position > currentPosition)
            .mapToInt(location -> location.position)
            .min(); 
    return min.isPresent() ? min.getAsInt() : 0;
}

/**
 * Filter out any locations for this row pair.
 * The locations for this row will be removed from the original list
 * @param nextRow The current row being processed
 * @param locations The remaining locations
 * @return The locations for the active row
 */
private List<Location> getLocationsByRowPair(int nextRow, List<Location> locations) {
    List<Location> activeLocations = new ArrayList<Location>();
    Iterator<Location> i = locations.iterator();
    int minRow = nextRow;
    int maxRow = ((nextRow & 1) == 0) ? nextRow + 1 : nextRow;  // If even, then pair includes the next higher row
    while (i.hasNext()) {
        Location current = i.next();
        if (current.row >= minRow && current.row <= maxRow) {
            activeLocations.add(current);
            i.remove();
        }
    }
    return activeLocations;
}

/**
 * Determine the lowest row from the locations provided
 * @param locations All remaining locations
 * @return The minimum row number remaining
 */
private int getNextRow(List<Location> locations) {
    if (locations.isEmpty())
        return 0;
    return locations.stream().mapToInt(location -> location.row)
            .min().getAsInt();
}

class Location {
    final int row;
    final int position;
    final int height;
    public Location(int row, int height, int position) {
        this.row = row;
        this.position = position;
        this.height = height;
    }
    @Override
    public String toString() {
        return "[" + row + ", " + height + ", " + position + "]";
    }

}
为了更好地理解最终排序列表(最接近的高度用于较小的高度移动),应如下所示:

30 02 01 
31 07 04 
31 02 05 
31 03 05 
30 04 05 
31 07 05 
30 09 05 
31 09 05 
31 03 06
30 02 01 
31 07 04
31 07 05 
30 09 05
31 09 05 
30 04 05
31 03 05    
31 02 05
31 03 06 

你知道如何使用我的排序算法来达到这个结果吗?

下面给出了限制条件,解决了叉车问题

ALGORITHM
Input:  All locations
Output:  Shortest path given constraints
1.  For all row/pairs, in increasing order
2.  For all positions in that row, in increasing order
3.  For all heights with same row/pair and position, add locations to minimize the height change given a starting height
代码使用Java8流。代码试图使用单一用途的方法;因此,请随意用更熟悉的语法重写任何方法。它不能保证被优化,但考虑到输入的低大小,这不应该成为一个问题。如果你有任何问题,请告诉我

以及守则:

Collections.sort(unoptimizedLocations, new Comparator<ItemOrderLocation>() {
    @Override
    public int compare(ItemOrderLocation item1, ItemOrderLocation item2) {

        int rowCmp = item1.row.compareTo(item2.row);
        int heightCmp = item1.height.compareTo(item2.height);
        int posCmp = item1.pos.compareTo(item2.pos);

        int item1Row = Integer.parseInt(item1.row);
        int item2Row = Integer.parseInt(item2.row);

        boolean onForkLiftPath = false;

        if (item1Row == (item2Row + 1) && (item2Row % 2 == 0)) {
            onForkLiftPath = true;
        }

        if (!onForkLiftPath && rowCmp != 0) {
            //Two differents rows which are not on Fork Lift Path
            return rowCmp;
        }

        //If are on forklift path we compare the position
        if (posCmp != 0) {
            return posCmp;
        }

        //Lastly if row is on forklift path and we are on same position we need to sort by nearest height
        return heightCmp;
    }
});
public class ForkLiftOperator {

public static void main(String[] args) {
    new ForkLiftOperator().start();
}

private void start() {

    List<Location> locations = new ArrayList<Location>();
    locations.add(new Location(30, 9, 5));
    locations.add(new Location(30, 4, 5));
    locations.add(new Location(30, 2, 1));
    locations.add(new Location(31, 7, 5));
    locations.add(new Location(31, 7, 4));
    locations.add(new Location(31, 3, 5));
    locations.add(new Location(31, 3, 6));
    locations.add(new Location(31, 9, 5));
    locations.add(new Location(31, 2, 5));
    locations.add(new Location(32, 2, 5));  // Extra to simulate additional row/pair

    List<Location> solution = solve(locations);
    System.out.println(solution);
}


private List<Location> solve(List<Location> locations) {

    List<Location> shortestPath = new ArrayList<Location>();
    int activeRow, activePosition, activeHeight;
    while ((activeRow = getNextRow(locations)) != 0) {
        System.out.println("Working on row="+activeRow);
        List<Location> activeLocations = getLocationsByRowPair(activeRow, locations);
        activePosition = 0;
        activeHeight = 0;
        while ((activePosition = getNextPos(activePosition, activeLocations)) != 0) {
            System.out.println("Working on pos="+activePosition);
            List<Location> activePositionLocations = getLocationsForRowAndPosition(activeRow, activePosition, activeLocations);
            shortestPath.addAll(minimizeHeight(activeHeight, activePositionLocations));
            activeHeight = shortestPath.get(shortestPath.size()-1).height;
        }
    }


    return shortestPath;
}

enum Direction { UP, DOWN }
/**
 * For the given locations (which are guaranteed to be at the same row/position), minimize the total height change
 * @param activePositionLocations The locations at this row/pair and location (they will only differ in height)
 * @return The order will minimize the height change
 */
private List<Location> minimizeHeight(int currentHeight, List<Location> activePositionLocations) {
    List<Location> optimizedHeightLocations = new ArrayList<Location>();
    System.out.println("Processing locations="+activePositionLocations);
    int minHeight = activePositionLocations.stream().mapToInt(location -> location.height).min().getAsInt();
    int maxHeight = activePositionLocations.stream().mapToInt(location -> location.height).max().getAsInt();
    /*
     * There are only two options to minimize (if the current height falls between min and max):
     * 1)  Travel down then up
     * 2)  Travel up then down
     */
    // First determine the first direction to go
    Direction direction;
    if (currentHeight == minHeight)
        direction = Direction.UP;
    else if (currentHeight == maxHeight)
        direction = Direction.DOWN;
    else {
        int distanceUp = maxHeight-currentHeight;
        int distanceDown = currentHeight-minHeight;
        direction = distanceUp < distanceDown ? Direction.UP : Direction.DOWN;
    }
    // Now travel in that direction (must sort the correct way first
    List<Location> sortedAscending = activePositionLocations.stream().sorted((l1, l2) -> Integer.compare(l1.height, l2.height)).collect(Collectors.toList());
    List<Location> sortedDescending = activePositionLocations.stream().sorted((l1, l2) -> Integer.compare(l2.height, l1.height)).collect(Collectors.toList());
    if (direction == Direction.UP) {
        optimizedHeightLocations.addAll(sortedAscending.stream().filter(location -> location.height >= currentHeight).collect(Collectors.toList()));
        optimizedHeightLocations.addAll(sortedDescending.stream().filter(location -> location.height < currentHeight).collect(Collectors.toList()));
    } else {    // Direction = DOWN
        optimizedHeightLocations.addAll(sortedDescending.stream().filter(location -> location.height <= currentHeight).collect(Collectors.toList()));
        optimizedHeightLocations.addAll(sortedAscending.stream().filter(location -> location.height > currentHeight).collect(Collectors.toList()));
    }

    return optimizedHeightLocations;
}

/**
 * Determine all the locations for this current row/pair and position
 * @param activeRow The current row/pair
 * @param activePos The current position
 * @param locations The locations for this row/pair
 * @return The locations at this exact row/pair and position
 */
private List<Location> getLocationsForRowAndPosition(int activeRow, int activePos,
        List<Location> locations) {
    int minRow = activeRow;
    int maxRow = ((activeRow & 1) == 0) ? activeRow + 1 : activeRow;    // If even, then pair includes the next higher row
    return locations.stream().filter(location -> location.row >= minRow && location.row <= maxRow && location.position == activePos)
            .collect(Collectors.toList());
}

/**
 * Determine the next position, given the current position
 * @param currentPosition Where the operator is currently
 * @param locations The locations for this row/pair
 * @return The next closest, or zero if they are at the end
 */
private int getNextPos(int currentPosition, List<Location> locations) {
    if (locations.isEmpty())
        return 0;
    OptionalInt min = locations.stream().filter(location -> location.position > currentPosition)
            .mapToInt(location -> location.position)
            .min(); 
    return min.isPresent() ? min.getAsInt() : 0;
}

/**
 * Filter out any locations for this row pair.
 * The locations for this row will be removed from the original list
 * @param nextRow The current row being processed
 * @param locations The remaining locations
 * @return The locations for the active row
 */
private List<Location> getLocationsByRowPair(int nextRow, List<Location> locations) {
    List<Location> activeLocations = new ArrayList<Location>();
    Iterator<Location> i = locations.iterator();
    int minRow = nextRow;
    int maxRow = ((nextRow & 1) == 0) ? nextRow + 1 : nextRow;  // If even, then pair includes the next higher row
    while (i.hasNext()) {
        Location current = i.next();
        if (current.row >= minRow && current.row <= maxRow) {
            activeLocations.add(current);
            i.remove();
        }
    }
    return activeLocations;
}

/**
 * Determine the lowest row from the locations provided
 * @param locations All remaining locations
 * @return The minimum row number remaining
 */
private int getNextRow(List<Location> locations) {
    if (locations.isEmpty())
        return 0;
    return locations.stream().mapToInt(location -> location.row)
            .min().getAsInt();
}

class Location {
    final int row;
    final int position;
    final int height;
    public Location(int row, int height, int position) {
        this.row = row;
        this.position = position;
        this.height = height;
    }
    @Override
    public String toString() {
        return "[" + row + ", " + height + ", " + position + "]";
    }

}
公共类ForkLiftOperator{
公共静态void main(字符串[]args){
新的ForkLiftOperator().start();
}
私有void start(){
列表位置=新的ArrayList();
位置。添加(新位置(30、9、5));
位置。添加(新位置(30、4、5));
位置。添加(新位置(30,2,1));
增加(新地点(31、7、5));
增加(新地点(31、7、4));
位置。添加(新位置(31,3,5));
位置。添加(新位置(31,3,6));
增加(新地点(31、9、5));
位置。添加(新位置(31,2,5));
locations.add(新位置(32,2,5));//额外模拟额外的行/对
列出解决方案=解决(位置);
System.out.println(解决方案);
}
私有列表求解(列表位置){
List shortestPath=new ArrayList();
int activeRow、activePosition、activeHeight;
而((activeRow=getNextRow(位置))!=0){
System.out.println(“处理行=“+activeRow”);
List activeLocations=getLocationsByRowPair(activeRow,位置);
活动位置=0;
活动高度=0;
而((activePosition=getNextPos(activePosition,activeLocations))!=0){
System.out.println(“在pos=“+activePosition上工作”);
List activePositionLocations=GetLocationsErrorAndPosition(activeRow、activePosition、activeLocations);
addAll(最小高度(activeHeight,activePositionLocations));
activeHeight=shortestPath.get(shortestPath.size()-1).height;
}
}
返回最短路径;
}
枚举方向{向上,向下}
/**
*对于给定位置(保证位于同一行/位置),将总高度变化降至最低
*@param activePositionLocations此行/对的位置和位置(它们仅在高度上不同)
*@返回订单将最小化高度变化
*/
私有列表最小高度(int currentHeight,List activePositionLocations){
List optimizedHeightLocations=new ArrayList();
System.out.println(“处理位置=“+activePositionLocations”);
int minHeight=activePositionLocations.stream().mapToInt(位置->位置.height).min().getAsInt();
int maxHeight=activePositionLocations.stream().mapToInt(位置->位置.height).max().getAsInt();
/*
*只有两个选项可最小化(如果当前高度介于“最小”和“最大”之间):
*1)向下移动,然后向上移动
*2)先上后下
*/
//首先确定要走的第一个方向
方向;
如果(当前高度==最小高度)
方向=向上的方向;
else if(currentHeight==maxHeight)
方向=方向。向下;
否则{
int distance up=最大高度currentHeight;
int distance down=当前高度最小高度;
方向=距离向上<距离向下?方向。向上:方向。向下;
}
//现在沿该方向行驶(必须先按正确的方式排序
List sortedAscending=activePositionLocations.stream().sorted((l1,l2)->Integer.compare(l1.height,l2.height)).collect(Collectors.toList());
List SORTEDESCENDING=activePositionLocations.stream().sorted((l1,l2)->Integer.compare(l2.height,l1.height)).collect(Collectors.toList());
如果(方向==向上方向){
optimizedHeightLocations.addAll(sortedAscending.stream().filter(location->location.height>=currentHeight).collect(Collectors.toList());
optimizedHeightLocations.addAll(sortedDescending.stream().filter(location->location.heightlocation.height location.height>currentHeight).collect(Collector.toList());
}
返回优化的八个位置;
}
/**
*确定当前行/对和位置的所有位置
*@param activeRow当前行/对
*@param activePos当前位置
*@param locations此行/对的位置
*@返回此精确行/对和位置的位置
*/
私有列表GetLocationsErrorAndPosition(int activeRow、int activePos、,
(列出地点){
int minRow=activeRow;
int maxRow=((activeRow&1)==0)?activeRow+1:activeRow;//如果为偶数,则该对包括下一个更高的行
返回locations.stream().filter(location->location.row>=minRow&&loca
private int getNextPos(int currentPosition, List<Location> locations) {
    if (locations.isEmpty())
        return 0;
    OptionalInt min = locations.stream().filter(location -> location.position > currentPosition)
            .mapToInt(location -> location.position)
            .min(); 
    return min.isPresent() ? min.getAsInt() : 0;
}
private int getNextPos(int currentPosition, List<Location> locations) {
    if (locations.isEmpty())
        return 0;
    int minValue = Integer.MAX_VALUE;
    for (Location location : locations) {
        if (location.position > currentPosition && location.position < minValue)
            minValue = location.position;
    }
    return minValue == Integer.MAX_VALUE ? 0 : minValue;
}
private int getNextRow(List<Location> locations) {
    if (locations.isEmpty())
        return 0;
    return locations.stream().mapToInt(location -> location.row)
            .min().getAsInt();
}
private int getNextRow(List<Location> locations) {
    if (locations.isEmpty())
        return 0;
    int minValue = Integer.MAX_VALUE;
    for (Location location : locations) {
        if (location.row < minValue)
            minValue = location.row;
    }
    return minValue;
}
private List<Location> minimizeHeight(int currentHeight, List<Location> activePositionLocations) {
    List<Location> optimizedHeightLocations = new ArrayList<Location>();

    int minHeight = Integer.MAX_VALUE;
    int maxHeight = Integer.MIN_VALUE;
    for (Location location : activePositionLocations) {
        if (location.height < minHeight)
            minHeight = location.height;
        if (location.height > maxHeight)
            maxHeight = location.height;
    }

    /*
     * There are only two options to minimize (if the current height falls between min and max):
     * 1)  Travel down then up
     * 2)  Travel up then down
     */
    // First determine the first direction to go
    Direction direction;
    if (currentHeight == minHeight)
        direction = Direction.UP;
    else if (currentHeight == maxHeight)
        direction = Direction.DOWN;
    else {
        int distanceUp = maxHeight-currentHeight;
        int distanceDown = currentHeight-minHeight;
        direction = distanceUp < distanceDown ? Direction.UP : Direction.DOWN;
    }
    // Now travel in that direction (must sort the correct way first
    List<Location> sortedAscending = new ArrayList<Location>(activePositionLocations);  // Clone it
    Collections.sort(sortedAscending, new Comparator<Location>() {
        @Override
        public int compare(Location l1, Location l2) {
            return Integer.compare(l1.height, l2.height);
        }
    });
    List<Location> sortedDescending = new ArrayList<Location>(activePositionLocations); // Clone it
    Collections.sort(sortedDescending, new Comparator<Location>() {
        @Override
        public int compare(Location l1, Location l2) {
            return Integer.compare(l2.height, l1.height);
        }
    });

    if (direction == Direction.UP) {
        for (Location location : sortedAscending) {
            if (location.height >= currentHeight)
                optimizedHeightLocations.add(location);
        }
        for (Location location : sortedDescending) {
            if (location.height < currentHeight)
                optimizedHeightLocations.add(location);
        }
    } else {    // Direction = DOWN
        for (Location location : sortedDescending) {
            if (location.height <= currentHeight)
                optimizedHeightLocations.add(location);
        }
        for (Location location : sortedAscending) {
            if (location.height > currentHeight)
                optimizedHeightLocations.add(location);
        }
    }

    return optimizedHeightLocations;
}