使用numpy的{Pareto前沿指数

时间:2017-01-19 11:23:53

标签: python numpy

我正在尝试标记多个numpy向量(矩阵 M ),以便标签显示Pareto前沿索引。

例如,非支配的向量集(v0)将使用帕累托前沿索引{{​​1}}进行标记,非主导向量的集合 v1 (< em> v1 = M - v0 )将标记为索引0,非支配向量的下一个集合/前沿 v2 v2 = M - v0 - v1 1等等,直到矩阵 M 的所有向量都被标记。

我已经将一些测试用例放在一起了,但无论我想出什么,要么效率极低(目前不太在意)或者只是不起作用。

2

向量 x 支配 y 如果foreach a in x,b in y:a&gt; = b AND至少存在一个 a x a&gt; B'/ em>的

这是我的尝试:

mat1 = np.asarray([
    [1, 2, 3, 4, 5, 7],
    [1, 2, 3, 4, 5, 6],
    [1, 2, 3, 4, 5, 6],
])

calc_fronts(mat1) == [0, 1, 1]

mat2 = np.asarray([
    [1, 2, 3, 4, 5, 7],
    [1, 2, 3, 4, 5, 6],
    [1, 22, 3, 4, 5, 6],
])

calc_fronts(mat2) == [0, 1, 0]


mat3 = np.asarray([
    [1, 2, 3, 4, 5, 7],
    [1, 2, 3, 4, 5, 5],
    [1, 2, 2, 4, 5, 4],
])

calc_fronts(mat3) == [0, 1, 2]


mat4 = np.asarray([
    [0, 2, 3, 4, 5, 7],
    [1, 2, 3, 4, 5, 6],
    [1, 22, 2, 4, 5, 6],
])

calc_fronts(mat4) == [0, 0, 0]

1 个答案:

答案 0 :(得分:0)

这是我非常沉重的尝试,希望能给出一些新的想法。虽然要注意创建了一个(m,m,n)临时数组(当M为(m,n)形状时)。

import numpy as np

def calc_fronts(M):
    i_dominates_j = np.all(M[:,None] >= M, axis=-1) & np.any(M[:,None] > M, axis=-1)
    remaining = np.arange(len(M))
    fronts = np.empty(len(M), int)
    frontier_index = 0
    while remaining.size > 0:
        dominated = np.any(i_dominates_j[remaining[:,None], remaining], axis=0)
        fronts[remaining[~dominated]] = frontier_index

        remaining = remaining[dominated]
        frontier_index += 1
    return fronts

演示:

In [217]: M = np.array([[ 0, 18,  1],
     ...:               [ 4,  8, 11],
     ...:               [ 3, 19,  3],
     ...:               [18,  1, 19],
     ...:               [16,  7, 13],
     ...:               [ 3, 18,  3],
     ...:               [15, 13, 19],
     ...:               [13,  5, 13],
     ...:               [ 2, 16, 16],
     ...:               [ 9, 14, 17]])

In [218]: calc_fronts(M)
Out[218]: array([2, 1, 0, 0, 0, 1, 0, 1, 0, 0])