mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-11 23:04:52 +09:00
3 files changed
+94
-78
No files matched your search
+44
-65
@@ -32,108 +32,87 @@ 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,numreq_total_adj)
|
||||
{
|
||||
var inputs=[numreq,instore,store_last_tick,dole,carry,prev_req];
|
||||
numreq=Number(numreq);
|
||||
instore=Number(instore);
|
||||
var instore_adj=instore;
|
||||
if (instore_adj==0) instore_adj=0.1;
|
||||
|
||||
var b=Math.trunc(prev_req/instore_adj*numreq);
|
||||
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];
|
||||
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;
|
||||
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]=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]);
|
||||
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]+outputs[0]-res1;
|
||||
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
|
||||
//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,numreq_total_adj)
|
||||
{
|
||||
var inputs=[instore,dole,store_last_tick];
|
||||
var instore_adj=instore;
|
||||
if (instore_adj==0) instore_adj=0.1;
|
||||
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]=1.0*0.5381062031;
|
||||
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]=1.0*-0.5653554201;
|
||||
outputs[1]=outputs[1]+inputs[0]*0.65881145;
|
||||
outputs[1]=outputs[1]+inputs[1]*0.6852278709;
|
||||
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}
|
||||
module.exports = {Dose,Tick}
|
||||
@@ -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,
|
||||
})
|
||||
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")
|
||||
|
||||
+42
-8
@@ -2,16 +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,
|
||||
items, gaugePrefix
|
||||
}){
|
||||
// Set some storage variables for the dole divider
|
||||
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.stats=[]
|
||||
|
||||
setInterval(()=>{
|
||||
for(let name in this.items){
|
||||
@@ -22,10 +43,16 @@ class neuralDole {
|
||||
let magicData = doleNN.Tick(
|
||||
count,
|
||||
this.dole[name],
|
||||
this.itemsLastTick[name]
|
||||
this.itemsLastTick[name],
|
||||
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]
|
||||
// TODO handle magicData[1] for graphing for our users
|
||||
// DONE handle magicData[1] for graphing for our users
|
||||
this.prometheusNNDoleGauge.labels(name).set(magicData[1] || 0);
|
||||
}
|
||||
this.itemsLastTick = JSON.parse(JSON.stringify(this.items))
|
||||
}, 1000)
|
||||
@@ -42,15 +69,22 @@ 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.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
|
||||
//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]
|
||||
|
||||
// Remove item from DB and send it
|
||||
if(this.items.removeItem({count: magicData[0], name: object.name})){
|
||||
if(config.logItemTransfers){
|
||||
@@ -96,7 +130,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 +177,4 @@ function doleDivider({
|
||||
module.exports = {
|
||||
doleDivider,
|
||||
neuralDole
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user