如何对数组数组进行排序以使其最像身份矩阵?

时间:2014-08-20 16:53:18

标签: javascript arrays sorting matrix

我尝试过很多不同的算法,但是找不到这种算法。

所以基本上我会有一个矩阵

1 0 1 | 4
7 0 1 | 9
1 1 3 | 3

我想要对它进行排序,使其最像身份矩阵

1 0 0
0 1 0
0 0 1

因此,对于前一个矩阵,它将返回

1 0 1 | 4
1 1 3 | 3
7 0 1 | 9

任何人都可以告诉我一个排序功能,最好用javascript吗?

这是我到目前为止所拥有的

matrix.sort(function(a,b) {
      if (b.indexOf(1)!=-1) {
          var index =  a.indexOf(1)-b.indexOf(1)
          if (index!==0) return index
              else {
                  return b.indexOf(0) - a.indexOf(0)
              }
      }
      else {
          return 0
      }
})

更多例子

3  1 -2 | 2
1 -2  1 | 3
2 -1 -3 | 3

会变成

1 -2  1 | 3
3  1 -2 | 2 
2 -1 -3 | 3

 3  1 -2 | -7
 2  2  1 |  9
-1 -1  3 |  6

会变成

-1 -1  3 |  6
 3  1 -2 | -7
 2  2  1 |  9

2 个答案:

答案 0 :(得分:0)

这与String Metrics非常相似。换句话说,您的算法应该使用字符串度量/距离算法建模,例如Levenshtein Distance

基本上,您的算法需要定义您想要如何对相似性进行排名。 这通常使用“置换”和“匹配”的点来完成。

什么接近100 - 010或000?

您应该决定如何对相似度进行排名,然后找到排名最高的集合。

答案 1 :(得分:0)

我的最终代码:

    function(matrix) {
            var newmatrix = matrix.slice(0)
            var sorted = []
            var id = identity(newmatrix.length)
            for ( var i = 0; i < id.length; i++ ) {
                    var bestindex;
                    var bestdist = 100
                    for ( var j = 0; j < newmatrix.length; j++ ) {
                            var idstr = id[i].join('')
                            var matstr = newmatrix[j].join('')
                            var newdist = levenshteinDistance(idstr,matstr)
                            if (newdist < bestdist) {
                                    bestdist = newdist
                                    bestindex = j
                            }
                    }
                    sorted[i] = newmatrix[bestindex]
                    newmatrix.splice(bestindex,1)
            }
            return sorted
    }
    function levenshteinDistance(s, t) {
            if (s.length === 0) return t.length;
            if (t.length === 0) return s.length;
            return Math.min(
                    levenshteinDistance(s.substr(1), t) + 1,
                    levenshteinDistance(t.substr(1), s) + 1,
                    levenshteinDistance(s.substr(1), t.substr(1)) + (s[0] !== t[0] ? 1 : 0)
            );
    }
    function identity(n) {
            var id = []
            for ( var i = 0; i < n; i++) {
                    id[i]=[]
                    for (var j = 0; j < n; j++) {
                            id[i][j] = (i===j) ? 1 : 0
                    }
            }
            return id
    }

我使用了for循环,因为数组开头的项比匹配更重要。万分感谢@Etai的公式!