From 277c0b7b79a24c20e8779b2224559bcd6ccad979 Mon Sep 17 00:00:00 2001 From: fujie <405295521@qq.com> Date: Sun, 27 Aug 2017 19:24:03 +0800 Subject: [PATCH] =?UTF-8?q?1.=E4=BF=AE=E6=94=B9eval=E6=94=AF=E6=8C=81strin?= =?UTF-8?q?g=E5=8F=82=E6=95=B0=E6=88=96lambda=E7=B1=BB=E5=9E=8B=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E3=80=822.=E5=A2=9E=E5=8A=A0=E4=B8=A4=E4=B8=AA?= =?UTF-8?q?=E8=83=8C=E5=8C=85=E7=A4=BA=E4=BE=8B=E3=80=823.=E4=BC=98?= =?UTF-8?q?=E5=8C=96dpKnapSack=E7=9B=B8=E5=85=B3=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E3=80=824.=E5=AE=8C=E5=96=84=E5=AE=9E=E4=BE=8B=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../function/list/DpKnapsackFunction.java | 10 ------- .../function/DataSetKnapsackFunction.java | 12 -------- .../resources/example/dataSetDpKnapsack.ts | 21 +++++++++----- .../src/test/resources/example/dpFund.ts | 4 +-- .../src/test/resources/example/dpShopping.ts | 12 ++++---- .../src/test/resources/example/question1.ts | 15 ++++++++++ .../src/test/resources/example/question2.ts | 29 +++++++++++++++++++ .../function/AbstractDpKnapsackFunction.java | 24 ++++++++++++--- .../function/EvalScriptFunction.java | 26 ++++++++++------- 9 files changed, 101 insertions(+), 52 deletions(-) create mode 100644 org.tinygroup.tinyscript/src/test/resources/example/question1.ts create mode 100644 org.tinygroup.tinyscript/src/test/resources/example/question2.ts diff --git a/org.tinygroup.tinyscript.collection/src/main/java/org/tinygroup/tinyscript/collection/function/list/DpKnapsackFunction.java b/org.tinygroup.tinyscript.collection/src/main/java/org/tinygroup/tinyscript/collection/function/list/DpKnapsackFunction.java index a16e7ae..401913f 100644 --- a/org.tinygroup.tinyscript.collection/src/main/java/org/tinygroup/tinyscript/collection/function/list/DpKnapsackFunction.java +++ b/org.tinygroup.tinyscript.collection/src/main/java/org/tinygroup/tinyscript/collection/function/list/DpKnapsackFunction.java @@ -136,14 +136,4 @@ public class DpKnapsackFunction extends AbstractDpKnapsackFunction { return obj; } - @Override - protected boolean executePrune(LambdaFunction pruneFunction, ScriptContext context, Object... parameters) - throws ScriptException { - try { - return (Boolean) (pruneFunction.execute(context, parameters).getResult()); - } catch (Exception e) { - throw new ScriptException("剪枝函数执行异常", e); - } - } - } diff --git a/org.tinygroup.tinyscript.dataset/src/main/java/org/tinygroup/tinyscript/dataset/function/DataSetKnapsackFunction.java b/org.tinygroup.tinyscript.dataset/src/main/java/org/tinygroup/tinyscript/dataset/function/DataSetKnapsackFunction.java index 1a42785..ac1072d 100644 --- a/org.tinygroup.tinyscript.dataset/src/main/java/org/tinygroup/tinyscript/dataset/function/DataSetKnapsackFunction.java +++ b/org.tinygroup.tinyscript.dataset/src/main/java/org/tinygroup/tinyscript/dataset/function/DataSetKnapsackFunction.java @@ -153,16 +153,4 @@ public class DataSetKnapsackFunction extends AbstractDpKnapsackFunction { return lastResult; } - @Override - protected boolean executePrune(LambdaFunction pruneFunction, ScriptContext context, Object... parameters) - throws ScriptException { - try { - int i = (Integer) parameters[1] + 1; - int bagSize = (Integer) parameters[2]; - return (Boolean) (pruneFunction.execute(context, i, bagSize).getResult()); - } catch (Exception e) { - throw new ScriptException("剪枝函数执行异常", e); - } - } - } diff --git a/org.tinygroup.tinyscript/src/test/resources/example/dataSetDpKnapsack.ts b/org.tinygroup.tinyscript/src/test/resources/example/dataSetDpKnapsack.ts index 0d3897c..fd46563 100644 --- a/org.tinygroup.tinyscript/src/test/resources/example/dataSetDpKnapsack.ts +++ b/org.tinygroup.tinyscript/src/test/resources/example/dataSetDpKnapsack.ts @@ -2,10 +2,12 @@ dataSet = readTxt("/example/knapsack1.txt"); dataSet = dataSet.double("value").int("weight").int("count"); //================================================================================ //01背包 -println(dataSet.dpKnapsack(10,dataSet.weight,1,dataSet.value)); +bagSize = 10; +println(dataSet.dpKnapsack(bagSize,dataSet.weight,1,dataSet.value));//1表示所有物品的最大份数都为1 //完全背包 -println(dataSet.dpKnapsack(10,dataSet.weight,dataSet.value)); +bagSize = 10; +println(dataSet.dpKnapsack(bagSize,dataSet.weight,dataSet.value)); //================================================================================ @@ -13,22 +15,24 @@ dataSet = readTxt("/example/knapsack2.txt"); dataSet = dataSet.double("value").int("weight","count"); //================================================================================ //多重背包 -println(dataSet.dpKnapsack(15,dataSet.weight,dataSet.count,dataSet.value)); +bagSize = 15; +println(dataSet.dpKnapsack(bagSize,dataSet.weight,dataSet.count,dataSet.value)); dataSet = readTxt("/example/knapsack3.txt"); dataSet = dataSet.double("value").int("weight","count"); //================================================================================ //混合背包 -println(dataSet.dpKnapsack(15,dataSet.weight,dataSet.count,dataSet.value)); +bagSize = 15; +println(dataSet.dpKnapsack(bagSize,dataSet.weight,dataSet.count,dataSet.value)); //基金问题 dataSet = readTxt("/example/knapsack4.txt"); dataSet = dataSet.int("minmoney","maxmoney").double("interestRate"); dataSet.insertColumn(1,"value").insertColumn(2,"count").double("value").int("count"); -dataSet.update("value",interestRate[0]*minmoney[0]*80); -dataSet.update("count",maxmoney[0]/minmoney[0]); +dataSet.update("value",interestRate[0]*minmoney[0]*80);//计算基金实际收益 +dataSet.update("count",maxmoney[0]/minmoney[0]);//根据基金的可购买的最大份额和最小份额算出最大的份数 //================================================================================ println(dataSet.dpKnapsack(5000,dataSet.minmoney,dataSet.count,dataSet.value)); @@ -37,9 +41,10 @@ println(dataSet.dpKnapsack(5000,dataSet.minmoney,dataSet.count,dataSet.value)); dataSet = readTxt("/example/knapsack5.txt"); dataSet = dataSet.int("price","importance","rule"); dataSet.insertColumn(1,"value").double("value"); -dataSet.update("value",price[0]*importance[0]); +dataSet.update("value",price[0]*importance[0]);//计算每件物品的实际价值(重要度*价格) //================================================================================ -println(dataSet.dpKnapsack(1000,dataSet.price,1,dataSet.value,(i,money)->{ +money = 1000; +println(dataSet.dpKnapsack(money,dataSet.price,1,dataSet.value,()->{ if(rule[i] == 0){ if( price[i] <= money){ return true; diff --git a/org.tinygroup.tinyscript/src/test/resources/example/dpFund.ts b/org.tinygroup.tinyscript/src/test/resources/example/dpFund.ts index 0935e08..50ca50b 100644 --- a/org.tinygroup.tinyscript/src/test/resources/example/dpFund.ts +++ b/org.tinygroup.tinyscript/src/test/resources/example/dpFund.ts @@ -1,5 +1,5 @@ class Product{ - name,amountPerServing ,maxCount,rate; + name,amountPerServing ,maxCount,rate;//name:基金名字 amountPerServing:一份的价格 maxCount:最大份数 rate:利率 Product(name,amountPerServing,maxCount,rate){ } } @@ -8,5 +8,5 @@ class Product{ days=80; list=[new Product("鹏华国防",100,10,0.00045),new Product("鹏华中证",100,20,0.00035),new Product("国投瑞银",100,20,0.00055),new Product("华商主题精选",100,10,0.0004),new Product("金鹰智慧",100,5,0.0003)]; println(list.dpKnapsack(5000,list.amountPerServing,list.maxCount,()->{ - return [0.00045,0.00035,0.00055,0.00040,0.00030]*days*100; + return [0.00045,0.00035,0.00055,0.00040,0.00030]*days*100;//每个基金的总收益由利率*时间*一份价格算出 })); \ No newline at end of file diff --git a/org.tinygroup.tinyscript/src/test/resources/example/dpShopping.ts b/org.tinygroup.tinyscript/src/test/resources/example/dpShopping.ts index baa6780..799a7bf 100644 --- a/org.tinygroup.tinyscript/src/test/resources/example/dpShopping.ts +++ b/org.tinygroup.tinyscript/src/test/resources/example/dpShopping.ts @@ -2,19 +2,19 @@ 为了不超出预算,他把每件物品规定了一个重要度,分为 5 等:用整数 1 ~ 5 表示,如果要买归类为附件的物品,必须先买该附件所属的主件(0表示物品)。 在不超过 N 元(可以等于 N 元)的前提下,使每件物品的价格与重要度的乘积的总和最大。*/ class Goods{ - name,price,value,rule; + name,price,value,rule;//name:商品名字 price:商品价格 value:商品价值(根据题意由重要度*价格算出) rule:标记物品或者附件(0表示物品,其他数字表示是该数字对应物品的附件) Goods(name,price,value,rule){ } } -list=[new Goods("电脑",800,1600.0,0),new Goods("打印机",400,2000.0,1),new Goods("扫描仪",300,1500.0,1),new Goods("书柜",400,1200.0,0),new Goods("书桌",500,1000.0,0)]; +list=[new Goods("电脑",800,2*800,0),new Goods("打印机",400,5*400.0,1),new Goods("扫描仪",300,5*300,1),new Goods("书柜",400,3*400,0),new Goods("书桌",500,2*500,0)]; money = 1000; -result = list.dpKnapsack(money,list.price,1,list.value,(ele,i,money)->{ - if(ele.get(i).rule ==0){ - if(ele.get(i).price<=money){ +result = list.dpKnapsack(money,list.price,1,list.value,()->{ + if(list.get(i-1).rule ==0){ + if(list.get(i-1).price<=money){//如果该物品的价格低于当前钱数表示可以购买 return true; } }else{ - if(ele.get(i).price+ele.get(ele.get(i).rule-1).price<=money){ + if(list.get(i-1).price+list.get(list.get(i-1).rule-1).price<=money){//如果该附件加附件对应的物品一共的价格低于当前钱数则表示可以购买 return true; } } diff --git a/org.tinygroup.tinyscript/src/test/resources/example/question1.ts b/org.tinygroup.tinyscript/src/test/resources/example/question1.ts new file mode 100644 index 0000000..ee87cd0 --- /dev/null +++ b/org.tinygroup.tinyscript/src/test/resources/example/question1.ts @@ -0,0 +1,15 @@ +/*在n个物品中挑选若干物品装入背包,最多能装多满?假设背包的大小为bagSize,每个物品的大小为weight[i]*/ +class Obj{ + name,weight,value; + Obj(name,weight,value){ + } +} +//根据题目,本题的最大价值实际上就是最大容量,所以value和weight是相等的。 +list=[new Obj("a",2,2),new Obj("b",3,3),new Obj("c",5,5),new Obj("d",7,7)]; +bagSize = 12; +println("装满背包问题:\n"+list.dpKnapsack(bagSize,list.weight,1,list.value,()->{ + if(resultArray[i][v]<=bagSize){//判断是否超出容量 + return true; + } + return false; +})); \ No newline at end of file diff --git a/org.tinygroup.tinyscript/src/test/resources/example/question2.ts b/org.tinygroup.tinyscript/src/test/resources/example/question2.ts new file mode 100644 index 0000000..182a98a --- /dev/null +++ b/org.tinygroup.tinyscript/src/test/resources/example/question2.ts @@ -0,0 +1,29 @@ +/*给一个整数数组,调整每个数的大小,使得相邻的两个数的差不大于一个给定的整数target,调整每个数的代价为调整前后的差的绝对值,求调整代价之和最小是多少。 + 注意事项:你可以假设数组中每个整数都是正整数,且小于等于100。*/ + +//样例 对于数组[1, 4, 2, 3]和target=1。求调整代价之和最小。 +class Obj{ + weight,value; + Obj(weight,value){ + } +} +//因为本题没有实际的weight,将weight初始化为1,value表示实际的数值。 +list=[new Obj(1,1),new Obj(1,4),new Obj(1,2),new Obj(1,3)]; +count = list.size(); +bagSize = 100; +target = 1; +list.dpKnapsack(bagSize,list.weight,100,list.value,()->{ + if(resultArray[i][v] == 0){ + resultArray[i][v] = Integer.MAX_VALUE;//因为这里是求最小值,所以二维表需要初始化最大。 + } + if(k>=max(v-target,1)&&k<=max(v+target,100)){ + resultArray[i][v] = min(resultArray[i][v],resultArray[i-1][k]+abs(list.get(i-1).value-v)); + return false; + } + return false; +}); +result = Integer.MAX_VALUE; +for (i = 1; i <= 100; i++) { + result = min(result, resultArray[count][i]); +} +println("调整代价之和:"+result); \ No newline at end of file diff --git a/org.tinygroup.tinyscriptbase/src/main/java/org/tinygroup/tinyscript/function/AbstractDpKnapsackFunction.java b/org.tinygroup.tinyscriptbase/src/main/java/org/tinygroup/tinyscript/function/AbstractDpKnapsackFunction.java index 12780a8..bf7b773 100644 --- a/org.tinygroup.tinyscriptbase/src/main/java/org/tinygroup/tinyscript/function/AbstractDpKnapsackFunction.java +++ b/org.tinygroup.tinyscriptbase/src/main/java/org/tinygroup/tinyscript/function/AbstractDpKnapsackFunction.java @@ -10,7 +10,7 @@ import org.tinygroup.tinyscript.ScriptException; import org.tinygroup.tinyscript.interpret.LambdaFunction; public abstract class AbstractDpKnapsackFunction extends DynamicNameScriptFunction { - + @Override public boolean exsitFunctionName(String name) { if (name.equals("dpKnapsack")) @@ -30,6 +30,7 @@ public abstract class AbstractDpKnapsackFunction extends DynamicNameScriptFuncti List list = new ArrayList(); Collections.addAll(list, items); list.set(0, result[weight.length - 1][bagSize]); + return list; } @@ -52,10 +53,12 @@ public abstract class AbstractDpKnapsackFunction extends DynamicNameScriptFuncti */ private void dpKnapsackResult(double result[][], int types, int bagSize, int[] weight, int[] maxCount, double value[], Object... parameters) throws Exception { + ScriptContext context = null; LambdaFunction pruneFunction = null; if (parameters.length > 0) { context = (ScriptContext) parameters[1]; + context.getParent().put("resultArray", result); pruneFunction = (LambdaFunction) parameters[2]; } @@ -70,8 +73,13 @@ public abstract class AbstractDpKnapsackFunction extends DynamicNameScriptFuncti result[i][v] = 0; int nCount = Math.min(maxCount[i], v / weight[i]); for (int k = 0; k <= nCount; k++) { + if (context != null) { + context.put("i", i); + context.put("v", v); + context.put("k", k); + } if (parameters.length > 0) { - if (executePrune(pruneFunction, context, parameters[0], i - 1, bagSize))// 用户自定义剪枝的情况 + if (executePrune(pruneFunction, context))// 用户自定义剪枝的情况 result[i][v] = Math.max(result[i][v], result[i - 1][v - k * weight[i]] + k * value[i]); } else result[i][v] = Math.max(result[i][v], result[i - 1][v - k * weight[i]] + k * value[i]); @@ -146,12 +154,20 @@ public abstract class AbstractDpKnapsackFunction extends DynamicNameScriptFuncti } return (int[]) maxCount; } + + protected boolean executePrune(LambdaFunction pruneFunction, ScriptContext context) + throws ScriptException { + try { + return (Boolean) (pruneFunction.execute(context).getResult()); + } catch (Exception e) { + throw new ScriptException("剪枝函数执行异常", e); + } + } abstract protected List getLastResult(List result, Object obj) throws ScriptException; abstract protected Object convertToArray(Object array, Class clazz) throws ScriptException; - abstract protected boolean executePrune(LambdaFunction pruneFunction, ScriptContext context, Object... parameters) - throws ScriptException; + } diff --git a/org.tinygroup.tinyscriptbase/src/main/java/org/tinygroup/tinyscript/function/EvalScriptFunction.java b/org.tinygroup.tinyscriptbase/src/main/java/org/tinygroup/tinyscript/function/EvalScriptFunction.java index 1552234..b5b1418 100644 --- a/org.tinygroup.tinyscriptbase/src/main/java/org/tinygroup/tinyscript/function/EvalScriptFunction.java +++ b/org.tinygroup.tinyscriptbase/src/main/java/org/tinygroup/tinyscript/function/EvalScriptFunction.java @@ -3,33 +3,39 @@ package org.tinygroup.tinyscript.function; import org.tinygroup.tinyscript.ScriptContext; import org.tinygroup.tinyscript.ScriptException; import org.tinygroup.tinyscript.ScriptSegment; +import org.tinygroup.tinyscript.interpret.LambdaFunction; /** * 动态执行脚本 + * * @author yancheng11334 * */ -public class EvalScriptFunction extends AbstractScriptFunction{ +public class EvalScriptFunction extends AbstractScriptFunction { public String getNames() { return "eval"; } - public Object execute(ScriptSegment segment, ScriptContext context, - Object... parameters) throws ScriptException { - try{ + public Object execute(ScriptSegment segment, ScriptContext context, Object... parameters) throws ScriptException { + try { if (parameters == null || parameters.length == 0) { throw new ScriptException(String.format("%s函数的参数为空!", getNames())); - }else if(checkParameters(parameters, 1)){ - String script = (String) parameters[0]; - return getScriptEngine().execute(convertExpression(script), context); - }else { + } else if (checkParameters(parameters, 1)) { + if (parameters[0] instanceof String) { + String script = (String) parameters[0]; + return getScriptEngine().execute(convertExpression(script), context); + } + + LambdaFunction pruneFunction = (LambdaFunction) parameters[0]; + return pruneFunction.execute(context).getResult(); + } else { throw new ScriptException(String.format("%函数的参数格式不正确!", getNames())); } - }catch (ScriptException e) { + } catch (ScriptException e) { throw e; } catch (Exception e) { - throw new ScriptException(String.format("%s函数执行发生异常:", getNames()),e); + throw new ScriptException(String.format("%s函数执行发生异常:", getNames()), e); } } -- Gitee