• ベストアンサー

データの管理の方法について

私は中学生です。 休日や平日の暇な時間を使って、趣味でプログラミングをしています。 今回、私は数百体の生物を肉食・草食などに分け、食物連鎖の世界を模倣しようと考えています。 このプログラムでは百単位の大量なデータを扱うことになり、また、生物の死亡・生殖などもシミュレートしようと思うので、 データを途中で追加・削除することのできるSTLのlistクラスを使用しようと考えました。 ここで質問なのですが、このようなプログラムの場合、listクラスを使うのは正しいでしょうか? それとも、普通の配列変数を使ったり、他の方法でデータを管理したほうがよいでしょうか? 私はいくつかの参考書や、ネットでの情報を見てきましたが、 いままでlistクラスを使ったプログラムは一度も見たことがありません。 どなたか回答をお願いしますm(_ _)m

質問者が選んだベストアンサー

  • ベストアンサー
  • GOOD-Fr
  • ベストアンサー率32% (83/256)
回答No.4

「趣味のプログラム」ということなので、細かい突っ込みはどうかとは思いましたが・・・。 時間があるときにちょこちょこ、という感じでプログラムを楽しんでいるのだと文章から想像します。「今度はどの STL クラスを使おうかな」と考えている時間もきっと楽しいんだと思いますが、たぶん本当に楽しいのは「食物連鎖の世界を模倣」する「本当のプログラム」をしているときですし、それが完成して「世界」を見ているときではないかと思います。 そういう意味では、STL を選んだり使い方を覚えたり、というのは、「あまり楽しくない」ほうのプログラムに入るはずです。もちろん、「趣味のプログラム」ですから、いつのまにか食物連鎖の話を忘れてしまって、「STL を覚えた」だけになってしまったとしても、それはそれで「面白かったし、有意義だった」という考え方もあると思います。ですが、やはり「ライブラリの使い方」を考える時間があるのなら、「本質的な部分」に目を向けたほうが有意義だと思います。 さて、質問者の方は「とりあえず配列でテストをしてみた」と言っています。つまり、STL は使わなくても「制限事項付きならなんとか動作する」わけですね。それなら、いっそ、配列で作ってしまったらいいんじゃないでしょうか? 「配列は要素数が限られてるから、今回みたいに数が決まってなかったり、あとから数が増えるときには使えないので、STL を使おうと考えたんです」と言うでしょう。それは確かに正しいです。が、たかだか(この「たかだか」は数学用語の「たかだか」です)「100単位のデータ」を扱えればいいだけなら、とりあえず1ケタ、それでも心配なら2ケタ上の 10000要素の配列を確保すればいいのです。仮に1要素のデータが10KB あるとしても、この配列のためのメモリは「たかだか 100MB」に過ぎません。実際、BLOB データを含まない、数値や文字のデータだけで 10KB というのは、1要素としてはとてもたくさんのデータだと思います。(4バイト整数で 2500個にもなります) 今日のメモリ量から考えて、100MB 程度は大したことはありません。ギガバイトクラスのメモリを搭載しているパソコンはめずらしくありませんよね。2GB のメモリのうちの 100MB は「たかだか 5%」にしか過ぎないのです。この程度のメモリをどうするか悩む暇があるのなら、「確保しちゃったほうがよほど簡単」だと思います。 つぎに、「百単位の大量なデータ」を扱うので、STL のどのクラスを選ぶかが重要だ、ということですが、これはすでに書いたように大きなポイントではありません。 なぜか?STL のパフォーマンステストをするときはたいてい 10万以上の数を相手にしています。さきほど list クラスで実測してみましたが、10万件の push_front や push_back、イテレータを使ってすべての要素にアクセスのどれもが 100ms から速いものでは 25ms で完了しています。つまり、1つの要素へのアクセスに要する時間は「1マイクロ秒」もかからないのです。 「それでもほんのわずかでも速いほうがいい」というのも、正しい考え方でしょう。では、あるプログラム全体の実行時間で 10% が STL の内部でとられていたとします。(ひとつのライブラリで 10% もの計算時間を消費する、というのは、普通では考えられないほど大きな値です) あなたがクラスを選びなおして、「STL に関して2倍の速度」のクラスを見つけたとします。実行時間はどのくらいになるかというと、10% が半分になるわけですから、5%。これに他の部分の実行時間を足して 95% になります。逆にクラス選択がよくなくて、「2倍の時間がかかる」ものを選んだとします。この場合、STL 部分が倍になって 20%、これに 90% を足しますから 110% です。 100% が 95% になっても 110% になっても、大した差とは言えません。それなら、残りの 90% の部分をアルゴリズムなどの工夫で「ほんの1割」向上するだけで、このプログラムは 91% の実行時間で動作することになります。半分にできれば 55% です。どうせ頭と時間を使うのなら、「STL 選び」よりも「もっと速いアルゴリズム」に使うほうが楽しいですよね。実際のプログラムでは STL だけで 10% もの時間を消費してしまうことはありえません。たぶんかなり多く見積もっても、たかだか 2%、現実的なところでは 0.1%以下でしょう。多少、クラス選択を間違えたところで、全体の実行時間の中では誤差です。ストップウォッチを握りしめないとわからない程度の差をつめるために、プログラム作成が止まったままになってしまったのではもったいないと思いませんか? 最後に「vectorなどは削除・挿入などにかなりの時間がかかると聞いていました」ということですが、なるほど、よく勉強しているようですね。事前にいろいろ調べるのはいいことだと思います。でも、ちょっと頭でっかちになってるようですね。速い、遅い、と論議したところで、アクセスに要する時間はマイクロセカンドの単位です。100万回のアクセスでやっと1秒なのですから、大した問題ではありません。こういうところこそ、テストしてみるべきです。さらに、「かなりの時間がかかる」というのは、あくまでも大量のデータを相手にした場合の話で、計算機の世界で「大量」というのは、100とか1000ではありません。少なくとも数十万とか、最近なら数億などの単位です。このように「要素が1ケタ増えた時」などの計算時間を見積もるのにつかわれるのが「オーダー」です。 STL など、標準ライブラリはさすがによく作られていて、「悪くても N のオーダー」、いいものは「Log N のオーダ」もしくは「要素数に寄らず一定」です。Log N のオーダーというのは、実はかなり優秀で、要素数が1ケタ増えても計算時間は3倍程度にしかなりません。アルゴリズムが悪い場合、オーダーは N^2 から N^3 になることがありますから、N や Log N なら、「とてつもなく優秀」なアルゴリズムと言ってもいいのです。 質問者の悩んでいる「100単位の要素数」は最小単位の「1」と比較しても、わずか2ケタの差しかありません。この程度なら、N でも Log N でも数倍程度の差にしかならないのです。そして、計算時間全体に占める割合から考えると、STL のところで数倍程度の差がついたところで、全体の時間としては誤差の範囲になります。結論から言うと「どれを選んでもいっしょ」という答えになります。 最後になりますが、STL の中で list は vector と同じくらいよく使われるメジャーなクラスです。「そもそも、STL を使ってる人がいない」という話はともかく、STL 使いの中では多用されるほうだと思って間違いないでしょう。また、これが大事なポイントですが、STL はクラスを変えても要素へのアクセスのしかたがほとんど/まったく変わらないことが特徴です。つまり、とりあえずどれかの STL で作っておいて、あとで STL クラスだけ変更、ということが比較的簡単にできます。そういう意味でも、「どの STL にしようかなー」と悩んでしまってプログラムが進まない、というのは、あまりにももったいない、と思います。 「趣味のプログラムなんだから、好きなように楽しめばいい」と、思いましたが、あえていろいろと書いてみました。テストをしながらプログラムを進めている点など、とても「すじがいい」と思うので、あえて細かいこともいいましたが、言いたかったことは「本当に大事なことってなに?」ってことです。 「要素数が確定してないから、とりあえず必要量の2ケタ上ぐらい確保してしまえ」、「STL の使い方を悩んでいる時間があれば、配列でやっちゃえ」など、自分でも乱暴なところはかなりあると思っていますが、こんなところで止まっている時間があるのなら、ぜひ「食物連鎖の世界」を早く見たいものだ、と思ってあえて突っ込んでみました。お役にたてば幸いです。

