Javascript 从数组数组中拾取唯一集
我以前试图问一个更复杂的问题,但我不能很好地解释它,所以我用一个简化的用例再试一次 我将有一个数组,如下所示Javascript 从数组数组中拾取唯一集,javascript,arrays,mathematical-optimization,Javascript,Arrays,Mathematical Optimization,我以前试图问一个更复杂的问题,但我不能很好地解释它,所以我用一个简化的用例再试一次 我将有一个数组,如下所示 var allData=[[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5]。您可以计算所有元素,并使用相同的指数进行各种比较 函数x([…数据]){ while(data.some(Array.isArray)){ 常数 计数=数据。减少((r,a,i)=>{ if(Array.isArra
var allData=[[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5]。您可以计算所有元素,并使用相同的指数进行各种比较
函数x([…数据]){
while(data.some(Array.isArray)){
常数
计数=数据。减少((r,a,i)=>{
if(Array.isArray(a))a.forEach(v=>(r[JSON.stringify(v)]=r[JSON.stringify(v)]| |[]).push(i));
返回r;
}, {}),
条目=对象。条目(计数),
更新=([k,v])=>{
如果(v.length==1){
data[v[0]]=JSON.parse(k);
返回true;
}
};
如果(条目。某些(更新))继续;
const group=entries.reduce((r,[,a])=>{
const key=JSON.stringify(a);
r[键]=(r[键]| 0)+1;
返回r;
}, {});
Object.entries(分组).forEach(([json,length])=>{
const index=JSON.parse(JSON);
如果(index.length==长度){
设j=0;
forEach(i=>data[i]=data[i][j++]);
返回;
}
如果(长度==1){
const value=JSON.parse(entries.find([\uz,a])=>JSON.stringify(a)==JSON)[0]);
index.forEach(i=>data[i]=data[i].filter(v=>v!==value));
数据[指数[0]]=数值;
}
});
}
返回数据;
}
log(…x([[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5]);
log(…x([[1,2,4],[1,2],[1,2],[2,4,5],[1,2,3,5]]);
log(…x([[1,2,4],[1,2],[1,2],[2,4,5],[1,2,3,5],[6,7,8,9],[6,7,8,9],[6,7,8,10],[6,7,8,10])代码>您可以从一个相当简单的回溯算法开始:
函数选取(bin,n=0,res={}){
如果(n==料仓长度){
返回res
}
用于(设x个料仓[n]){
如果(!res[x]){
res[x]=n+1
让发现=拾取(箱子,n+1,res)
如果(找到)
返回发现
res[x]=0
}
}
}
//
设a=[[1,2,4],[1,2],[1,2],[2,4,5],[1,2,3,4]]
log(pick(a))
您可以使用MILP模型解决此问题。以下是Minizing的一个实现(数据已延长至七天):
下面的包看起来很适合JavaScript实现:这里是一个基于计算数组中出现次数的实现
它首先通过计算每个值所在的内部数组的数量来创建一个索引映射。然后,它按内部数组长度排序以确定较短数组的优先级,然后迭代每个内部数组,按出现次数排序并选择计数最低的第一个非重复数组,或者,如果没有唯一值,则选择计数最低的元素
const
发生率SacrossArray=(arr)=>
啊
.减少((a,_arr)=>{
[…新集合(_arr)]。forEach(n=>{
a[n]=a[n]| | 0;
a[n]+=1;
});
返回a;
}, {}),
生成组合=(arr)=>{
const dist=发生率SacrossArray(arr)
返回arr
.sort((a,b)=>a.length-b.length)
.减少((a,_arr)=>{
_arr.sort((a,b)=>dist[a]-dist[b]);
设m=_arr.find(n=>!a.includes(n));
如果(m!==未定义){
a、 推力(m);
}否则{
a、 推送(_arr[0]);
}
返回a;
}, []);
};
log(generateCombination([[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5]).toString();
log(generateCombination([[1,2,4],[1,2],[1],[2,4,5],[1,2,3,5]).toString();
log(generateCombination([[1,2,4],[1,2],[1,2],[2,4,5],[1,2,3,5],[6,7,8,9],[6,7,8,9],[6,7,8,10],[6,7,8,10]).toString()代码>请求库是ot。顺便说一句,你试过什么?这是一个重要的概念问题。不是“将此逻辑实现为代码”,而是“什么样的逻辑可能在这里工作”,这是合理的。我正在对我尝试过的东西进行编辑。这是我的主要问题。更重要的是,这是一个基本概念,我很难将我的大脑包裹在解决此问题的意义上。这就是为什么我提到暴力,它消除了对底层数学的任何实际理解。是的,它可以工作,但不太好。量子计算机在这里可能很有用……谢谢,我正在看这些,并试图理解它的含义。不幸的是,我的javascript技能严重缺乏,但它看起来很有前途。我正在努力让它发挥作用,但我正在工作的网站不支持???=语法。我试图重写这个没有它,但没有任何运气。我真的需要更好地理解所有的速记箭头符号,请参见编辑。基本上,这个a???=[]
是a=a | |[]
与undefined
或null
值的缩写。谢谢!看着这些答案,我学到了很多东西。我的知识非常基础,我倾向于使用所有非常低级的类型概念。这比这里的许多简明逻辑要长得多。只是告诉我还有很多东西需要学习。我会和一些真实的数据一起看一看。我认为,如果我得到大量的结果,我可以坚持随机选择,但如果我得到一个较小的结果集,我需要像这样更聪明。谢谢,我正在尝试运行此程序,但是语法a[n]??=0在我测试的地方不起作用。这与如果(a[n]==u)相同吗
int: Days = 7;
int: Items = 5;
set of int: DAY = 1..Days;
set of int: ITEM = 1..Items;
array[DAY, ITEM] of 0..1: A = % whether item k is allowed on day i
[| 1, 1, 0, 1, 0
| 1, 1, 0, 0, 0
| 1, 1, 0, 0, 0
| 0, 1, 0, 1, 1
| 1, 1, 0, 0, 0
| 0, 1, 0, 1, 1
| 1, 1, 1, 0, 1 |];
array[DAY, ITEM] of var 0..1: x; % 1 if item selected k on day i, otherwise 0
array[DAY, DAY, ITEM] of var 0..1: w; % 1 if item k selected on both day i and day j, otherwise 0
% exactly one item per day
constraint forall(i in DAY)
(sum(k in ITEM)(x[i, k]) = 1);
% linking variables x and w
constraint forall(i, j in DAY, k in ITEM where i < j)
(w[i, j, k] <= x[i, k] /\ w[i, j, k] <= x[j, k] /\ w[i, j, k] >= x[i, k] + x[j, k] - 1);
% try to minimize duplicates and if there are duplicates put them as far apart as possible
var int: obj = sum(i, j in DAY, k in ITEM where i < j)(((Days - (j - i))^2)*w[i, j, k]);
solve minimize obj;
output
["obj="] ++ [show(obj)] ++
["\nitem="] ++ [show([sum(k in ITEM)(k*x[i, k]) | i in DAY])];
obj=8
item=[2, 1, 5, 4, 3, 2, 1]