根据动态优先级显示结果的算法

时间:2015-02-14 14:00:49

标签: algorithm

我有一个很大的关系,其中每个元组都有一个对应于每列的整数值。现在我需要根据用户指定的每列优先级(显然根据用户而改变)按顺序显示这些元组。微型示例: 考虑这种关系: enter image description here

用户分别为A,B,C和D输入8,9,5和4的优先级,我需要确定最符合用户优先级的元组的顺序。 到目前为止我所想到的是按照提供的用户优先级的排序顺序应用过滤器,然后显示结果。我需要帮助以获得更准确的算法。

1 个答案:

答案 0 :(得分:1)

答案可能就像......一样简单吗? 显然,这不是答案,但我仍处于黑暗中,正确的结果可能是什么......

基本上问题归结为"哪个指标符合用户的最佳品味?"。

虽然我自己提供2个指标,但任何有想法的人都可以通过提供指标功能来缩短他们的答案。您可以尝试使用以下代码,例如http://www.tryfsharp.org/Create

第一个(metric1使用标量积)。 虽然第二个值很小,但优先级高的第一个值在排名中会增加(6,2,3,8)。

第二个(metric2)尝试与价值无关,使用一些排名方法(在强大的估算器,baysean等中排名),其中排序的元组值相对于位置的位置匹配在排序的优先级元组中,奖励一个2 ^(优先级位置)的数字。这意味着,优先级最高的等级匹配永远不会被较低优先级的位置匹配打败。你仍然关注,对吗? :)

更明确地说明metric2(我相信它可以改进 - 当你需要它们时谷歌的那些人在哪里?!):

[3; 2; 4; 1] [2; 1; 3; 4] ([1; 5; 9; 2] [8; 9; 5; 4])
0
[4; 1; 3; 2] [2; 1; 3; 4] ([6; 2; 3; 8] [8; 9; 5; 4])
12
[4; 3; 2; 1] [2; 1; 3; 4] ([4; 4; 4; 4] [8; 9; 5; 4])
0

在这里,您可以看到表中所有3个4元组的metric2的中间值。 最右边你会看到优先级值元组。右起第二个,输入值元组。前两个列表显示了表元组和优先元组的排序索引(按降序排列)。

现在......一个好的匹配将具有与优先元组相同的排序顺序。 (这个指标理论)。因此,如果表元组中的最大值位于优先元组中最高优先级所在的位置,那么这将是好的。对于优先元组中的高优先级位置,这甚至更好。如果表元组中的第二个最高值位于优先元组中第二高优先级值的位置,这也很好 - 但不如最高优先级的第一个值那么重要......

为了避免最少"重要"的排序。元组中的值根据优先级元组赢得更多"重要"其中,我为指标添加了特定于优先级的值。

如果第一个优先级匹配,则得到度量值2 ^ 4 = 16.如果第二个匹配则为8,则为4,2,1。因此,即使第一场比赛失败并且所有其他比赛都匹配,一个元组也无法击败第一场比赛位于正确位置的元组。

为方便研究人员,我添加了一个空的metric3,可用于寻找更好的替代方案。

let ua,ub,uc,ud = (8,9,5,4)
let table = [ 1,5,9,2; 6,2,3,8; 4,4,4,4 ]
let metric1 (a,b,c,d) = a*ua + b * ub + c * uc + d * ud
let metric2 (a,b,c,d) = 
    let indices = [1;2;3;4]
    let values = [a;b;c;d]
    let indByValue  = 
        List.zip indices values 
        |> List.sortBy (fun (i,v) -> v)  
        |> List.map (fun (i,v) -> i) 
        |> List.rev
    let prioIndByValue = 
        List.zip indices [ua;ub;uc;ud] 
        |> List.sortBy (fun (i,p) -> p) 
        |> List.map (fun (i,p) -> i) 
        |> List.rev
    //printfn "%A %A (%A %A)" indByValue prioIndByValue values [ua;ub;uc;ud]
    let r,_ = 
        List.zip indByValue prioIndByValue 
        |> List.fold (fun (cnt,w) (x,y)-> if x = y then (cnt + (1 <<< w),w-1) else (cnt,w-1) ) (0,4)
    r
let metric3 (a,b,c,d) = 
    // TODO: Write your favourite metric here ;)
    0
let best1 = List.maxBy metric1 table
let sorted1 = List.sortBy metric1 table
let best2 = List.maxBy metric2 table
let sorted2 = List.sortBy metric2 table
let best3 = List.maxBy metric3 table
let sorted3 = List.sortBy metric3 table

//table |> List.iter (fun r -> printfn "%A" (metric2 r))