morogon
質問者

お礼

ごもっともな意見です。 趣味の範疇なら、listでもvectorでも配列変数でも良かったですね。 listの良し悪しは自分で使用してみて、自分なりの結論を出したいと思います。 GOOD-Frさんの言うとおり、私の意識は自分の思い描いたプログラムを作るよりも、 一般的で効率の良いプログラムを作るほうに向かっていた気がします。 自分が求めているのは食物連鎖の世界や群れのシミュレートであって、 listの良し悪し、コードの綺麗さではないことを再確認できました。 少し、この質問を延ばしすぎたのかもしれません。 とりあえず、ひとつのプログラムを作り、処理速度などを考えるときになったら、 もう一度コンテナクラスについて考えてみたいと思います。 そうなったら、もう一度質問に来るかもしれません。そのときはよろしくおねがいします。 なので、この質問は解決済みにさせて頂きます。 私自身は自分自身の答えを出したので、解決できたとは思います。 それでは、この質問に回答していただいたGOOD-Frさん、ecogilisさん どうもありがとうございましたm(_ _)m

その他の回答 (3)

  • GOOD-Fr
  • ベストアンサー率32% (83/256)
回答No.3

この勘違いは、いただけません。 > 一回、普通の配列変数で実装し、あたり判定をしてみたところ、100体でもかなりの負担がかかったので、大量のデータに入ると思っていました サンプルでプログラムを作ってみて、あらかじめパフォーマンス等を確認する、という方法はとてもいいと思います。全部できあがっていざ動作させたら、計算の終了まで 100年かかるとわかった、では、報われませんから。 ですが、質問者の方がテストしているのは「あたり判定」のテストで、この処理が重かった、ということですよね。であれば、これは STL 以前の問題のはずです。どの STL クラスを使うのがいいか、というのは、それぞれのクラスの特性もありますが、あくまでもデータの出し入れや検索する時間などの差で決めるべきことです。が、今回の場合、時間がかかっているのは「取り出したデータを加工する」部分ですから、どのクラスを選ぼうと速度に関係ありません。 テストをしながらプログラムを進めるのはとてもいいことですが、テストの結果を正しく解釈しなければテストの意味がありません。質問者がおっしゃっていることは「データの格納方法にかかわらず、データの処理が重い」ということです。この処理に時間がかかるから「100件は大量のデータであり、STL で処理したらもっと重くなるに違いない」という考察は残念ながら的外れですね。

