簡體   English   中英

如何從一組不平等比較中在Perl中創建一個有序列表?

[英]How to create an ordered list in Perl from a set of inequality comparisons?

我正在Perl中進行歷史股票市場分析。 一方面涉及分析研究公司過去的股票評級的准確性。 最基本的評分標准是買入,持有,賣出。 但是,這些公司中有許多使用不同的術語,有些公司的規模超過3分。

我所擁有的是數百家不同公司(來自Yahoo Finance)發布的數千種升級/降級列表,看起來像這樣:

Action      From      To
==================================================
Upgrade     Add           Buy
Downgrade   Add           Hold
Upgrade     Hold          Add
Downgrade   Buy           Outperform
Upgrade     Hold          Outperform
Downgrade   Hold          Reduce
Upgrade     Add           Outperform

所以基本上它是比較列表,例如A> B,D <C,B> C,D <A

對於每個研究公司,我需要一長串這些比較的清單,如下所示:

A> B> C> D> E

我給了這個問題很多想法,無法解決。 如果每個升級/降級僅跳躍一個增量,我想我可以做到,但是我不能全神貫注於如何插入比較,例如C <A,它會跳躍兩個增量。

有人有什么想法嗎?




更新:

謝謝@ikegami。 我用原始數據測試過,您是正確的。

我還通過Graph :: Easy運行了一些數據,該圖呈現了圖形。

碼:

use Graph::Easy;
my $graph = Graph::Easy->new( );

# Note that these are all in 'Upgrade' direction
$graph->add_edge ('Hold', 'Add');
$graph->add_edge ('Hold', 'Buy');
$graph->add_edge ('Hold', 'Outperform');
$graph->add_edge ('Buy', 'Outperform');
$graph->add_edge ('Reduce', 'Hold');
$graph->add_edge ('Add', 'Buy');

print $graph->as_ascii( );

輸出:

               +------------------------+
               |                        v
+--------+     +------+     +-----+     +-----+     +------------+
| Reduce | --> | Hold | --> | Add | --> | Buy | --> | Outperform |
+--------+     +------+     +-----+     +-----+     +------------+
               |                                    ^
               +------------------------------------+

這是帶有一些明顯歧義的圖表。 也許我可以以某種方式使用兩個模塊(或Graph的某些功能)來測試歧義。

+------------------------------+
|                              v
+--------+     +---------+     +-----+
| Reduce | --> | Neutral | --> | Buy |
+--------+     +---------+     +-----+
                 ^               ^
                 |               |
                 |               |
               +---------+       |
               |  Sell   | ------+
               +---------+

我不經常使用圖形,但是此代碼(使用Graph模塊)似乎可以完成工作:

use Graph;
use strict;

my $graph = Graph->new;

while (<DATA>) {
    my ($dir, $x, $y) = split;
    if ($dir eq 'Downgrade') {
        ($x, $y) = ($y, $x);
    } elsif ($dir ne 'Upgrade') {
        die qq(Unknown direction "$dir"\n);
    }
    $graph->add_edge($x, $y);
}

$graph->is_dag
    or die "Graph has a cycle--unable to analyze\n";
$graph->is_weakly_connected
    or die "Graph is not weakly connected--unable to analyze\n";

print join(' < ', $graph->topological_sort), "\n";

__DATA__
Upgrade     Add           Buy
Downgrade   Add           Hold
Upgrade     Hold          Add
Downgrade   Buy           Outperform
Upgrade     Hold          Outperform
Downgrade   Hold          Reduce
Upgrade     Add           Outperform

此打印品Reduce < Hold < Add < Outperform < Buy

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM