计算三段路程之和最低,应用于海运中的1:门到门、2:门到港、3:港到门、4:港到港

当计算海运价格时,会包含始发地到始发港、始发港都目的港、目的港到目的地的这三段路程。当系统中已经维护了始发地到始发港的字典数据,始发港都目的港的字典数据,目的港到目的地的字典数据后,当要查询1:门到门、2:门到港、3:港到门、4:港到港的最低价格,并且给出各段的分别价格时,用到如下方法

注释:

1:门到门包含:始发地到始发港+始发港到目的港+目的港到目的地

2:门到港包含:始发地到始发港+始发港到目的港

3:港到门:始发港到目的港+目的港到目的地

4:港到港:始发港到目的港

上代码

/**
     * 查询最低价格
     *
     * @param dto
     * @return
     */
    public SearchPriceResult getSearchPriceResult(SearchPriceDTO dto) {
        SearchPriceResult searchPriceResult = new SearchPriceResult();
        // 创建价格信息字典
        Map<String, List<PriceInfo>> priceMap = new HashMap<>();
        //集港价格集合
        //List<TSeaFreightConsolidationPrice> tSeaFreightConsolidationPriceList =  tSeaFreightConsolidationPriceService.list();
        List<TSeaFreightConsolidationPrice> tSeaFreightConsolidationPriceList = myCache.getAllTSeaFreightConsolidationPrice();
        // 添加集港价格信息,达到类似下面效果
        if (EmptyUtil.isNotEmpty(tSeaFreightConsolidationPriceList)) {
            for (TSeaFreightConsolidationPrice price : tSeaFreightConsolidationPriceList) {
                String originatingDetailAddress = price.getNvcOrginatingDetailAddress();
                String loadingPort = price.getNvcDestinationPortAddress();
                Double priceValue = price.getDContainerTrailerFee();
                PriceInfo priceInfo = new PriceInfo("集港", originatingDetailAddress, loadingPort, priceValue);
                // 检查priceMap中是否已经有该始发地的列表
                List<PriceInfo> priceInfoList = priceMap.getOrDefault(originatingDetailAddress, new ArrayList<>());
                // 添加新的PriceInfo到列表中
                priceInfoList.add(priceInfo);
                // 将列表放回priceMap中
                priceMap.put(originatingDetailAddress, priceInfoList);
            }
        }
        // 添加集港价格信息
        /*
        priceMap.put("始发地A", Arrays.asList(
                new PriceInfo("集港", "始发地A", "始发港1", 100.0),
                new PriceInfo("集港", "始发地A", "始发港2", 120.0)
        ));
        priceMap.put("始发地B", Collections.singletonList(
                new PriceInfo("集港", "始发地B", "始发港3", 90.0)
        ));
        */
        //海运价格集合
        //List<TOceanfreightPrice> oceanFreightPrices  = tOceanfreightPriceService.list();
        List<TOceanfreightPrice> oceanFreightPrices = myCache.getAllTOceanfreightPrice();
        // 遍历查询结果
        for (TOceanfreightPrice price : oceanFreightPrices) {
            // 假设 OceanFreightPrice 类有相应的 getter 方法来获取字段值
            String originatingPort = price.getNvcOriginatingPortAddress(); // 始发港
            String destinationPort = price.getNvcDestinationPortAddress(); // 目的港
            double freightPrice = price.getDOceanFreight() + price.getDOriginatingExtras(); // 海运费

            // 检查 priceMap 中是否已经有该始发港的列表
            List<PriceInfo> priceInfoList = priceMap.getOrDefault(originatingPort, new ArrayList<>());

            // 创建 PriceInfo 对象并添加到列表中
            PriceInfo priceInfo = new PriceInfo("海运", originatingPort, destinationPort, freightPrice);
            priceInfoList.add(priceInfo);

            // 将列表放回 priceMap 中
            priceMap.put(originatingPort, priceInfoList);
        }

        // 添加海运价格信息
        /*
        priceMap.put("始发港1", Collections.singletonList(
                new PriceInfo("海运", "始发港1", "目的港1", 500.0)
        ));
        priceMap.put("始发港2", Arrays.asList(
                new PriceInfo("海运", "始发港2", "目的港1", 480.0),
                new PriceInfo("海运", "始发港2", "目的港2", 490.0)
        ));
        priceMap.put("始发港3", Collections.singletonList(
                new PriceInfo("海运", "始发港3", "目的港2", 510.0)
        ));
        */
        //送货价格集合
        //List<TSeaFreightDeliveryPrice> tSeaFreightDeliveryPrices = tSeaFreightDeliveryPriceService.list();
        List<TSeaFreightDeliveryPrice> tSeaFreightDeliveryPrices = myCache.getAllTSeaFreightDeliveryPrice();
        // 遍历查询结果
        for (TSeaFreightDeliveryPrice price : tSeaFreightDeliveryPrices) {
            // 假设 OceanFreightPrice 类有相应的 getter 方法来获取字段值
            String destinationPort = price.getNvcDestinationPortAddress(); // 目的港
            String destinationDetailAddress = price.getNvcDestinationDetailAddress(); // 目的地
            double freightPrice = price.getDDestinationExtras() + price.getDDeliveryTrailerFee(); // 海运费

            // 检查 priceMap 中是否已经有该始发港的列表
            List<PriceInfo> priceInfoList = priceMap.getOrDefault(destinationPort, new ArrayList<>());

            // 创建 PriceInfo 对象并添加到列表中
            PriceInfo priceInfo = new PriceInfo("送货", destinationPort, destinationDetailAddress, freightPrice);
            priceInfoList.add(priceInfo);

            // 将列表放回 priceMap 中
            priceMap.put(destinationPort, priceInfoList);
        }

        // 添加送货价格信息
        /*
        priceMap.put("目的港1", Arrays.asList(
                new PriceInfo("送货", "目的港1", "目的地X", 150.0),
                new PriceInfo("送货", "目的港1", "目的地Y", 160.0)
        ));
        priceMap.put("目的港2", Collections.singletonList(
                new PriceInfo("送货", "目的港2", "目的地Y", 140.0)
        ));
        */
        // 创建海运价格计算器实例
        SeaFreightCalculator calculator = new SeaFreightCalculator(priceMap);
        LowestPriceResult result = new LowestPriceResult();
        if (dto.getIType() == 1) {
            result = calculator.calculateLowestPrice(dto.getNvcOrginatingDetailAddress(), dto.getNvcDestinationDetailAddress());

        }
        if (dto.getIType() == 2) {
            result = calculator.calculateLowestPriceFromOriginToPort(dto.getNvcOrginatingDetailAddress(), dto.getNvcDestinationDetailAddress());
        }
        if (dto.getIType() == 3) {
            result = calculator.calculateLowestPriceFromPortToDestination(dto.getNvcOrginatingDetailAddress(), dto.getNvcDestinationDetailAddress());
        }
        if (dto.getIType() == 4) {
            result = calculator.calculateLowestPriceFromPortToPort(dto.getNvcOrginatingDetailAddress(), dto.getNvcDestinationDetailAddress());
        }

        searchPriceResult.setLowestTotalPrice(result.getLowestTotalPrice());
//        if (result.getPortPrice()==null)  result.getSeaPrice().setPrice() = 0.0;
        searchPriceResult.setPortPrice(result.getPortPrice() == null ? null : result.getPortPrice().getPrice());
        searchPriceResult.setSeaPrice(result.getSeaPrice() == null ? null : result.getSeaPrice().getPrice());
        searchPriceResult.setDeliveryPrice(result.getDeliveryPrice() == null ? null : result.getDeliveryPrice().getPrice());

        /*
        // 计算从始发地A到目的港的最低价格  门到港
        LowestPriceResult result1 = calculator.calculateLowestPriceFromOriginToPort("始发地A", "目的港2");
        System.out.println(result1);

        // 计算从始发港1到目的港的最低价格  港到港
        LowestPriceResult result2 = calculator.calculateLowestPriceFromPortToPort("始发港1", "目的港1");
        System.out.println(result2);

        // 计算从始发港2到目的地的最低价格  港到门
        LowestPriceResult result3 = calculator.calculateLowestPriceFromPortToDestination("始发港2", "目的地Y");
        System.out.println(result3);

        // 计算从始发地A到目的地Y的最低价格  门到门
        LowestPriceResult result = calculator.calculateLowestPrice("始发地A", "目的地Y");
        System.out.println(result);*/
        return searchPriceResult;
    }

下面是计算价格的核心方法

public class SeaFreightCalculator {
    private Map<String, List<PriceInfo>> priceMap;

    public SeaFreightCalculator(Map<String, List<PriceInfo>> priceMap) {
        this.priceMap = priceMap;
    }

    // 公共方法:获取特定类型的价格信息
    private List<PriceInfo> getPrices(String from, String type) {
        return priceMap.getOrDefault(from, Collections.emptyList()).stream()
                .filter(price -> price.getType().equals(type))
                .collect(Collectors.toList());
    }

    // 计算从始发港到目的港的最低价格(港到港)
    public LowestPriceResult calculateLowestPriceFromPortToPort(String from, String to) {
        LowestPriceResult result = new LowestPriceResult();
        result.setFrom(from);
        result.setTo(to);

        double lowestTotalPrice = Double.MAX_VALUE;
        PriceInfo lowestPrice = null;

        for (PriceInfo price : getPrices(from, "海运")) {
            if (price.getTo().equals(to) && lowestTotalPrice > price.getPrice()) {
                lowestTotalPrice = price.getPrice();
                lowestPrice = price;
            }
        }

        if (lowestPrice != null) {
            result.setLowestTotalPrice(lowestTotalPrice);
            result.setSeaPrice(lowestPrice);
        }

        return result;
    }

    // 计算从始发地到目的港的最低价格(需要集港和海运两段)(门到港)
    public LowestPriceResult calculateLowestPriceFromOriginToPort(String from, String to) {
        LowestPriceResult result = new LowestPriceResult();
        result.setFrom(from);
        result.setTo(to);

        double lowestTotalPrice = Double.MAX_VALUE;
        PriceInfo lowestPortPrice = null, lowestSeaPrice = null;

        // 遍历所有集港价格
        for (PriceInfo collectionPrice : getPrices(from, "集港")) {
            String intermediatePort = collectionPrice.getTo(); // 中间港口

            // 对于每个中间港口,找到到目的港的海运价格
            for (PriceInfo seaPrice : getPrices(intermediatePort, "海运")) {
                if (seaPrice.getTo().equals(to)) {
                    double totalPrice = collectionPrice.getPrice() + seaPrice.getPrice();
                    if (totalPrice < lowestTotalPrice) {
                        lowestTotalPrice = totalPrice;
                        lowestPortPrice = collectionPrice;
                        lowestSeaPrice = seaPrice;
                    }
                }
            }
        }

        if (lowestPortPrice != null && lowestSeaPrice != null) {
            result.setLowestTotalPrice(lowestTotalPrice);
            result.setPortPrice(lowestPortPrice);
            result.setSeaPrice(lowestSeaPrice);
        }

        return result;
    }


    // 计算从始发港到目的地的最低价格(需要海运和送货两段)(港到门)
    public LowestPriceResult calculateLowestPriceFromPortToDestination(String fromPort, String toDestination) {
        LowestPriceResult result = new LowestPriceResult();
        result.setFrom(fromPort);
        result.setTo(toDestination);

        double lowestTotalPrice = Double.MAX_VALUE;
        PriceInfo lowestSeaPrice = null, lowestDeliveryPrice = null;

        for (PriceInfo seaPrice : getPrices(fromPort, "海运")) {
            for (PriceInfo deliveryPrice : getPrices(seaPrice.getTo(), "送货")) {
                if (deliveryPrice.getTo().equals(toDestination)) {
                    double totalPrice = seaPrice.getPrice() + deliveryPrice.getPrice();
                    if (totalPrice < lowestTotalPrice) {
                        lowestTotalPrice = totalPrice;
                        lowestSeaPrice = seaPrice;
                        lowestDeliveryPrice = deliveryPrice;
                    }
                }
            }
        }

        if (lowestSeaPrice != null && lowestDeliveryPrice != null) {
            result.setLowestTotalPrice(lowestTotalPrice);
            result.setSeaPrice(lowestSeaPrice);
            result.setDeliveryPrice(lowestDeliveryPrice);
        }

        return result;
    }

    // 计算最低价格的方法 (计算从始发地到目的地的最低价格需要集港、海运、送货三段,门到门)
    public LowestPriceResult calculateLowestPrice(String from, String to) {
        LowestPriceResult lowestPriceResult = new LowestPriceResult();
        lowestPriceResult.setFrom(from);
        lowestPriceResult.setTo(to);

        double lowestTotalPrice = Double.MAX_VALUE;
        PriceInfo lowestPortPrice = null, lowestSeaPrice = null, lowestDeliveryPrice = null;

        // 遍历所有可能的路径
        for (PriceInfo portPrice : priceMap.getOrDefault(from, Collections.emptyList())) {
            if ("集港".equals(portPrice.getType())) {
                for (PriceInfo seaPrice : priceMap.getOrDefault(portPrice.getTo(), Collections.emptyList())) {
                    if ("海运".equals(seaPrice.getType())) {
                        for (PriceInfo deliveryPrice : priceMap.getOrDefault(seaPrice.getTo(), Collections.emptyList())) {
                            if ("送货".equals(deliveryPrice.getType()) && deliveryPrice.getTo().equals(to)) {
                                double totalPrice = portPrice.getPrice() + seaPrice.getPrice() + deliveryPrice.getPrice();
                                if (totalPrice < lowestTotalPrice) {
                                    lowestTotalPrice = totalPrice;
                                    lowestPortPrice = portPrice;
                                    lowestSeaPrice = seaPrice;
                                    lowestDeliveryPrice = deliveryPrice;
                                }
                            }
                        }
                    }
                }
            }
        }

        // 设置最低价格和各段价格
        if (lowestTotalPrice != Double.MAX_VALUE) {
            lowestPriceResult.setLowestTotalPrice(lowestTotalPrice);
            lowestPriceResult.setPortPrice(lowestPortPrice);
            lowestPriceResult.setSeaPrice(lowestSeaPrice);
            lowestPriceResult.setDeliveryPrice(lowestDeliveryPrice);
        }

        return lowestPriceResult;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值