morogon
質問者

お礼

ごめんなさい、これは私の回答の仕方が誤っていました。 この質問の趣旨は、処理の重さというよりは、 通常、プログラムでこのような量のデータを管理する場合、どのような方法で管理しているのか。 ということと、 一般的にlistクラスは使うのか。 ということでした。 私は、少なくともこのプログラムでは100単位のデータは大量のデータと判断していました。 それは、言った通り当たり判定で処理が重かったからです。 しかし、これは管理方法とはまったく違う問題で、処理を軽くすることは出来る、とはわかっていました。 ただ、当たり判定というSTL等とはまったく関係のない処理で、 データが大量か否かを判断し、管理の方法での質問や回答に持ち出したことは間違っていました。 ここら辺は余り深く考えていませんでした。ごめんなさい。

  • GOOD-Fr
  • ベストアンサー率32% (83/256)
回答No.2

> このようなプログラムの場合、listクラスを使うのは正しいでしょうか? まちがいではないでしょう。 が、これだけでは判断できません。要求されているのは「データを途中で追加・削除することのできる」ということだけです。それなら、list でなくても、deque でも map でも set でも vector でもかまわないことになります。「百単位の大量なデータ」ということですが、この程度は「大量」には入らないので、どれを使ってもパフォーマンスも大差ないでしょう。 > いままでlistクラスを使ったプログラムは一度も見たことがありません。 そうですか? Java なので厳密には STL ではありませんが、List を使っているのとか見かけますけどね。

morogon
質問者

お礼

vectorなどは削除・挿入などにかなりの時間がかかると聞いていましたが、あまり変わらない(?)ようですね。 一回、普通の配列変数で実装し、あたり判定をしてみたところ、 100体でもかなりの負担がかかったので、大量のデータに入ると思っていました。 恐らく、クイックソートなどを使えばもう少し速くなると思うので とりあえずはlistクラスでやってみたいと思います。 回答ありがとうございました。

  • ecogilis
  • ベストアンサー率60% (12/20)
回答No.1

こんにちわ。 listは、追加と削除の操作を高速に行う目的で考案されましたので、そのような操作は高速ですが、代わりにインデックスによる管理がされませんので、ランダムアクセスに向きません。 また、オンメモリ操作になるので、生物1固体あたりのデータ量と、個体数の最大を併せてメモリ内に収まりそうか、も判断の基準のひとつだと思います。 ランダムアクセスが必要無くデータ量としても少量であるならlistでいいと思います。

morogon
質問者

お礼

回答ありがとうございます 恐らくランダムアクセスは必要ありませんので、 listクラスを使ってみようと思います。

