2012-01-19 4 views
2

私はPerlで過去の株式市場分析をしています。 1つの側面は、研究機関の過去の株式格付けの正確性を分析することを扱う。最も基本的な評価尺度は、購入、保留、売却です。しかし、これらの企業の多くは異なる用語を使用していますが、その中には3点以上のものもあります。私が持っているもの不等式の比較からPerlで順序付きリストを作成する方法は?

は、次のようになります(ヤフー・ファイナンスから)別の企業数百人によって発行されたアップグレード/ダウングレードの何千ものリストです:

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> E

私はこの問題に多くの考えを与えており、解決策を思いつくことはできません。各アップグレード/ダウングレードが1増分だけ飛び降りた場合、私はそれを行うことができたと思いますが、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 | 
+--------+  +------+  +-----+  +-----+  +------------+ 
       |         ^
       +------------------------------------+ 

は、ここではいくつかの明確なあいまいさを持つグラフです。おそらく私は何とか両方のモジュール(またはグラフのいくつかの機能)を使っ​​てあいまいさをテストすることができます。

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

各データセットに 'A> B> C> D> E'が存在すると仮定できますか? – Dave

+0

あなたの例では、OutperformがAddよりも高いか低いかはあいまいです。 – Sean

+0

@Sean:申し訳ありませんが、グラフにデータを追加しました。私は簡潔さを目指していましたが、必要な情報をすべて提供していないことがわかりました。 – calyeung

答えて

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を印刷します。

+0

グラフ理論のご紹介ありがとうございます。これは非常に洗練されたソリューションです。 – calyeung

+0

これはあいまいさを検出しないことに注意してください。可能な順序を返します。例えば、答えが「Hold ikegami

関連する問題