yewanji 2024-07-29 15:11 采纳率: 36.3%
浏览 11
已结题

java 贪心算法优化问题

在一般的贪心算法里面,都是将物品重量进行降序,然后判断是否大于箱子的重量,再将物品放入到箱子的,如:

private static void fillBoxes(Item[] items, Box[] boxes) {
        // Sort the items by their weight
        Arrays.sort(items, Comparator.comparingDouble(Item::getItemWeight));

        // Fill each box with items
        for (Item item : items) {
            for (Box box : boxes) {
                if ( box.canAddItem(item)) {
                    box.addItem(item);
                    break;
                }
            }
        }
    }

但是这样有一个最大的问题,比如箱子能装6kg,苹果是4.1kg,葡萄是1.9kg,按道理说这两个东西应该放一起的,实际上两者没有被放一起,请问如何解决这种问题

  • 写回答

14条回答 默认 最新

  • 杨同学* 2024-08-05 14:09
    关注

    该回答结合ChatGPT4o及杨同学*共同作答, 如有帮助,还请采纳。
    要解决这个问题,可以改用动态规划(Dynamic Programming, DP)的方法,而不是简单的贪心算法。这是因为贪心算法的局限在于它做的决策是局部最优的,而没有考虑到全局最优。通过动态规划,可以找到使箱子重量利用最优的方案。

    然而,如果希望继续使用贪心算法,可以采用一些优化策略来提高放置物品的效率。例如,可以在尝试放置物品时,考虑多种组合情况,或者使用更复杂的贪心策略。

    方案1:使用动态规划(DP)解决背包问题

    下面是一个使用动态规划解决背包问题的简化版本:

    import java.util.*;
    
    public class BoxFilling {
    
        static class Item {
            private String name;
            private double weight;
    
            public Item(String name, double weight) {
                this.name = name;
                this.weight = weight;
            }
    
            public double getItemWeight() {
                return weight;
            }
    
            @Override
            public String toString() {
                return name + " (" + weight + ")";
            }
        }
    
        static class Box {
            private double capacity;
            private List<Item> items;
    
            public Box(double capacity) {
                this.capacity = capacity;
                this.items = new ArrayList<>();
            }
    
            public boolean canAddItem(Item item) {
                return getCurrentWeight() + item.getItemWeight() <= capacity;
            }
    
            public void addItem(Item item) {
                items.add(item);
            }
    
            public double getCurrentWeight() {
                return items.stream().mapToDouble(Item::getItemWeight).sum();
            }
    
            @Override
            public String toString() {
                return "Box{" +
                        "capacity=" + capacity +
                        ", items=" + items +
                        '}';
            }
        }
    
        public static void main(String[] args) {
            Item[] items = {
                    new Item("Apple", 4.1),
                    new Item("Grapes", 1.9),
                    new Item("Orange", 2.5),
                    new Item("Banana", 3.0)
            };
            
            Box[] boxes = {
                    new Box(6.0),
                    new Box(6.0)
            };
    
            fillBoxes(items, boxes);
    
            for (Box box : boxes) {
                System.out.println(box);
            }
        }
    
        private static void fillBoxes(Item[] items, Box[] boxes) {
            Arrays.sort(items, Comparator.comparingDouble(Item::getItemWeight).reversed());
    
            for (Box box : boxes) {
                List<Item> remainingItems = new ArrayList<>(Arrays.asList(items));
                List<Item> boxItems = findBestFit(remainingItems, box.capacity);
    
                for (Item item : boxItems) {
                    box.addItem(item);
                    remainingItems.remove(item);
                }
            }
        }
    
        private static List<Item> findBestFit(List<Item> items, double capacity) {
            int n = items.size();
            double[][] dp = new double[n + 1][(int) (capacity * 100) + 1];
            boolean[][] keep = new boolean[n + 1][(int) (capacity * 100) + 1];
    
            for (int i = 1; i <= n; i++) {
                Item item = items.get(i - 1);
                int itemWeight = (int) (item.getItemWeight() * 100);
    
                for (int w = 0; w <= (int) (capacity * 100); w++) {
                    if (itemWeight <= w && dp[i - 1][w - itemWeight] + item.getItemWeight() > dp[i - 1][w]) {
                        dp[i][w] = dp[i - 1][w - itemWeight] + item.getItemWeight();
                        keep[i][w] = true;
                    } else {
                        dp[i][w] = dp[i - 1][w];
                    }
                }
            }
    
            List<Item> result = new ArrayList<>();
            for (int i = n, w = (int) (capacity * 100); i > 0; i--) {
                if (keep[i][w]) {
                    Item item = items.get(i - 1);
                    result.add(item);
                    w -= (int) (item.getItemWeight() * 100);
                }
            }
    
            return result;
        }
    }
    

    方案2:优化贪心算法

    优化贪心算法,可以尝试以下方法:

    1. 尝试多个箱子的组合:在放置每个物品时,尝试将物品放置到不同的箱子,计算各个组合的利用率。

    2. 提前规划:在放置每个物品时,考虑未来可能要放置的物品,并且根据当前物品和未来物品的组合情况进行决策。

    这是一个优化贪心算法的示例:

    private static void fillBoxesOptimized(Item[] items, Box[] boxes) {
        // Sort the items by their weight in descending order
        Arrays.sort(items, Comparator.comparingDouble(Item::getItemWeight).reversed());
    
        // Create a priority queue to keep track of the boxes by their remaining capacity
        PriorityQueue<Box> pq = new PriorityQueue<>(Comparator.comparingDouble(Box::getCurrentWeight).reversed());
    
        for (Box box : boxes) {
            pq.offer(box);
        }
    
        // Fill each box with items
        for (Item item : items) {
            Box bestBox = null;
            double minWaste = Double.MAX_VALUE;
    
            // Find the best box to place the item
            for (Box box : pq) {
                if (box.canAddItem(item)) {
                    double waste = box.capacity - (box.getCurrentWeight() + item.getItemWeight());
                    if (waste < minWaste) {
                        minWaste = waste;
                        bestBox = box;
                    }
                }
            }
    
            // Add item to the best box found
            if (bestBox != null) {
                bestBox.addItem(item);
                pq.remove(bestBox);
                pq.offer(bestBox);
            }
        }
    }
    

    在上述示例中,我们通过优化贪心策略来尽可能减少每次放置物品后的空闲空间,最大化利用箱子容量。

    通过这些方法,可以在一定程度上解决单纯贪心算法在复杂情况下的局限性。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(13条)

报告相同问题?

问题事件

  • 系统已结题 8月16日
  • 已采纳回答 8月8日
  • 赞助了问题酬金15元 8月1日
  • 创建了问题 7月29日

悬赏问题

  • ¥15 可以实现这个有不同背景颜色的九九乘法表吗?
  • ¥50 python写segy数据时出错2
  • ¥20 关于R studio 做精确稳定检验的问题!(语言-r语言)
  • ¥50 用贝叶斯决策方法,设计CAD程序
  • ¥20 关于#目标检测#的问题:(qq收集表到时间才能填写,填写的份数有上限)
  • ¥50 ZYNQ7020双核FLAHS烧写的问题
  • ¥20 ue 5 中想要实现第一人称人物左右行走摆动的效果,摄像头只向右摆动一次(关键词-结点)
  • ¥15 AD9164瞬时带宽1.8G,怎么计算出来?
  • ¥15 鼠标右键,撤销删除 复制 移动,要怎样删除? HKEY_CLASSES_ROOT*\shellex\ContextMenuHandlers 没用
  • ¥15 服务器安装php5.6版本