関連するQ&A

  • 食物連鎖の問題です

    ある草原で植物、草食動物、肉食動物の食物連鎖のつりあいが保たれている時、草食動物が何らかの理由で増えた場合、その後の生物の数はどう変化しますか?

  • 食物連鎖についての理科の問題を教えて下さい

    ある草原で植物、草食動物、肉食動物の食物連鎖のつりあいが保たれている時、草食動物が何らかの理由で増えた場合、その後の生物の数は一時的にどう変化しますか? (1)肉食動物が増えて、植物も増えるので、草食動物はさらに増える。 (2)肉食動物が増えて、植物が減るので、草食動物は減っていく。 (3)肉食動物は減り、植物も減るので、草食動物は減っていく。 (4)肉食動物は減り、植物は増えるので、草食動物はさらに増えていく。

  • 鮫とシャチではどちらが食物連鎖の頂点に立っているのでしょうか?

    鮫とシャチではどちらが食物連鎖の頂点に立っているのでしょうか? どちらも大形で肉食性の海洋生物ですがどちらが強いのですか? または生息域とか、エサの種類で棲み分けがあるのでしょうか?

  • プリミティブ以外のデータ型が分からないので教えて

    class ★★<Object, Integer, List<■■>> ・この時、List<■■>のデータ型を何と呼ぶのでしょうか? (配列型? クラス型? ユーザー定義型? それ以外?) ・「ジェネリクスで指定できる型」と「普通に指定できる型」に違いはありますか? (ジェネリクスでしか指定できない、みたいな型はある?) ・「List<データ型>」の「データ型」として指定できる内容には、どんなものがあるのでしょうか? (ユーザー定義クラス?)

    • ベストアンサー
    • Java
  • C言語で使うことの出来る配列のLIB

    C言語から使うことの出来るSTLのコンテナクラスのようなものはありますでしょうか? 配列の追加、削除、検索、更新を高速で処理したいので(LIST構造)、汎用的に使えるLIBのようなものがあれば教えていただきたいです。

  • STLのlistで重複するものだけを取り出す方法

    C++でVC++7.0を使用してプログラミングを学んでます。 ひとつハマっているのですが…、 STLのlistを利用して、重複するデータのみを一つにしたlistにしたいです。 例えば std::list<std::string> [1] bbb [2] aaa [3] bbb [4] ccc [5] eee [6] ddd [7] bbb [8] ccc と格納されたlistがあった場合に、 [1] bbb [2] ccc と2つ以上あるデータを1つのみ格納するようにしたいです。 重複するデータを省く処理なら思いつくのですが… (.sort()で重複するデータを並べ、.unique()で重複するデータを削除する) 上記のようなことは可能でしょうか? 何か有効な案がありましたら是非ご教授下さい!

  • エクセル ドロップダウンリスト 項目作成

    【やりたい事】エクセルで、『ある列の項目(下記例:A列)』から 『条件が一致した(下記例:C列で"肉食")』項目だけドロップダウンリスト『ライオン、トラ、ヒョウ(下記例:A列の名前)』を作成したい。 ドロップダウンリストは、同じsheetの別の列(全て)に表示させてい。 ※A列は、任意に入力します。 ※B列は、意味ここでは意味ない列になります。 ※C列は、別のシートでプルダウンリスト"肉食"、"草食"を選択しています。 ※D列は、現在途中の条件出しを行っていますが、うまくいっていません。 ※Z列に「プルダウンリスト(肉食動物名一覧)」を表示させたい。 ●プルダウンリスト条件  Z列:"肉食"の時、A列の名前だけを表示(※空白は、削除したい) 【エクセル例】 -------------------------------   A列    B列    C列   D列  ...  Z列 1 動物名  地域区別  肉食か?       肉食動物名 2 ライオン アフリカ  肉食   ライオン  [プルダウンリスト] 3 カバ    アフリカ  草食         [プルダウンリスト] 4 シマウマ アフリカ  草食         [プルダウンリスト] 5 トラ    アジア   肉食    トラ   [プルダウンリスト] 6 ヒョウ   アフリカ  肉食    ヒョウ  [プルダウンリスト] 7 うさぎ   いろいろ  草食         [プルダウンリスト] 8 パンダ   中国    草食         [プルダウンリスト] ------------------------------- ※D列は、現在行ったやり方です。 しかし、空白欄(D3,D4,D7,D8)がドロップダウンリストに表示されてしまう。 D列の各行で条件を出しをしている。 現在、[D2]:=IF((C2="肉食"),A2) [D3]:=IF((C3="肉食"),A3) 名前付け:D2:D8を「肉食動物」として、 「データツール」>「データの入力規則」で、 「入力値の種類:リスト」の「空白を無視する」のオフにして、 「元の値」=肉食動物(D2:D8)としていますが、プルダウンリストに「空白」も表示されており、選択しづらいです。 プルダウンリスト(例)では --- ライオン (空白) (空白) トラ <<以下省略>> --- と、空白がでています。 やり方、設定方法を間違っているかもしれません。 何方か、お教えください。

  • セシウムについて

    以前も同じ様な質問をさせて頂きましたがもう一度お願いします。 セシウムはそのままだと半減期は30年と言われています。 しかし体内に取り込まれるとカリウムと同じで水溶性の酸化塩となって体外に排出されやすくなる為に体内での半減期が70日であるらしいのですがそれで良いのしょうか? これは魚や海洋生物でも同様であり従って食物連鎖の頂点にあるクジラやその他肉食の魚には長く留まらないと言うのが前回の回答とWikiによる結論であった様な気がします。 そう考えて良いのでしょうか?

  • List<DataClass>からデータ抽出

    javaでプログラミングを始めたのですが、人のプログラムを読んでいてわからない所があります。 まずデータクラスとして「GPSData」があり、これは2つの値のsetterとgetterを持っています。 public class GpsData { private float lat; private float lon; public float getLat() {return lat;} public void setLat(float lat) {this.id = lat;} public float getLon() {return lon;} public void setLon(float lon) {this.id = lon;} } GPSDaoというクラスがselectAllというメソッドを持っており、これはDBのGPSテーブルの値を取得し、List<GPSData>を返します。 以下のようにまずはlistをnewして、その中にselectAll()で取得したList<GPSData>を代入する所までは記述できたのですが、このあとどうしたらlistの中のデータをsetterとgetterで取り出せますか? GpsDao gdao = new GpsDao(); List<GpsData> list = gdao.selectAll(); 「list.」と書いても、「デフォルト・プロポーザルがありません」となってしまいます。

    • ベストアンサー
    • Java
  • 進化した生物ほど未熟な状態で生まれてくるってどういうこと?

    先日、このQ&Aで以下のような質問をしました。 Q 鶏の雛は孵化してからすぐに自分で餌をついばむが、ツバメの雛は巣の中で親が餌をくれるのを待っている。   この違いを専門用語でなんと言いますか?   またどちらがより進化した生物ですか? A 早成性、晩生性、または離巣性・留巣性とも言う。   赤裸で生まれる晩成性は新しい生き方なのでしょう。 ここでまた疑問がわきました。  誕生した後、成長するために親の負担が少なく、すぐに自立歩行したり、自分で餌をとったり、外敵が襲ってきても可能な限り自分で逃げることが出来る生物ほど、原始に近い生物であり、  逆に誕生した後も親から餌をもらったり、自立歩行・自立行動が出来ず巣や棲家の中に庇護されて外敵から守ってもらったりする期間(子育て期間とでも言うべきか)が長ければ長いほど進化した生物、ということになります。  動物紹介の番組などではよく次のような説明がなされます。 「草食獣は生まれてすぐに自立歩行する。野生の草食獣は肉食獣に襲われたとき、自分の足で逃げる以外の方法がないからだ。  肉食獣は生まれた後、親に守られながら生長期間を過ごす。野生獣の食物連鎖の頂点に位置する彼らは外敵が少ないので親が外敵から守ってやることが出来るからだ。」 しかし「進化」という言葉の捕らえ方の問題になるかもしれませんが、「親に近い状態」で誕生する生物が原始に近い生物であり、「未熟な状態」で誕生するというのであれば逆だと思うのですが。 未完全な状態で生まれて、親の手を煩わせて子育てさせて、死亡率の高い乳幼児期間を母体(あるいは卵)の外で過ごすのであれば、これは「進化した生物」とは言えないのでは?  子育て期間は親は子に懸かりっきりになってしまい、自分のことは後回しです。下手すれば親子共倒れになります。 むしろ「進化した生物」であれば、細菌の細胞分裂のように、親とそっくりのコピー状態で生まれてきてもおかしくないと思いますが。 なぜ未完全な状態で生まれてくる生物ほど「進化した生物」なのでしょうか?