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

时间:2012-01-19 21:05:31

标签: perl list graph-theory stocks

我正在玩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

所以基本上它是一个比较列表,如A> B,D< C,B> C,D<甲

我需要为每个研究公司提供一长串的这些比较,这是一个有序列表,如下所示:

A> B> C> D> ë

我已经考虑过这个问题并且无法提出解决方案。如果每次升级/降级只跳过一个增量,我想我可以做到,但我无法解决如何插入像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   | ------+
               +---------+

1 个答案:

答案 0 :(得分: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

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