兴起解的一道题

来源:互联网 发布:东方财富软件ddx 编辑:程序博客网 时间:2024/04/29 17:55

兴起解的一道题,留代码纪念。

我认为每次保证截取完的绳子剩余长度最短就是最节省材料的截法

结果还有待验证。

 

问题:

标准绳子的长度=15M,用这个绳子来截取A,B,C三种绳子

A,B,C绳子长度为变量,断绳不能再接

求:截取m个A,n个B,p个C最节省材料的截取法

 

 

主要逻辑

Java code
/** * 最节省材料算法 * @deprecated 最短剩余确保法则 * @author oushuuryuu */class CaculateBestCutting { private int _baseLength; //标准绳子长度 /** * 构造函数 * @param baseLength 标准绳子长度 */ public CaculateBestCutting(int baseLength) { this._baseLength = baseLength; } /** * 所需最少根数取得 * @param lenA A绳的长度 * @param cntA A绳的数量 * @param lenB B绳的长度 * @param cntB B绳的数量 * @param lenC C绳的长度 * @param cntC C绳的数量 * @return */ public int getMinLinesCount(int lenA, int cntA,int lenB,int cntB,int lenC,int cntC) { int minCount = 0; //所需要标准绳子的长度 int currentLineLen = 0; //当前绳子的长度 int totalWastedLen = 0; //剩余绳子长度 System.out.println("绳子截取开始"); System.out.println("绳子A:长度=" + lenA + " " + "数量=" + cntA); System.out.println("绳子B:长度=" + lenB + " " + "数量=" + cntB); System.out.println("绳子C:长度=" + lenC + " " + "数量=" + cntC); //到绳子全部截取完为止做下面的处理 while (cntA + cntB + cntC > 0) { int paramLenA = cntA>0?lenA:_baseLength + 1; int paramLenB = cntB>0?lenB:_baseLength + 1; int paramLenC = cntC>0?lenC:_baseLength + 1; int cutIndex = getCuttingIndex(currentLineLen, paramLenA, paramLenB, paramLenC); switch (cutIndex) { case 0: //截取绳子A currentLineLen -= lenA; cntA--; System.out.println("截取A绳 剩余长度=" + currentLineLen); break; case 1: //截取绳子B currentLineLen -= lenB; cntB--; System.out.println("截取B绳 剩余长度=" + currentLineLen); break; case 2: //截取绳子C currentLineLen -= lenC; cntC--; System.out.println("截取C绳 剩余长度=" + currentLineLen); break; default: //剩余长度不够截取 totalWastedLen += currentLineLen; currentLineLen = _baseLength; minCount++; System.out.println("取标准绳子 绳子番号=" + minCount); break; } } System.out.println("绳子截取完成"); System.out.println("所需标准绳子条数=" + minCount + " " + "边角料长度=" + totalWastedLen); return minCount; } /** * 取得应该截取的绳子 * @param currentLen 剩余绳子的长度 * @param lenA A绳的长度 * @param lenB B绳的长度 * @param lenC C绳的长度 * @return -1:截取不可 0:截取A绳 1:截取B绳 2:截取C绳 */ private int getCuttingIndex(int currentLen, int lenA, int lenB, int lenC) { int index = -1; //绳子长度由小到大排序 TreeMap<Integer,Integer> sortMap = new TreeMap<Integer,Integer>(); sortMap.put(lenA, 0); sortMap.put(lenB, 1); sortMap.put(lenC, 2); if (sortMap.containsKey(currentLen)) { index = sortMap.get(currentLen); } else { //比currentLen小的最大键值的map取得 Entry<Integer,Integer> targetMap = sortMap.lowerEntry(currentLen); if (targetMap != null) { index = targetMap.getValue(); } } return index; }}


测试代码 用问题1代入的
Java code
//绳子截取测试 问1的情况 int baseLength = 15;//绳子标准长度 int lenA = 15; //A绳子长度 int cntA = 0; //所需A绳子数量 int lenB = 7; //B绳子长度 int cntB = 6; //所需B绳子数量 int lenC = 5; //C绳子长度 int cntC = 6; //所需C绳子数量 CaculateBestCutting cutLines = new CaculateBestCutting(baseLength); int cntBase = cutLines.getMinLinesCount(lenA, cntA, lenB, cntB, lenC, cntC); System.out.println("所需标准绳子条数=" + cntBase);