From fddafaec09a19beb5643a2245cd4f78eae3929f3 Mon Sep 17 00:00:00 2001 From: axapaxa123 <49201376+axapaxa123@users.noreply.github.com> Date: Wed, 3 Apr 2019 14:39:29 +0200 Subject: [PATCH 1/6] Update remove.js --- routes/api/remove.js | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/routes/api/remove.js b/routes/api/remove.js index 23476749..83f334b2 100644 --- a/routes/api/remove.js +++ b/routes/api/remove.js @@ -4,14 +4,17 @@ const doleNN = require("./../../lib/dole_nn_base.js") class neuralDole { constructor({ - items, + items, gauge }){ // Set some storage variables for the dole divider + this.prometheusDoleFactorGauge = gauge this.items = items this.itemsLastTick = JSON.parse(JSON.stringify(items)) this.dole = {} this.carry = {} this.lastRequest = {} + this.doleinfo_last = {} + this.doleinfo_new = {} setInterval(()=>{ for(let name in this.items){ @@ -22,10 +25,15 @@ class neuralDole { let magicData = doleNN.Tick( count, this.dole[name], - this.itemsLastTick[name] + this.itemsLastTick[name], + this.doleinfo_last[name] || {numreq:0 , numslave:0}, + this.doleinfo_new[name] || {numreq:0 , numslave:0} ) this.dole[name] = magicData[0] - // TODO handle magicData[1] for graphing for our users + // DONE handle magicData[1] for graphing for our users + this.prometheusDoleFactorGauge.labels(name).set(magicData[1] || 0); + this.doleinfo_last[name]=this.doleinfo_new[name] + this.doleinfo_new[name]={numreq:0 , numslave:0} } this.itemsLastTick = JSON.parse(JSON.stringify(this.items)) }, 1000) @@ -42,15 +50,20 @@ class neuralDole { this.items[object.name], this.itemsLastTick[object.name] || 0, this.dole[object.name], - this.carry[object.name] || 0, - this.lastRequest[object.name+"_"+object.instanceID+"_"+object.instanceName] || 0 + this.carry[object.name+" "+object.instanceID] || 0, + this.lastRequest[object.name+"_"+object.instanceID+"_"+object.instanceName] || 0, + this.doleinfo_last[object.name] || {numreq:0 , numslave:0} ) this.lastRequest[object.name+"_"+object.instanceID+"_"+object.instanceName] = object.count //0.Number of items to give in that dose //1.New dole for item X //2.New carry for item X slave Y this.dole[object.name] = magicData[1] - this.carry[object.name] = magicData[2] + this.carry[object.name+" "+object.instanceID] = magicData[2] + + this.doleinfo_new[object.name].numreq=magicData[0] + (this.doleinfo_new[object.name].numreq || 0) + this.doleinfo_new[object.name].numslave=1 + (this.doleinfo_new[object.name].numslave || 0) + // Remove item from DB and send it if(this.items.removeItem({count: magicData[0], name: object.name})){ if(config.logItemTransfers){ @@ -96,7 +109,7 @@ function doleDivider({ prometheusImportGauge, req,res, }){ - const doleDivisionRetardation = 10; //lower rates will equal more dramatic swings + const doleDivisionRetardation = 10; //lower rates will equal more dramatic swings const maxDoleDivision = 250; //a higher cap will divide the store more ways, but will take longer to recover as supplies increase const originalCount = Number(object.count) || 0; @@ -143,4 +156,4 @@ function doleDivider({ module.exports = { doleDivider, neuralDole -} \ No newline at end of file +} From 7d2ac5808fccfb11c649bd5204bf8728a87efb68 Mon Sep 17 00:00:00 2001 From: axapaxa123 <49201376+axapaxa123@users.noreply.github.com> Date: Wed, 3 Apr 2019 14:40:11 +0200 Subject: [PATCH 2/6] Update dole_nn_base.js --- lib/dole_nn_base.js | 107 +++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 62 deletions(-) diff --git a/lib/dole_nn_base.js b/lib/dole_nn_base.js index ace6650c..0aeaf97c 100644 --- a/lib/dole_nn_base.js +++ b/lib/dole_nn_base.js @@ -32,69 +32,43 @@ function sigmoid3(x) //dole - Current dole for item X //carry - carry for item X slave Y //prev_req - Numreq for previous request for item X slave Y +//* doleinfo_last - Object with 2 values for last "tick period": numreq - total number or requests for item, numslave - number of slaves requesting that item //Returns: Array of 3 elements //0.Number of items to give in that dose //1.New dole for item X //2.New carry for item X slave Y -function Dose(numreq,instore,store_last_tick,dole,carry,prev_req) +function Dose(numreq,instore,store_last_tick,dole,carry,prev_req,doleinfo_last) { - var inputs=[numreq,instore,store_last_tick,dole,carry,prev_req]; + var instore_adj=instore; + if (instore_adj==0) instore_adj=0.1; + var numreq_total_adj=doleinfo_last.numreq; + if (numreq_total_adj==0) numreq_total_adj=0.1; + + var a=(doleinfo_last.numslave)*numreq; + if (a>0) {a=(doleinfo_last.numreq)/a;} else {a=1000;} + var b=Math.trunc(prev_req/instore_adj*numreq); + var inputs=[numreq,instore_adj,store_last_tick/numreq,dole,carry,prev_req/numreq,doleinfo_last.numslave,numreq/numreq_total_adj,a,store_last_tick/numreq_total_adj,prev_req/instore,b]; var internal=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; - var outputs=[0,0]; + var outputs=[0,0,0]; //NN: Please don't touch :), code is generated -internal[1]=internal[8]*-1.643964648; -internal[1]=internal[1]+internal[3]*1.475263; -internal[1]=internal[1]+internal[10]*1.137161493; -internal[1]=internal[1]+1.0*0.581692636; -internal[1]=internal[1]+inputs[3]*-0.7429554462; -internal[1]=internal[1]+inputs[1]*-4.860008717; -internal[1]=internal[1]+inputs[0]*0.8682486415; -internal[1]=internal[1]+inputs[5]*-2.332767725; -internal[1]=sigmoid0(internal[1]); -internal[2]=internal[1]*0.8746165037; -internal[2]=sigmoid0(internal[2]); -internal[3]=inputs[0]*-5.502003193; -internal[3]=internal[3]+inputs[4]*0.2463098913; -internal[3]=internal[3]+inputs[5]*2.313313961; -internal[3]=internal[3]+1.0*-0.3230940998; -internal[3]=internal[3]+inputs[3]*-0.7781001329; -internal[3]=internal[3]+inputs[2]*7.295908451; -internal[3]=sigmoid0(internal[3]); -internal[6]=internal[1]*1.406680346; -internal[6]=internal[6]+inputs[3]*0.5068955421; -internal[6]=internal[6]+inputs[1]*-0.4729067087; -internal[6]=internal[6]+inputs[2]*0.8344552517; -internal[6]=internal[6]+inputs[0]*2.739265203; -internal[6]=sigmoid0(internal[6]); -internal[7]=inputs[0]*-0.9354650974; -internal[7]=internal[7]+inputs[5]*1.853131294; -internal[7]=internal[7]+inputs[2]*-0.5912416577; -internal[7]=internal[7]+inputs[1]*1.000927806; -internal[7]=sigmoid0(internal[7]); -internal[8]=1.0*-2.179960728; -internal[8]=internal[8]+inputs[1]*1.66548419; -internal[8]=internal[8]+inputs[0]*1.550180197; -internal[8]=sigmoid0(internal[8]); -internal[10]=inputs[2]*1.491255403; -internal[10]=internal[10]+1.0*1.035691857; -internal[10]=sigmoid0(internal[10]); -outputs[0]=inputs[2]*0.5093510151; -outputs[0]=outputs[0]+inputs[4]*0.9384511113; -outputs[0]=outputs[0]+outputs[1]*-3.595440626; -outputs[0]=sigmoid1(outputs[0]); -outputs[1]=inputs[2]*1.534054637; -outputs[1]=outputs[1]+internal[2]*-2.732098818; -outputs[1]=outputs[1]+outputs[2]*1.163635135; -outputs[1]=outputs[1]+internal[1]*-0.2005333602; -outputs[1]=outputs[1]+internal[6]*0.6757783294; +internal[11]=inputs[1]*2.584747791; +internal[11]=internal[11]+inputs[4]*0.9939581156; +internal[11]=internal[11]+inputs[5]*-0.5315227509; +internal[11]=internal[11]+inputs[3]*0.2037106603; +internal[11]=internal[11]+inputs[2]*1.38696003; +internal[11]=internal[11]+inputs[6]*-0.5434055328; +internal[11]=internal[11]+inputs[8]*-0.4344435036; +internal[11]=internal[11]+1.0*-1.461762667; +internal[11]=sigmoid0(internal[11]); +outputs[0]=inputs[0]*0.4289886355; +outputs[0]=outputs[0]+internal[11]*1.96782124; +outputs[0]=outputs[0]+inputs[3]*-2.196558237; +outputs[0]=sigmoid3(outputs[0]); +outputs[1]=outputs[0]*3.200549364; +outputs[1]=outputs[1]+inputs[7]*-0.3701510429; outputs[1]=sigmoid0(outputs[1]); -outputs[2]=1.0*-0.9311643243; -outputs[2]=outputs[2]+inputs[1]*-1.85346806; -outputs[2]=outputs[2]+inputs[2]*-1.232177019; -outputs[2]=outputs[2]+inputs[0]*1.937278271; -outputs[2]=outputs[2]+internal[7]*-0.728112638; outputs[2]=sigmoid0(outputs[2]); if (outputs[0]<0) outputs[0]=0; @@ -103,7 +77,7 @@ outputs[2]=sigmoid0(outputs[2]); if (res1>numreq) res1=numreq; if (res1>instore) res1=instore; if (res1<0) res1=0; - carry=outputs[2]+outputs[0]-res1; + carry=outputs[2]; return [res1,outputs[1],carry]; } @@ -111,29 +85,38 @@ outputs[2]=sigmoid0(outputs[2]); //Instore - number of items for item X in master gauge (currently) //dole - Current dole for item X //store_last_tick - Number of items for item X in master gauge at time of last tick (not this one) +//* doleinfo_last - Object with 2 values for last "tick period": numreq - total number or requests for item, numslave - number of slaves requesting that item +//* doleinfo_new - Object with 2 values for new "tick period": numreq - total number or requests for item, numslave - number of slaves requesting that item + //Returns: Array of 2 elements //0.New dole for item X //1.Guessed percentage average of items supplied in last 10 ticks -function Tick(instore,dole,store_last_tick) +function Tick(instore,dole,store_last_tick,doleinfo_last,doleinfo_new) { - var inputs=[instore,dole,store_last_tick]; + var instore_adj=instore; + if (instore_adj==0) instore_adj=0.1; + var numreq_total_adj=doleinfo_last.numreq; + if (numreq_total_adj==0) numreq_total_adj=0.1; + var a=doleinfo_new.numreq; + if (a>0) {a=doleinfo_last.numreq/doleinfo_new.numreq;} else {a=1000;} + var aa=doleinfo_last.numslave*instore; + if (aa>0) {doleinfo_last.numreq/aa;} else {aa=1000;} + var inputs=[instore,dole,store_last_tick/instore_adj,a,doleinfo_last.numslave,doleinfo_new.numslave,aa,store_last_tick/numreq_total_adj]; var internal=[0,0,0,0,0]; var outputs=[0,0]; //NN: Please don't touch :), code is generated -outputs[0]=1.0*0.5381062031; -outputs[0]=sigmoid1(outputs[0]); -outputs[1]=1.0*-0.5653554201; -outputs[1]=outputs[1]+inputs[0]*0.65881145; -outputs[1]=outputs[1]+inputs[1]*0.6852278709; +outputs[0]=sigmoid0(outputs[0]); +outputs[1]=inputs[7]*4.376355648; outputs[1]=sigmoid0(outputs[1]); avg=outputs[1]; if (avg>1) avg=1; if (avg<0) avg=0; + return [outputs[0],avg]; } -module.exports = {Dose,Tick} \ No newline at end of file +module.exports = {Dose,Tick} From 595b4e5ac905cb0ba2fec859b25439ea60286d50 Mon Sep 17 00:00:00 2001 From: axapaxa123 <49201376+axapaxa123@users.noreply.github.com> Date: Wed, 3 Apr 2019 14:40:42 +0200 Subject: [PATCH 3/6] Update master.js --- master.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/master.js b/master.js index 3c8a5ac3..f2029ba8 100644 --- a/master.js +++ b/master.js @@ -536,7 +536,7 @@ app.post("/api/place", authenticate.middleware, function(req, res) { }); const routes_api_remove = require("./routes/api/remove.js") const neuralDole = new routes_api_remove.neuralDole({ - items: db.items, + items: db.items, gauge: prometheusDoleFactorGauge }) /** POST endpoint to remove items from DB when client orders items. From 0fe5633926fdb8a6efc6c4ca81ee0437ef503125 Mon Sep 17 00:00:00 2001 From: axapaxa123 <49201376+axapaxa123@users.noreply.github.com> Date: Wed, 10 Apr 2019 01:11:32 +0200 Subject: [PATCH 4/6] Moved gauge creation, 0 items don't fail requests --- master.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/master.js b/master.js index f2029ba8..276af857 100644 --- a/master.js +++ b/master.js @@ -258,7 +258,7 @@ db.items.addItem = function(object) { if(this[object.name] && Number(this[object.name]) != NaN){ this[object.name] = Number(this[object.name]) + Number(object.count); } else { - this[object.name] = object.count; + this[object.name] = Number(object.count); } return true; } @@ -535,9 +535,12 @@ app.post("/api/place", authenticate.middleware, function(req, res) { } }); const routes_api_remove = require("./routes/api/remove.js") -const neuralDole = new routes_api_remove.neuralDole({ - items: db.items, gauge: prometheusDoleFactorGauge -}) +var neuralDole = null + +if(config.useNeuralNetDoleDivider)//Only initialize neural network when it's enabled, otherwise it might override gauge + neuralDole=new routes_api_remove.neuralDole({ + items: db.items, gaugePrefix: prometheusPrefix + }) /** POST endpoint to remove items from DB when client orders items. @@ -564,7 +567,7 @@ app.post("/api/remove", authenticate.middleware, function(req, res) { if(slaves[object.instanceID]) object.instanceName = slaves[object.instanceID].instanceName; let item = db.items[object.name] // console.dir(doc); - if(!item + if((item === undefined) ||(( config.disableImportsOfEverythingExceptElectricity === true || config.disableImportsOfEverythingExceptElectricity === "true" ) && object.name != "electricity") From 86d4f3dba47fda9a4a6ad27f79e5ec50e68a67eb Mon Sep 17 00:00:00 2001 From: axapaxa123 <49201376+axapaxa123@users.noreply.github.com> Date: Wed, 10 Apr 2019 01:13:06 +0200 Subject: [PATCH 5/6] Longer accounting period, moved creation of gauge --- routes/api/remove.js | 47 ++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/routes/api/remove.js b/routes/api/remove.js index 83f334b2..18feabb1 100644 --- a/routes/api/remove.js +++ b/routes/api/remove.js @@ -2,19 +2,37 @@ const averagedTimeSeries = require("averaged-timeseries") const doleNN = require("./../../lib/dole_nn_base.js") +const Prometheus = require('prom-client'); + class neuralDole { + + getRequestStats(itemname,samples) + { + var sum=0; + samples=Math.min(samples,(this.stats[itemname] || []).length-1); + if (samples<1) return 0.1; + for (var i = 1; i <= samples; i++) { + sum+=this.stats[itemname][i].req; + } + if (sum==0) return 0.1; + return sum/samples; + } + constructor({ - items, gauge + items, gaugePrefix }){ // Set some storage variables for the dole divider - this.prometheusDoleFactorGauge = gauge + this.prometheusNNDoleGauge = new Prometheus.Gauge({ + name: gaugePrefix+'nn_dole_gauge', + help: 'Current demand being supplied by Neural Network ; 1 means all demand covered, 0.5 means about half of each supply is covered, 0 means no items are given', + labelNames: ["itemName"], + }); this.items = items this.itemsLastTick = JSON.parse(JSON.stringify(items)) this.dole = {} this.carry = {} this.lastRequest = {} - this.doleinfo_last = {} - this.doleinfo_new = {} + this.stats=[] setInterval(()=>{ for(let name in this.items){ @@ -26,14 +44,15 @@ class neuralDole { count, this.dole[name], this.itemsLastTick[name], - this.doleinfo_last[name] || {numreq:0 , numslave:0}, - this.doleinfo_new[name] || {numreq:0 , numslave:0} + this.getRequestStats(name,5) ) + this.stats[name]=this.stats[name] || [] + this.stats[name].unshift({req:0,given:0});//stats[name][0] is the one we currently collect + if (this.stats[name].length>10) this.stats[name].pop();//remove if too many samples in stats + this.dole[name] = magicData[0] // DONE handle magicData[1] for graphing for our users - this.prometheusDoleFactorGauge.labels(name).set(magicData[1] || 0); - this.doleinfo_last[name]=this.doleinfo_new[name] - this.doleinfo_new[name]={numreq:0 , numslave:0} + this.prometheusNNDoleGauge.labels(name).set(magicData[1] || 0); } this.itemsLastTick = JSON.parse(JSON.stringify(this.items)) }, 1000) @@ -52,8 +71,13 @@ class neuralDole { this.dole[object.name], this.carry[object.name+" "+object.instanceID] || 0, this.lastRequest[object.name+"_"+object.instanceID+"_"+object.instanceName] || 0, - this.doleinfo_last[object.name] || {numreq:0 , numslave:0} + this.getRequestStats(object.name,5) ) + if ((this.stats[object.name] || []).length>0) + { + this.stats[object.name][0].req+=Number(object.count); + this.stats[object.name][0].given+=Number(magicData[0]); + } this.lastRequest[object.name+"_"+object.instanceID+"_"+object.instanceName] = object.count //0.Number of items to give in that dose //1.New dole for item X @@ -61,9 +85,6 @@ class neuralDole { this.dole[object.name] = magicData[1] this.carry[object.name+" "+object.instanceID] = magicData[2] - this.doleinfo_new[object.name].numreq=magicData[0] + (this.doleinfo_new[object.name].numreq || 0) - this.doleinfo_new[object.name].numslave=1 + (this.doleinfo_new[object.name].numslave || 0) - // Remove item from DB and send it if(this.items.removeItem({count: magicData[0], name: object.name})){ if(config.logItemTransfers){ From ce9e1d876af8b772944ad4a5186f4ef210a6abdf Mon Sep 17 00:00:00 2001 From: axapaxa123 <49201376+axapaxa123@users.noreply.github.com> Date: Wed, 10 Apr 2019 01:14:39 +0200 Subject: [PATCH 6/6] Updated neural network and interface --- lib/dole_nn_base.js | 68 +++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/lib/dole_nn_base.js b/lib/dole_nn_base.js index 0aeaf97c..e4dda0b6 100644 --- a/lib/dole_nn_base.js +++ b/lib/dole_nn_base.js @@ -38,47 +38,41 @@ function sigmoid3(x) //0.Number of items to give in that dose //1.New dole for item X //2.New carry for item X slave Y -function Dose(numreq,instore,store_last_tick,dole,carry,prev_req,doleinfo_last) +function Dose(numreq,instore,store_last_tick,dole,carry,prev_req,numreq_total_adj) { + numreq=Number(numreq); + instore=Number(instore); var instore_adj=instore; if (instore_adj==0) instore_adj=0.1; - var numreq_total_adj=doleinfo_last.numreq; - if (numreq_total_adj==0) numreq_total_adj=0.1; - var a=(doleinfo_last.numslave)*numreq; - if (a>0) {a=(doleinfo_last.numreq)/a;} else {a=1000;} var b=Math.trunc(prev_req/instore_adj*numreq); - var inputs=[numreq,instore_adj,store_last_tick/numreq,dole,carry,prev_req/numreq,doleinfo_last.numslave,numreq/numreq_total_adj,a,store_last_tick/numreq_total_adj,prev_req/instore,b]; + var inp1=[numreq,instore_adj,store_last_tick/numreq,dole,carry];//0..4 + var inp2=[prev_req/numreq,numreq/numreq_total_adj,store_last_tick/numreq_total_adj,prev_req/instore_adj,b];//5..9 + var inputs=inp1.concat(inp2); var internal=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; var outputs=[0,0,0]; //NN: Please don't touch :), code is generated -internal[11]=inputs[1]*2.584747791; -internal[11]=internal[11]+inputs[4]*0.9939581156; -internal[11]=internal[11]+inputs[5]*-0.5315227509; -internal[11]=internal[11]+inputs[3]*0.2037106603; -internal[11]=internal[11]+inputs[2]*1.38696003; -internal[11]=internal[11]+inputs[6]*-0.5434055328; -internal[11]=internal[11]+inputs[8]*-0.4344435036; -internal[11]=internal[11]+1.0*-1.461762667; -internal[11]=sigmoid0(internal[11]); -outputs[0]=inputs[0]*0.4289886355; -outputs[0]=outputs[0]+internal[11]*1.96782124; -outputs[0]=outputs[0]+inputs[3]*-2.196558237; -outputs[0]=sigmoid3(outputs[0]); -outputs[1]=outputs[0]*3.200549364; -outputs[1]=outputs[1]+inputs[7]*-0.3701510429; +outputs[0]=inputs[2]*3.101320028; +outputs[0]=outputs[0]+inputs[7]*0.5471593142; +outputs[0]=outputs[0]+inputs[3]*2.691268921; +outputs[0]=outputs[0]+outputs[1]*-1.64255929; +outputs[0]=outputs[0]+inputs[6]*0.7746122479; +outputs[0]=sigmoid0(outputs[0]); +outputs[1]=inputs[2]*-0.9946503043; +outputs[1]=outputs[1]+inputs[1]*0.2128598392; outputs[1]=sigmoid0(outputs[1]); -outputs[2]=sigmoid0(outputs[2]); +outputs[2]=sigmoid2(outputs[2]); + outputs[0]=Number(outputs[0]); if (outputs[0]<0) outputs[0]=0; outputs[0]=outputs[0]*numreq; - var res1=Math.trunc(outputs[0]); + var res1=Math.round(outputs[0]); if (res1>numreq) res1=numreq; if (res1>instore) res1=instore; if (res1<0) res1=0; - carry=outputs[2]; - return [res1,outputs[1],carry]; + carry=sigmoid0(outputs[2]); + return [res1,sigmoid0(outputs[1]),carry]; } //TICK - Updates values for item X, should be called once for each item for each round of all slaves requesting that item @@ -92,31 +86,33 @@ outputs[2]=sigmoid0(outputs[2]); //Returns: Array of 2 elements //0.New dole for item X //1.Guessed percentage average of items supplied in last 10 ticks -function Tick(instore,dole,store_last_tick,doleinfo_last,doleinfo_new) +function Tick(instore,dole,store_last_tick,numreq_total_adj) { var instore_adj=instore; if (instore_adj==0) instore_adj=0.1; - var numreq_total_adj=doleinfo_last.numreq; - if (numreq_total_adj==0) numreq_total_adj=0.1; - var a=doleinfo_new.numreq; - if (a>0) {a=doleinfo_last.numreq/doleinfo_new.numreq;} else {a=1000;} - var aa=doleinfo_last.numslave*instore; - if (aa>0) {doleinfo_last.numreq/aa;} else {aa=1000;} - var inputs=[instore,dole,store_last_tick/instore_adj,a,doleinfo_last.numslave,doleinfo_new.numslave,aa,store_last_tick/numreq_total_adj]; + var inputs=[instore,dole,store_last_tick/instore_adj,store_last_tick/numreq_total_adj]; var internal=[0,0,0,0,0]; var outputs=[0,0]; //NN: Please don't touch :), code is generated -outputs[0]=sigmoid0(outputs[0]); -outputs[1]=inputs[7]*4.376355648; +internal[2]=sigmoid0(internal[2]); +outputs[0]=internal[2]*0.4049594998; +outputs[0]=outputs[0]+1.0*-5.026565075; +outputs[0]=outputs[0]+inputs[0]*0.9100194573; +outputs[0]=outputs[0]+inputs[1]*-1.063795686; +outputs[0]=sigmoid1(outputs[0]); +outputs[1]=outputs[0]*1.049500823; +outputs[1]=outputs[1]*inputs[0]*3.437163115; outputs[1]=sigmoid0(outputs[1]); + avg=outputs[1]; + if (numreq_total_adj<0.11) avg=1;//When no item's are requested, result is 0.1 ; In that case there is no deficit, so return 1 = 100% demand fulfilled if (avg>1) avg=1; if (avg<0) avg=0; - return [outputs[0],avg]; + return [sigmoid0(outputs[0]),avg]; } module.exports = {Dose,Tick}