如何从一组不等式比较中在Perl中创建有序列表?

cal*_*ung 2 perl graph-theory stocks list

我正在玩Perl的历史股市分析.一个方面涉及分析过去股票评级的研究公司的准确性.最基本的评级量表是买入,持有,卖出.然而,这些公司中有许多使用不同的术语,有些术语的规模超过3分.

我所拥有的是数百个不同公司(来自雅虎财经)发布的数千个升级/降级列表,如下所示:

Action      From      To
==================================================
Upgrade     Add           Buy
Downgrade   Add           Hold
Upgrade     Hold          Add
Downgrade   Buy           Outperform
Upgrade     Hold          Outperform
Downgrade   Hold          Reduce
Upgrade     Add           Outperform
Run Code Online (Sandbox Code Playgroud)

所以基本上它是一个比较列表,如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( );
Run Code Online (Sandbox Code Playgroud)

输出:

               +------------------------+
               |                        v
+--------+     +------+     +-----+     +-----+     +------------+
| Reduce | --> | Hold | --> | Add | --> | Buy | --> | Outperform |
+--------+     +------+     +-----+     +-----+     +------------+
               |                                    ^
               +------------------------------------+
Run Code Online (Sandbox Code Playgroud)

这是一个有一些明显含糊之处的图表.也许我可以以某种方式使用两个模块(或Graph的某些功能)来测试模糊性.

+------------------------------+
|                              v
+--------+     +---------+     +-----+
| Reduce | --> | Neutral | --> | Buy |
+--------+     +---------+     +-----+
                 ^               ^
                 |               |
                 |               |
               +---------+       |
               |  Sell   | ------+
               +---------+
Run Code Online (Sandbox Code Playgroud)

Sea*_*ean 5

我不经常使用图表,但是这段代码(使用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
Run Code Online (Sandbox Code Playgroud)

这打印Reduce < Hold < Add < Outperform < Buy.