diff --git a/dntd-model-buildheating/src/main/java/com/dky/calculate/Scheme.java b/dntd-model-buildheating/src/main/java/com/dky/calculate/Scheme.java index b2bac5c..5456780 100644 --- a/dntd-model-buildheating/src/main/java/com/dky/calculate/Scheme.java +++ b/dntd-model-buildheating/src/main/java/com/dky/calculate/Scheme.java @@ -4,56 +4,68 @@ package com.dky.calculate; import com.dky.utils.entity.SysDeviceHeatScene; import com.dky.utils.result.MatchedDevice; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; public class Scheme { - public static List>>> calScheme(Double buildArea, List list) { - // 区分电锅炉、热泵 - Map> grouped = list.stream() + /** + * 根据设备细类筛选出不同技术类型的不同功率设备需要的数量 + * List 同一个技术类型下的设备列表以及每个设备所需要的台数 + * Map>> 键为设备细类 + * + * @param buildArea 建筑面积 + * @param sysDeviceHeatSceneList 替代设备列表 + * @return + */ + public static List> calScheme(Double buildArea, List sysDeviceHeatSceneList) { + // 根据设备细类筛选出一个以设备细类为键,该细类下设备列表为值的Map + Map> groupByDevSubTypeMap = sysDeviceHeatSceneList.stream() .collect(Collectors.groupingBy(SysDeviceHeatScene::getDevSubType)); - List>>> maps = new ArrayList<>(); + // 区分技术类型 - grouped.forEach((k, v) -> { - Map>> map = new HashMap<>(); - List> planList = new ArrayList<>(); - Map> collect = v.stream().collect(Collectors.groupingBy(SysDeviceHeatScene::getDevTechType)); - collect.forEach((k2, v2) -> { - List matchedDevices = calSchemeByTechType(buildArea, v2); + List> planList = new ArrayList<>(); + groupByDevSubTypeMap.forEach((devSubType, v) -> { + + // 该细类下的设备根据技术类型筛选出一个以技术类型为键,该技术类型下设备列表为值的Map + Map> groupByDevTechTypeMap = v.stream().collect(Collectors.groupingBy(SysDeviceHeatScene::getDevTechType)); + + groupByDevTechTypeMap.forEach((devTechType, devList) -> { + List matchedDevices = calSchemeByTechType(buildArea, devList); planList.add(matchedDevices); }); - map.put(k, planList); - maps.add(map); + }); - return maps; + return planList; } - public static List calSchemeByTechType(Double buildArea, List list) { - // 对List按照单台设备可参考供暖面积进行排序 - list.sort((o1, o2) -> Double.compare(o2.getDevReferenceArea(), o1.getDevReferenceArea())); + + /** + * 根据建筑面积和其中一个设备细类-技术类型下的不同功率的设备,计算出该技术类型分别需要不同功率的设备的的数量 + * + * @param buildArea 建筑面积 + * @param sysDeviceHeatSceneList 不同设备细类-技术类型下的设备列表 + * @return 不同功率的设备对应所需要的数量 + */ + public static List calSchemeByTechType(Double buildArea, List sysDeviceHeatSceneList) { + // 对技术类型下的设备list按照单台设备可参考供暖面积进行排序 + sysDeviceHeatSceneList.sort((o1, o2) -> Double.compare(o2.getDevReferenceArea(), o1.getDevReferenceArea())); Double remainArea = buildArea; // 遍历设备,根据建筑面积进行匹配设备数量 List matchedDeviceList = new ArrayList<>(); - for (SysDeviceHeatScene deviceHeatScene : list) { + for (SysDeviceHeatScene deviceHeatScene : sysDeviceHeatSceneList) { double v = remainArea / deviceHeatScene.getDevReferenceArea(); int count = (int) (v); - if (v < 1){ + if (v < 1) { count = count + 1; } remainArea = remainArea - count * deviceHeatScene.getDevReferenceArea(); matchedDeviceList.add(new MatchedDevice(count, deviceHeatScene)); - if (remainArea <= 0){ + if (remainArea <= 0) { // 当总供暖面积已经满足需求时,跳出循环,不再选择其他设备 break; } } return matchedDeviceList; } - - - } diff --git a/dntd-model-buildheating/src/main/java/com/dky/calculate/SchemeRating.java b/dntd-model-buildheating/src/main/java/com/dky/calculate/SchemeRating.java index 90f3864..bf09f38 100644 --- a/dntd-model-buildheating/src/main/java/com/dky/calculate/SchemeRating.java +++ b/dntd-model-buildheating/src/main/java/com/dky/calculate/SchemeRating.java @@ -1,6 +1,7 @@ package com.dky.calculate; +import com.dky.utils.entity.SysDeviceHeatScene; import com.dky.utils.result.MatchedDevice; import java.util.*; @@ -9,38 +10,27 @@ import java.util.concurrent.atomic.AtomicReference; public class SchemeRating { /** - * 计算效率和成本评分 + * 计算每一种方案的效率和成本评分 * @param list * @return */ - public static Map> getOptimalList(List>>> list,Double costRatio,Double effRatio) { + public static Map> getOptimalList(List> list,Double costRatio,Double effRatio,Map maxEff,Map minPrice) { + Map> optimalMap = new HashMap<>(); - list.parallelStream().forEach(stringListMap -> { - // 区分热泵、电锅炉 - stringListMap.forEach((k,v)->{ - // 循环遍历各个方案 - v.parallelStream().forEach((plan)->{ - AtomicReference rating = new AtomicReference<>(0.0); - List> maps = getIndex(list); - for (Map map : maps) { - map.forEach((k1, v1) -> { - if (k1.equals(k)){ - Double eff = 0.0; - Double cost = 0.0; - for (MatchedDevice device : plan) { - eff = device.getDeviceHeatScene().getHeatEfficiency(); - } - for (MatchedDevice device : plan) { - cost = cost + ((device.getCount() * device.getDeviceHeatScene().getDevPrice()) + (device.getCount()) * device.getDeviceHeatScene().getDevSubstituteLaborCost() * device.getDeviceHeatScene().getDevServiceLife()); - } - //3、效率成本公式:(1-(选择效率最大-当前值)/效率最大值)*100*0.8 +(1-(当前值-选择成本最小)/成本最小值)*100*0.2。 - rating.set(((1 - ((v1[0] - eff) / v1[0])) * 100 * effRatio) + ((1 - ((cost - v1[1]) / v1[1])) * 100 * costRatio)); - optimalMap.put(rating.get(), plan); - } - }); - } - }); - }); + list.forEach(plan->{ + AtomicReference rating = new AtomicReference<>(0.0); + String devSubType = plan.get(0).getDeviceHeatScene().getDevSubType(); + Double eff = 0.0; + Double cost = 0.0; + for (MatchedDevice device : plan) { + eff = device.getDeviceHeatScene().getHeatEfficiency(); + } + for (MatchedDevice device : plan) { + cost = cost + ((device.getCount() * device.getDeviceHeatScene().getDevPrice()) + (device.getCount()) * device.getDeviceHeatScene().getDevSubstituteLaborCost() * device.getDeviceHeatScene().getDevServiceLife()); + } + //3、(1-(选择对应设备细类的效率最大的效率值(效率最大值)-当前设备的效率值值)/效率最大值)*100*系数 +(1-(当前成本值-对应设备细类的成本最小值)/对应设备细类的成本最小值)*100*0.2。取最高得分。 + rating.set(((1 - ((maxEff.get(devSubType) - eff) / maxEff.get(devSubType))) * 100 * effRatio) + ((1 - ((cost - minPrice.get(devSubType)) / minPrice.get(devSubType))) * 100 * costRatio)); + optimalMap.put(rating.get(), plan); }); return optimalMap; } @@ -62,36 +52,72 @@ public class SchemeRating { return map.get(maxValue); } - public static List> getIndex(List>>> list) { - List> maps = new ArrayList<>(); - list.parallelStream().forEach(stringListMap -> { - // 区分热泵、电锅炉 - stringListMap.forEach((k, v) -> { - // 循环遍历各个方案 - // 热效率、成本 - final Double[] index = {0.0, Double.MAX_VALUE}; - v.parallelStream().forEach((plan) -> { - Double eff = 0.0; - Double cost = 0.0; - for (MatchedDevice device : plan) { - eff = device.getDeviceHeatScene().getHeatEfficiency(); - } - for (MatchedDevice device : plan) { - cost = cost + ((device.getCount() * device.getDeviceHeatScene().getDevPrice()) + (device.getCount()) * device.getDeviceHeatScene().getDevSubstituteLaborCost() * device.getDeviceHeatScene().getDevServiceLife()); - } - if (eff >= index[0]) { - index[0] = eff; - } - if (cost <= index[1]) { - index[1] = cost; - } - }); - Map map = new HashMap<>(); - map.put(k, index); - maps.add(map); - }); + /** + * 获取不同设备细类下的效率最大值 + * @param alternateDeviceList 可替代设备列表 + * @return 不同设备细类下的效率最大值map + */ + public static Map getMaxEfficiencyGroupByDevSubType( List alternateDeviceList){ + Map map = new HashMap<>(); + alternateDeviceList.forEach(alternateDevice ->{ + String devSubType = alternateDevice.getDevSubType(); + Double v = map.get(devSubType); + if ( v == null){ + map.put(devSubType,alternateDevice.getHeatEfficiency()); + } else { + if( alternateDevice.getHeatEfficiency() > v){ + map.put(devSubType,alternateDevice.getHeatEfficiency()); + } + } + }); + return map; + } + + /** + * 获取不同设备细类下的成本最小值 + * @param alternateDeviceList 可替代设备列表 + * @return 不同设备细类下的成本最小值map + */ + public static Map getMinPriceGroupByDevSubType( List alternateDeviceList){ + Map map = new HashMap<>(); + alternateDeviceList.forEach(alternateDevice -> { + String devSubType = alternateDevice.getDevSubType(); + Double v = map.get(devSubType); + if ( v == null){ + map.put(devSubType,alternateDevice.getDevPrice()+ alternateDevice.getDevSubstituteLaborCost()*alternateDevice.getDevServiceLife()); + } else { + if( alternateDevice.getDevPrice() < v){ + map.put(devSubType,alternateDevice.getDevPrice() + alternateDevice.getDevSubstituteLaborCost()*alternateDevice.getDevServiceLife()); + } + } }); + return map; + } + + + public static List> getIndex(List> list) { + List> maps = new ArrayList<>(); + final Double[] index = {0.0, Double.MAX_VALUE}; + Map map = new HashMap<>(); + list.parallelStream().forEach((plan) -> { + Double eff = 0.0; + Double cost = 0.0; + for (MatchedDevice device : plan) { + eff = device.getDeviceHeatScene().getHeatEfficiency(); + } + for (MatchedDevice device : plan) { + cost = cost + ((device.getCount() * device.getDeviceHeatScene().getDevPrice()) + (device.getCount()) * device.getDeviceHeatScene().getDevSubstituteLaborCost() * device.getDeviceHeatScene().getDevServiceLife()); + } + if (eff >= index[0]) { + index[0] = eff; + } + if (cost <= index[1]) { + index[1] = cost; + } + map.put(plan.get(0).getDeviceHeatScene().getDevSubType(), index); + maps.add(map); + }); return maps; } diff --git a/dntd-modelI/pom.xml b/dntd-modelI/pom.xml index b7e2b84..343c6e1 100644 --- a/dntd-modelI/pom.xml +++ b/dntd-modelI/pom.xml @@ -22,6 +22,12 @@ hutool-all 5.4.5 + + + com.dky + dntd-common + 1.0-SNAPSHOT + \ No newline at end of file diff --git a/dntd-modelI/src/main/java/com/dky/modelI/DntdModelI.java b/dntd-modelI/src/main/java/com/dky/modelI/DntdModelI.java index 6274d0e..ca8f38e 100644 --- a/dntd-modelI/src/main/java/com/dky/modelI/DntdModelI.java +++ b/dntd-modelI/src/main/java/com/dky/modelI/DntdModelI.java @@ -1,7 +1,11 @@ package com.dky.modelI; import cn.hutool.json.JSONObject; +import com.dky.utils.entity.SysDeviceHeatScene; + +import java.util.List; + public interface DntdModelI { - JSONObject createReport(JSONObject jsonObject); + JSONObject createReport(JSONObject jsonObject, List alternateDeviceList); } \ No newline at end of file diff --git a/dntd-tool/src/main/java/com/dky/generate/BuildHeatingScene.java b/dntd-tool/src/main/java/com/dky/generate/BuildHeatingScene.java new file mode 100644 index 0000000..e2ae61a --- /dev/null +++ b/dntd-tool/src/main/java/com/dky/generate/BuildHeatingScene.java @@ -0,0 +1,197 @@ +package com.dky.generate; + + +import cn.hutool.json.JSONObject; +import com.dky.calculate.BuildHeatingAdvantage; +import com.dky.calculate.BuildHeatingModel; +import com.dky.calculate.Scheme; +import com.dky.calculate.SchemeRating; +import com.dky.modelI.DntdModelI; +import com.dky.utils.entity.SysDeviceHeatScene; +import com.dky.utils.result.MatchedDevice; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class BuildHeatingScene implements DntdModelI { + + DecimalFormat decimalFormat = new DecimalFormat("#.00"); + + //首先A=由运行/合同容量折合成kW(x0.9)x85%, + static final Double COEFFICIENT_1 = 0.9; + static final Double COEFFICIENT_2 = 0.85; + + @Override + public JSONObject createReport(JSONObject jsonObject,List alternateDeviceList) { + + JSONObject distInfo = new JSONObject(); + JSONObject buildInfo = new JSONObject(); + JSONObject originalDevInfo = new JSONObject(); + + try{ + distInfo = (JSONObject) jsonObject.get("distInfo"); + buildInfo = (JSONObject) jsonObject.get("buildInfo"); + originalDevInfo = (JSONObject) jsonObject.get("originalDevInfo"); + } catch (Exception e){ + e.printStackTrace(); + } + + // 运行容量 + Double runCapacity = Double.parseDouble(distInfo.get("runCapacity").toString()); + // 上年最大需量 + Double lastYearNeed = Double.parseDouble(distInfo.get("lastYearNeed").toString()); + // 建筑面积 + Double heatingArea = Double.parseDouble(buildInfo.get("heatingArea").toString()); + // 年采暖时间(天) + Integer days = Integer.parseInt(buildInfo.get("days").toString()); + // 上年运行费用(万元) + Double lastYearFee = Double.parseDouble(buildInfo.get("lastYearFee").toString()); + + /* + 实际可承载容量A = 运行(或合同容量)x0.9[将运行容量或合同容量折算成容量]x85% + */ + double A = runCapacity * COEFFICIENT_1 * COEFFICIENT_2; + /* + 替代前设备总功率C + */ + Double C = 0.0; + if (originalDevInfo != null) { + //若存在原设备信息,则获取原设备中设备总功率,累加得出C + } else { + // C=建筑面积(万平方米)x770 + C = (heatingArea / 10000) * 770; + } + /* + 根据建筑面积计算出不同技术类型下所需要不同功率设备数据 + */ + List> matchedDeviceGroupList = Scheme.calScheme(heatingArea, alternateDeviceList); + /* + 替代后设备总功率C1 + */ + double C1 = 0.0; + if (originalDevInfo != null){ + //若存在原设备信息,则根据建筑面积计算每个技术类型下需要的不同功率的设备的数量,然后将不同功率及对应的数量进行计算得出总功率C1 + + } else { + C1 = C/2.5; + } + + /* + 改造前最大需量D + */ + double D = lastYearNeed + C; + + /* + 改造后最大需量D1 + */ + double D1 = lastYearNeed + C1; + + /* + 判断计算占比,默认效率0.8,成本0.2 + */ + double costRatio = 0.2; + double effRatio = 0.8; + try{ + double costRatio1 = Double.parseDouble(jsonObject.get("costRatio").toString()); + double effRatio1 = Double.parseDouble(jsonObject.get("effRatio").toString()); + if(costRatio1 < 1 && costRatio1 + costRatio1 == 1){ + costRatio = costRatio1; + effRatio = effRatio1; + } + }catch (Exception e){ + e.printStackTrace(); + } + + List matchedDeviceList ; + Map> listMap ; + /* + 根据具体容量与需量判断可使用的技术并计算评分 + */ + //计算不同细类下成本最小值与效率最大值 + Map maxEffMap = SchemeRating.getMaxEfficiencyGroupByDevSubType(alternateDeviceList); + Map minPriceMap = SchemeRating.getMinPriceGroupByDevSubType(alternateDeviceList); + String remark = ""; + if (D1 < A && A < D) { + // 判断只能用热泵 + List> heatPumpDevList = new ArrayList<>(); + matchedDeviceGroupList.forEach((matchedDevices -> { + MatchedDevice matchedDevice = matchedDevices.get(0); + if (!"供冷/暖电锅炉".equals(matchedDevice.getDeviceHeatScene().getDevSubType())){ + heatPumpDevList.add(matchedDevices); + } + })); + + listMap = SchemeRating.getOptimalList(heatPumpDevList,costRatio,effRatio,maxEffMap,minPriceMap); + matchedDeviceList = SchemeRating.getOptimalScheme(listMap); + } else { + //同时考虑热泵和电锅炉 + if ( A < D1){ + remark = "本方案存在扩容投资需求,扩容投资不计入初次投资费用"; + } + listMap = SchemeRating.getOptimalList(matchedDeviceGroupList,costRatio,effRatio,maxEffMap,minPriceMap); + matchedDeviceList = SchemeRating.getOptimalScheme(listMap); + } + + List> maps = new ArrayList<>(); + listMap.forEach((k,v)->{ + Map map = new HashMap<>(); + map.put("rating", decimalFormat.format(k)); + map.put("plan", v); + map.put("planName", v.get(0).getDeviceHeatScene().getDevTechType()); + maps.add(map); + }); + + + /* + 封装返回 + */ + JSONObject returnJsonObject = new JSONObject(); + Double startCost = 0.0; + Double runCost = 0.0; + Double allCost = 0.0; + Double calculateAnnualCarbon = 0.0; + Double electric = 0.0; + List> deviceList = new ArrayList<>(); + for (MatchedDevice matchedDevice : matchedDeviceList){ + HashMap map = new HashMap<>(); + map.put("devSubType",matchedDevice.getDeviceHeatScene().getDevSubType()); + map.put("devTechType",matchedDevice.getDeviceHeatScene().getDevTechType()); + map.put("devCount",matchedDevice.getCount()); + map.put("devPrice",matchedDevice.getDeviceHeatScene().getDevPrice()); + deviceList.add(map); + startCost = startCost + (matchedDevice.getCount() * matchedDevice.getDeviceHeatScene().getDevPrice()); + runCost = runCost + (BuildHeatingModel.getRunCost(matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevPower(), days, matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost())); + allCost = allCost + (BuildHeatingModel.getYearCost(matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevPrice(), matchedDevice.getDeviceHeatScene().getDevServiceLife(), matchedDevice.getDeviceHeatScene().getDevPower(), days, matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost())); + calculateAnnualCarbon = calculateAnnualCarbon + (BuildHeatingModel.calculateAnnualCarbonReduction(lastYearFee, matchedDevice.getDeviceHeatScene().getLaborCost(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevPower(), days)); + electric = electric + (BuildHeatingModel.getElectric(matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevPower(), days)); + } + //初次投资费用 + returnJsonObject.set("startCost", decimalFormat.format(startCost)); + //年运行费用 + returnJsonObject.set("yearRunCost", decimalFormat.format(runCost)); + //年总费用 + returnJsonObject.set("yearCost", decimalFormat.format(allCost)); + //年减碳量 + returnJsonObject.set("calculate", decimalFormat.format(calculateAnnualCarbon)); + //替代电量 + returnJsonObject.set("electric", decimalFormat.format(electric)); + //备注 + returnJsonObject.set("remark",remark); + //封装需配置设备情况 + returnJsonObject.set("deviceList",deviceList); + + //封装方案优势 + returnJsonObject.set("safety", BuildHeatingAdvantage.safety()); + returnJsonObject.set("economy", BuildHeatingAdvantage.economy(startCost, allCost, runCost, lastYearFee)); + returnJsonObject.set("intelligence", BuildHeatingAdvantage.intelligence()); + returnJsonObject.set("environment", BuildHeatingAdvantage.environment(Double.valueOf(decimalFormat.format(calculateAnnualCarbon)))); + + //封装方案评分 + returnJsonObject.set("matchedDeviceList", maps); + + return returnJsonObject; + } +} diff --git a/dntd-tool/src/main/java/com/dky/generate/BuildHeatingSence.java b/dntd-tool/src/main/java/com/dky/generate/BuildHeatingSence.java deleted file mode 100644 index 0d497d5..0000000 --- a/dntd-tool/src/main/java/com/dky/generate/BuildHeatingSence.java +++ /dev/null @@ -1,154 +0,0 @@ -package com.dky.generate; - - -import cn.hutool.json.JSONObject; -import com.dky.calculate.*; -import com.dky.modelI.DntdModelI; -import com.dky.tool.ModelTool; -import com.dky.utils.entity.SysDeviceHeatScene; -import com.dky.utils.result.MatchedDevice; - -import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicReference; - -public class BuildHeatingSence implements DntdModelI { - - DecimalFormat decimalFormat = new DecimalFormat("#.00"); - - //首先A=由运行/合同容量折合成kW(x0.9)x85%, - static final Double COEFFICIENT_1 = 0.9; - static final Double COEFFICIENT_2 = 0.85; - - @Override - public JSONObject createReport(JSONObject jsonObject2) { - List list = ModelTool.specList; - JSONObject distInfo = (JSONObject) jsonObject2.get("distInfo"); - JSONObject buildInfo = (JSONObject) jsonObject2.get("buildInfo"); - System.out.println("时间: " + Integer.parseInt(buildInfo.get("days").toString())); - // 运行容量 - Double runCapacity = Double.parseDouble(distInfo.get("runCapacity").toString()); - // 上年最大需量 - Double lastYearNeed = Double.parseDouble(distInfo.get("lastYearNeed").toString()); - // 建筑面积 - Double heatingArea = Double.parseDouble(buildInfo.get("heatingArea").toString()); - // 年采暖时间(天) - Integer days = Integer.parseInt(buildInfo.get("days").toString()); - // 上年运行费用(万元) - Double lastYearFee = Double.parseDouble(buildInfo.get("lastYearFee").toString()); - - // A=由运行/合同容量折合成kW(x0.9)x85%, - Double A = runCapacity * COEFFICIENT_1 * COEFFICIENT_2; - // 冗余容量 - Double B = A - lastYearNeed; - //投入供热设备总功率C - AtomicReference C = new AtomicReference<>(); - //投入供热设备总功率C1 - AtomicReference C1 = new AtomicReference<>(); - List>>> calScheme = Scheme.calScheme(heatingArea, list); - List> mapsC = CalC.getC(calScheme); - for (Map map : mapsC) { - map.forEach((k, v) -> { - if (k.contains("电锅炉")) { - C.set(v); - System.out.println("C" + C.get()); - } else { - C1.set(v); - System.out.println("C1" + C1.get()); - } - }); - } - Double D = lastYearNeed + C.get(); - Double D1 = lastYearNeed + C1.get(); - - List matchedDeviceList; - Map> listMap; - Double costRatio = 0.2; - Double effRatio = 0.8; - //获取计算占比 - try{ - Double costRatio1 = Double.parseDouble(jsonObject2.get("costRatio").toString()); - Double effRatio1 = Double.parseDouble(jsonObject2.get("effRatio").toString()); - if(costRatio1 < 1 && costRatio1 + costRatio1 == 1){ - costRatio = costRatio1; - effRatio = effRatio1; - } - }catch (Exception e){ - e.printStackTrace(); - } - if (D1 < A && A < D) { - // 判断只能用热泵 - List deviceList = new ArrayList<>(); - list.parallelStream().forEach((sysDeviceHeatScene -> { - if (!sysDeviceHeatScene.getDevTechType().contains("电锅炉")) { - deviceList.add(sysDeviceHeatScene); - } - })); - listMap = SchemeRating.getOptimalList(Scheme.calScheme(heatingArea, deviceList),costRatio,effRatio); - matchedDeviceList = SchemeRating.getOptimalScheme(listMap); - } else { - listMap = SchemeRating.getOptimalList(calScheme,costRatio,effRatio); - matchedDeviceList = SchemeRating.getOptimalScheme(listMap); - } - - List> maps = new ArrayList<>(); - listMap.forEach((k,v)->{ - Map map = new HashMap<>(); - map.put("rating", decimalFormat.format(k)); - map.put("plan", v); - map.put("planName", v.get(0).getDeviceHeatScene().getDevTechType()); - maps.add(map); - }); - - JSONObject jsonObject = new JSONObject(); - Double startCost = 0.0; - Double runCost = 0.0; - Double allCost = 0.0; - Double calculateAnnualCarbon = 0.0; - Double electric = 0.0; - - - List> deviceList = new ArrayList<>(); - - //封装整体情况 - for (MatchedDevice matchedDevice : matchedDeviceList){ - HashMap map = new HashMap<>(); - map.put("devSubType",matchedDevice.getDeviceHeatScene().getDevSubType()); - map.put("devTechType",matchedDevice.getDeviceHeatScene().getDevTechType()); - map.put("devCount",matchedDevice.getCount()); - map.put("devPrice",matchedDevice.getDeviceHeatScene().getDevPrice()); - deviceList.add(map); - startCost = startCost + (matchedDevice.getCount() * matchedDevice.getDeviceHeatScene().getDevPrice()); - runCost = runCost + (BuildHeatingModel.getRunCost(matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevPower(), days, matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost())); - allCost = allCost + (BuildHeatingModel.getYearCost(matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevPrice(), matchedDevice.getDeviceHeatScene().getDevServiceLife(), matchedDevice.getDeviceHeatScene().getDevPower(), days, matchedDevice.getDeviceHeatScene().getDevSubstituteLaborCost())); - calculateAnnualCarbon = calculateAnnualCarbon + (BuildHeatingModel.calculateAnnualCarbonReduction(lastYearFee, matchedDevice.getDeviceHeatScene().getLaborCost(), matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevPower(), days)); - electric = electric + (BuildHeatingModel.getElectric(matchedDevice.getCount(), matchedDevice.getDeviceHeatScene().getDevPower(), days)); - } - //初次投资费用 - jsonObject.put("startCost", decimalFormat.format(startCost)); - //年运行费用 - jsonObject.put("yearRunCost", decimalFormat.format(runCost)); - //年总费用 - jsonObject.put("yearCost", decimalFormat.format(allCost)); - //年减碳量 - jsonObject.put("calculate", decimalFormat.format(calculateAnnualCarbon)); - //替代电量 - jsonObject.put("electric", decimalFormat.format(electric)); - //封装需配置设备情况 - jsonObject.put("deviceList",deviceList); - - //封装方案优势 - jsonObject.put("safety", BuildHeatingAdvantage.safety()); - jsonObject.put("economy", BuildHeatingAdvantage.economy(startCost, allCost, runCost, lastYearFee)); - jsonObject.put("intelligence", BuildHeatingAdvantage.intelligence()); - jsonObject.put("environment", BuildHeatingAdvantage.environment(Double.valueOf(decimalFormat.format(calculateAnnualCarbon)))); - - //封装方案评分 - jsonObject.put("matchedDeviceList", maps); - - return jsonObject; - } -} diff --git a/dntd-tool/src/main/java/com/dky/generate/HeatBoilerSence.java b/dntd-tool/src/main/java/com/dky/generate/HeatBoilerSence.java index ab8ae67..ce1fefe 100644 --- a/dntd-tool/src/main/java/com/dky/generate/HeatBoilerSence.java +++ b/dntd-tool/src/main/java/com/dky/generate/HeatBoilerSence.java @@ -5,13 +5,15 @@ import com.dky.calculate.Advantage; import com.dky.calculate.Overall; import com.dky.entity.Heatboiler; import com.dky.modelI.DntdModelI; +import com.dky.utils.entity.SysDeviceHeatScene; import java.util.HashSet; +import java.util.List; import java.util.Set; public class HeatBoilerSence implements DntdModelI { @Override - public JSONObject createReport(JSONObject jsonObject) { + public JSONObject createReport(JSONObject jsonObject, List alternateDeviceList) { JSONObject jsonReport = new JSONObject(); Heatboiler heatboiler = jsonObject.toBean(Heatboiler.class); // 生成报告 diff --git a/dntd-tool/src/main/java/com/dky/test/TestMain.java b/dntd-tool/src/main/java/com/dky/test/TestMain.java new file mode 100644 index 0000000..0681132 --- /dev/null +++ b/dntd-tool/src/main/java/com/dky/test/TestMain.java @@ -0,0 +1,126 @@ +package com.dky.test; + +import com.dky.calculate.Scheme; +import com.dky.calculate.SchemeRating; +import com.dky.utils.entity.SysDeviceHeatScene; +import com.dky.utils.result.MatchedDevice; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class TestMain { + + public static void main(String[] args) { + + List alternateDeviceList = createDevList(); + + // List> alternateDeviceList = calSchemeMethodTest(14000.0, devList); + + // getMaxEfficiencyGroupByDevSubTypeTest(alternateDeviceList); + // getMinPriceGroupByDevSubTypeTest(alternateDeviceList); + + /* + 根据建筑面积计算出不同技术类型下所需要不同功率设备数据 + */ + List> matchedDeviceGroupList = Scheme.calScheme(44000.0, alternateDeviceList); + + + /* + 判断计算占比,默认效率0.8,成本0.2 + */ + double costRatio = 0.2; + double effRatio = 0.8; + + + List matchedDeviceList ; + Map> listMap ; + /* + 根据具体容量与需量判断可使用的技术并计算评分 + */ + //计算不同细类下成本最小值与效率最大值 + Map maxEffMap = SchemeRating.getMaxEfficiencyGroupByDevSubType(alternateDeviceList); + Map minPriceMap = SchemeRating.getMinPriceGroupByDevSubType(alternateDeviceList); + listMap = SchemeRating.getOptimalList(matchedDeviceGroupList,costRatio,effRatio,maxEffMap,minPriceMap); + matchedDeviceList = SchemeRating.getOptimalScheme(listMap); + + } + + + public static List> calSchemeMethodTest(Double buildArea, List SysDeviceHeatSceneList) { + return Scheme.calScheme(buildArea, SysDeviceHeatSceneList); + + } + + public static void getMaxEfficiencyGroupByDevSubTypeTest(List sysDeviceHeatSceneList){ + SchemeRating.getMaxEfficiencyGroupByDevSubType(sysDeviceHeatSceneList); + } + + public static void getMinPriceGroupByDevSubTypeTest(List sysDeviceHeatSceneList){ + SchemeRating.getMinPriceGroupByDevSubType(sysDeviceHeatSceneList); + } + + public static ListcreateDevList(){ + List deviceList = new ArrayList<>(); + + // 模拟从数据库中检索数据 + Object[][] data = + { + {19, "电锅炉", "供冷/暖电锅炉", "直热式电锅炉(电阻类)", 0.95, 360.00, 80000.00, 60000.00, 180000.00, 3000.00, 15, null, null}, + {20, "电锅炉", "供冷/暖电锅炉", "直热式电锅炉(电阻类)", 0.95, 720.00, 100000.00, 60000.00, 180000.00, 6000.00, 15, null, null}, + {21, "电锅炉", "供冷/暖电锅炉", "直热式电锅炉(电阻类)", 0.95, 1440.00, 160000.00, 60000.00, 180000.00, 12000.00, 15, null, null}, + {22, "电锅炉", "供冷/暖电锅炉", "直热式电锅炉(电极类)", 0.97, 360.00, 280000.00, 60000.00, 180000.00, 3000.00, 15, null, null}, + {23, "电锅炉", "供冷/暖电锅炉", "直热式电锅炉(电极类)", 0.97, 720.00, 460000.00, 60000.00, 180000.00, 6000.00, 15, null, null}, + {24, "电锅炉", "供冷/暖电锅炉", "直热式电锅炉(电极类)", 0.97, 1440.00, 900000.00, 60000.00, 180000.00, 12000.00, 15, null, null}, + {25, "电锅炉", "供冷/暖电锅炉", "直热式电锅炉(电磁涡流类)", 0.98, 360.00, 150000.00, 60000.00, 180000.00, 3000.00, 15, null, null}, + {26, "电锅炉", "供冷/暖电锅炉", "直热式电锅炉(电磁涡流类)", 0.98, 720.00, 180000.00, 60000.00, 180000.00, 6000.00, 15, null, null}, + {27, "电锅炉", "供冷/暖电锅炉", "直热式电锅炉(电磁涡流类)", 0.98, 1440.00, 300000.00, 60000.00, 180000.00, 12000.00, 15, null, null}, + {28, "电锅炉", "供冷/暖电锅炉", "蓄热式电锅炉(固体蓄热)", 0.95, 360.00, 360000.00, 60000.00, 180000.00, 3000.00, 15, null, null}, + {29, "电锅炉", "供冷/暖电锅炉", "蓄热式电锅炉(固体蓄热)", 0.95, 720.00, 720000.00, 60000.00, 180000.00, 6000.00, 15, null, null}, + {30, "电锅炉", "供冷/暖电锅炉", "蓄热式电锅炉(固体蓄热)", 0.95, 1440.00, 1440000.00, 60000.00, 180000.00, 12000.00, 15, null, null}, + {31, "电锅炉", "供冷/暖电锅炉", "蓄热式电锅炉(相变蓄热)", 0.98, 360.00, 120000.00, 60000.00, 180000.00, 3000.00, 15, null, null}, + {32, "电锅炉", "供冷/暖电锅炉", "蓄热式电锅炉(相变蓄热)", 0.98, 720.00, 160000.00, 60000.00, 180000.00, 6000.00, 15, null, null}, + {33, "电锅炉", "供冷/暖电锅炉", "蓄热式电锅炉(相变蓄热)", 0.98, 1440.00, 280000.00, 60000.00, 180000.00, 12000.00, 15, null, null}, + {34, "电锅炉", "供冷/暖电锅炉", "蓄热式电锅炉(水蓄)", 0.97, 360.00, 110000.00, 60000.00, 180000.00, 3000.00, 15, null, null}, + {35, "电锅炉", "供冷/暖电锅炉", "蓄热式电锅炉(水蓄)", 0.97, 720.00, 150000.00, 60000.00, 180000.00, 6000.00, 15, null, null}, + {36, "电锅炉", "供冷/暖电锅炉", "蓄热式电锅炉(水蓄)", 0.97, 1440.00, 260000.00, 60000.00, 180000.00, 12000.00, 15, null, null}, + {37, "热泵", "供冷/暖", "水源热泵", 4.00, 25.00, 45000.00, 60000.00, 180000.00, 500.00, 15, null, null}, + {38, "热泵", "供冷/暖", "水源热泵", 4.00, 45.00, 75000.00, 60000.00, 180000.00, 1000.00, 15, null, null}, + {39, "热泵", "供冷/暖", "水源热泵", 4.00, 90.00, 140000.00, 60000.00, 180000.00, 2000.00, 15, null, null}, + {40, "热泵", "供冷/暖", "土壤源热泵", 4.00, 25.00, 45000.00, 60000.00, 180000.00, 500.00, 15, null, null}, + {41, "热泵", "供冷/暖", "土壤源热泵", 4.00, 45.00, 75000.00, 60000.00, 180000.00, 1000.00, 15, null, null}, + {42, "热泵", "供冷/暖", "土壤源热泵", 4.00, 90.00, 140000.00, 60000.00, 180000.00, 2000.00, 15, null, null}, + {43, "热泵", "供冷/暖", "空气源热泵", 4.00, 25.00, 45000.00, 60000.00, 180000.00, 500.00, 15, null, null}, + {44, "热泵", "供冷/暖", "空气源热泵", 4.00, 45.00, 75000.00, 60000.00, 180000.00, 1000.00, 15, null, null}, + {45, "热泵", "供冷/暖", "空气源热泵", 4.00, 90.00, 140000.00, 60000.00, 180000.00, 2000.00, 15, null, null}, + {46, "热泵", "供冷/暖", "低品位余热源(如电厂低温循环水)热泵", 4.00, 25.00, 45000.00, 60000.00, 180000.00, 500.00, 15, null, null}, + {47, "热泵", "供冷/暖", "低品位余热源(如电厂低温循环水)热泵", 4.00, 45.00, 75000.00, 60000.00, 180000.00, 1000.00, 15, null, null}, + {48, "热泵", "供冷/暖", "低品位余热源(如电厂低温循环水)热泵", 4.00, 90.00, 140000.00, 60000.00, 180000.00, 2000.00, 15, null, null}, + {49, "热泵", "供冷/暖", "高温蒸汽热泵", 3.00, 45.00, 380000.00, 60000.00, 180000.00, 1000.00, 15, null, null}, + {50, "热泵", "供冷/暖", "高温蒸汽热泵", 3.00, 120.00, 550000.00, 60000.00, 180000.00, 2000.00, 15, null, null}, + }; + + // 创建对象并添加到列表 + for (Object[] row : data) { + int id = (int) row[0]; + String devType = (String) row[1]; + String devSubType = (String) row[2]; + String devTechType = (String) row[3]; + double heatEfficiency = (double) row[4]; + double devPower = (double) row[5]; + double devPrice = (double) row[6]; + double devSubstituteLaborCost = (double) row[7]; + double laborCost = (double) row[8]; + double devReferenceArea = (double) row[9]; + int devServiceLife = (int) row[10]; + + SysDeviceHeatScene device = new SysDeviceHeatScene( + id, devType, devSubType, devTechType, heatEfficiency, devPower, devPrice, + devSubstituteLaborCost, laborCost, devReferenceArea, devServiceLife, null, null); + + deviceList.add(device); + } + return deviceList; + } + +} diff --git a/dntd-tool/src/main/java/com/dky/tool/ModelTool.java b/dntd-tool/src/main/java/com/dky/tool/ModelTool.java index 803a097..a3c65f1 100644 --- a/dntd-tool/src/main/java/com/dky/tool/ModelTool.java +++ b/dntd-tool/src/main/java/com/dky/tool/ModelTool.java @@ -8,6 +8,7 @@ import com.dky.utils.ConfigReader; import com.dky.utils.entity.SysDeviceHeatScene; import com.dky.utils.enums.Code; import com.dky.utils.result.ResponseUtil; +import org.bouncycastle.math.raw.Mod; import java.lang.reflect.InvocationTargetException; import java.text.SimpleDateFormat; @@ -18,17 +19,29 @@ import java.util.Map; public class ModelTool { - public static List specList = new ArrayList<>(); - // 制热锅炉,单功率单价,单位。建缓冲区。List实体。 - public ModelTool(JSONObject list) { + public List specList; + // 私有化构造方法,避免外部实例化 + private ModelTool() { + } + + public ModelTool(List specList) { + this.specList = specList; + } + + // 创建工具类的静态工厂方法 + public static ModelTool create(JSONObject list) { + List specList = new ArrayList<>(); JSONArray specArray = list.getJSONArray("devSpecList"); for (int i = 0; i < specArray.size(); i++) { SysDeviceHeatScene devSpec = specArray.getJSONObject(i).toBean(SysDeviceHeatScene.class); specList.add(devSpec); } + return new ModelTool(specList); } - public static JSONObject exeModel2Report(JSONObject jsonObject, String key) { + + + public JSONObject exeModel2Report(JSONObject jsonObject, String key) { JSONObject jsonObjectResult = new JSONObject(); try { // 根据给定的类名初始化类 加密不需要反实例化new @@ -48,11 +61,11 @@ public class ModelTool { if (new Date().before(date)){ // 判断模型使用权限 // 根据给定的类名初始化类 加密不需要反实例化new - Class modelI = Class.forName("com.dky"+"."+ ConfigReader.getProperty(jsonObject.getStr("type"))); + Class buildHeatingScene = Class.forName("com.dky"+"."+ ConfigReader.getProperty(jsonObject.getStr("type"))); // 实例化这个类 - DntdModelI modelI1 = (DntdModelI)modelI.newInstance(); + DntdModelI buildHeatingSceneModel = (DntdModelI)buildHeatingScene.newInstance(); // 调用指定方法 - jsonObjectResult = modelI1.createReport(jsonObject); + jsonObjectResult = buildHeatingSceneModel.createReport(jsonObject,this.specList); }else { jsonObjectResult = ResponseUtil.createResponse(Code.KEY_EXPIRATION.getCode(), Code.KEY_EXPIRATION.getDesc(), null); }