unique-grouping
Version:
Groups list of individuals in K unique groupings of N groups using simulated annealing
2 lines • 2.39 kB
JavaScript
import SimulatedAnnealing from"simulated-annealing";import chunk from"chunk";import Combinatorics from"js-combinatorics";import empty from"is-empty";import last from"array-last";import isPositiveInteger from"validate.io-positive-integer";import findLastIndex from"lodash.findlastindex";import d3 from"d3-array";import clone from"clone";import equal from"fast-deep-equal";import StringBuilder from"yassb";import uniqueRandomArray from"unique-random-array";import random from"random";import randomArrayIndex from"random-array-index";const UniqueGrouping=(e=[],r=[],t=[],n,o={tempMax:65,tempMin:7e-4,coolingRate:2e-4,alpha:1,beta:1})=>{const a=(e,r)=>chunk(d3.shuffle(e),r),i=e=>e.reduce((e,n)=>{const o=(e,r)=>f*e**2+r.reduce((e,r)=>e+r*d,0),a=n.length;return 0===a?e:1===a?e+o(a,[]):e+o(a,Combinatorics.combination(n,2).map(e=>{if(t.some(r=>equal(r,e)||equal(r,e.reverse())))return 1/0;const[n,o]=e,{lastSeen:a,timesSeen:i}=((e,t)=>{const n=r.map(r=>r.filter(r=>r.some(r=>equal(r,e))&&r.some(e=>equal(e,t)))),o=n.length-1;return{lastSeen:empty(n)?-100:o-findLastIndex(n,e=>!empty(e)),timesSeen:n.filter(e=>!empty(e)).length}})(n,o);return((e,r,t)=>e/(1+(r/t)**2))(i+1,a,r.length+1)}))},0),m=e=>{const r=clone(e),t=uniqueRandomArray(r.filter(e=>!empty(e))),n=t(),o=t();return n.length>o.length&&random.boolean()?((e,r)=>{const t=randomArrayIndex(e);r.push(...e.splice(t,1))})(n,o):((e,r)=>{const t=randomArrayIndex(e),n=randomArrayIndex(r);[e[t],r[n]]=[r[n],e[t]]})(n,o),r},s=e=>e-p,{tempMax:l,tempMin:u,coolingRate:p,alpha:d,beta:f}=o;if(!isPositiveInteger(n))throw new Error("groupSize must be an integer greater than 0");if(empty(e)){if(empty(r))throw new Error("Either history or people must be a non-empty array");e=last(r).flat()}return new Promise((r,t)=>r(SimulatedAnnealing({initialState:a(e,n),tempMax:l,tempMin:u,newState:m,getTemp:s,getEnergy:i})))},grade=(e,r,t)=>{const n=new StringBuilder,o=e.reduce((e,o)=>{return o.length<2?e:e+Combinatorics.combination(o,2).reduce((e,o)=>{if(t.some(e=>equal(e,o)||equal(e,o.reverse())))return n.addLine(`FORBIDDEN PAIR DETECTED: ${a} is with ${i}`),1/0;const[a,i]=o,m=((e,t)=>r.flat().filter(r=>r.some(r=>equal(r,e))&&r.some(e=>equal(e,t))).length)(a,i);return n.addLine(`${a} has seen ${i} ${m} time(s)`),e+m},0)},0);return{log:n.toString(),totalTimesSeen:o}};export default UniqueGrouping;export{grade};
//# sourceMappingURL=index.min.js.map