Algorithm 基于元素成对关联的排序列表
给定一个元素列表,例如Algorithm 基于元素成对关联的排序列表,algorithm,sorting,graph-theory,greedy,Algorithm,Sorting,Graph Theory,Greedy,给定一个元素列表,例如[1,2,3,4],以及它们的成对关联,例如 [[0, 0.5, 1, 0.1] [0.5, 0, 1, 0.9] [ 1, 1, 0, 0.2] [0.1, 0.9, 0.2, 0]] 对于那些熟悉图论的人来说,这基本上是一个邻接矩阵 什么是对列表进行排序的最快方法,以使列表中的距离与成对关联最佳相关,即具有高度关联的节点对应彼此接近 有没有一种方法可以做到这一点(即使是贪婪的算法也可以)而不需要太多的研究和理论 作为奖金问题: 请注意,某些成对关联
[1,2,3,4]
,以及它们的成对关联,例如
[[0, 0.5, 1, 0.1]
[0.5, 0, 1, 0.9]
[ 1, 1, 0, 0.2]
[0.1, 0.9, 0.2, 0]]
对于那些熟悉图论的人来说,这基本上是一个邻接矩阵
什么是对列表进行排序的最快方法,以使列表中的距离与成对关联最佳相关,即具有高度关联的节点对应彼此接近
有没有一种方法可以做到这一点(即使是贪婪的算法也可以)而不需要太多的研究和理论
作为奖金问题:
请注意,某些成对关联可以完美地表示,如列表[1,2,3]
和成对关联:
[[0, 0, 1]
[0, 0, 1]
[1, 1, 0]]
完美的顺序是[1,3,2]
。但有些附属机构不能,比如:
[[0, 1, 1]
[1, 0, 1]
[1, 1, 0]]
任何订单都一样好/坏
有没有办法判断订单的质量?这是一个经过简单测试的算法,它采用邻接矩阵,按外观顺序设置元素/节点,然后尝试找到平衡点。因为它是一维的,所以我选择了一个非常简单的引力公式。也许增加排斥力会改善它
/*
* Sort the nodes of an adjacency matrix
* @return {Array<number>} sorted list of node indices
*/
function sort1d(mat) {
var n = mat.length;
// equilibrium total force threshold
var threshold = 1 / (n * n);
var map = new Map(); // <index, position>
// initial positions
for(var i = 0; i < n; i++) {
map.set(i, i);
}
// find an equilibrium (local minima)
var prevTotalForce;
var totalForce = n * n;
do {
prevTotalForce = totalForce;
totalForce = 0;
for(var i = 0; i < n; i++) {
var posi = map.get(i);
var force = 0;
for(var j = i + 1; j < n; j++) {
var posj = map.get(j);
var weight = mat[i][j];
var delta = posj - posi;
force += weight * (delta / n);
}
// force = Sum[i, j=i+1..n]( W_ij * ( D_ij / n )
map.set(i, posi + force);
totalForce += force;
}
console.log(totalForce, prevTotalForce);
} while(totalForce < prevTotalForce && totalForce >= threshold);
var list = [];
// Map to List<[position, index]>
map.forEach(function(v, k) { list.push([v, k]); });
// sort list by position
list.sort(function(a, b) { return a[0] - b[0]; });
// return sorted indices
return list.map(function(vk) { return vk[1]; });
}
var mat = [
[0, 0.5, 1, 0.1],
[0.5, 0, 1, 0.9],
[1, 1, 0, 0.2],
[0.1, 0.9, 0.2, 0]
];
var mat2 = [
[0, 1, 1],
[1, 0, 1],
[1, 1, 0]
];
console.log(sort1d(mat)); // [2, 0, 1, 3]
console.log(sort1d(mat2)); // [0, 1, 2]
/*
*对邻接矩阵的节点进行排序
*@return{Array}节点索引的排序列表
*/
函数sort1d(mat){
var n=材料长度;
//平衡总力阈值
var阈值=1/(n*n);
var map=new map();//
//初始位置
对于(变量i=0;i=阈值);
var列表=[];
//映射到列表
forEach(函数(v,k){list.push([v,k]);});
//按位置对列表排序
sort(函数(a,b){返回a[0]-b[0];});
//返回排序索引
return list.map(函数(vk){return vk[1];});
}
var mat=[
[0, 0.5, 1, 0.1],
[0.5, 0, 1, 0.9],
[1, 1, 0, 0.2],
[0.1, 0.9, 0.2, 0]
];
变量mat2=[
[0, 1, 1],
[1, 0, 1],
[1, 1, 0]
];
console.log(sort1d(mat));//[2,0,1,3]
console.log(sort1d(mat2));//[0,1,2]
如果你同意的话,可能会在上做得更好。@AakashM,也许你是对的。老实说,我不太确定这最适合哪里。也可能是一个候选。我现在就拭目以待,如果其他人支持迁移,那对我来说完全没问题。那么你的度量/优化目标到底是什么?(例如,L1/L2错误)?@sascha您也可以只查看未加权图(布尔权重)。度量不是先验定义的,而是取决于您选择投影到的空间。一种方法是将图放在n维欧几里德空间中(其中n最多是列表的长度)。如果减少n,最终将无法放置节点,以使配置完全尊重从属关系矩阵。从属关系矩阵和缩减空间中的有效距离之间的误差(L1/L2取决于您)可以用作质量度量。但正如我所说,如果可能,没有MDS。我收集了一个O(c*n^2+n*log(n))吸引力1d平衡解算器。它可能会给你一个令人满意的近似值。酷,我会在找到时间后仔细研究它。原则上,如果你有一个约束,即只有一个节点可以占据列表中的一个插槽,那么这个约束实际上已经是一个排斥力(一个非常奇怪的方法,尽管它只在局部起作用)。我想知道这是否可以用比O(n^2)更快的方法来完成…@jojo-我将节点位置初始化为其整数索引,而不是使用2d强制定向显示中的随机定位,这可能会改善结果。当应用强制时,新位置是实数,因此它们只是数字线上的点,在最后的排序步骤中它们只会成为数组中的插槽。比(n^2)可能意味着不太精确的近似,可能是通过创建n个列表,每个列表按邻接矩阵中的对应行排序,然后有人将这些列表合并在一起。下面是一个初始化的想法:找到图的最小生成树(因为你有亲缘关系,而不是距离,你必须稍微调整一下MST成本函数)。然后你可以在MST上迭代初始位置。要迭代树节点(可能有任意数量的子节点),迭代其一半的子节点,然后生成节点本身,然后迭代其余的子节点。@JerryFederspiel-据我所知,这个1d版本甚至不需要最佳的起始位置来收敛到一个答案。我真的不知道如何以100%的精度解出这个问题,可能解出一组线性方程组(或不平等)其中变量是最终列表的索引,不等式是顶点之间的各种权重。是的,它不需要最佳位置来开始。我认为这可能会减少迭代次数,但我没有测试过这一点或任何东西。感觉真实的解应该接近MST上的某个顺序迭代…b但这可能是因为我对亲缘关系中的“美好”有一些隐含的假设,这些假设并不总是成立的