忍者ブログ
  • 2019.11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 2020.01
C++のboostでgraphviz+dotを使ってみた
グラフを作りたかったので、graphvixを使ってみました。

【参考】Boost.Graph Graphviz形式で重みを出力

#include <fstream>
#include <vector>
#include <string>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
struct EdgeWithInfo
{
    int nodeS;
    int nodeE;
    int weight;
    std::string name;
};

typedef boost::adjacency_list<boost::listS, boost::vecS, boost::directedS,
                              boost::no_property, boost::property<boost::edge_all_t, EdgeWithInfo>>
    Graph;
typedef std::pair<int, int> Edge;

enum
{
    A,
    B,
    C,
    D,
    E,
    N
};

const std::string name[] = {"A", "B", "C", "D", "E"};

int main()
{
    const std::vector<EdgeWithInfo> edgeWithInfo =
        {
            {A, B, 3, "→B"},
            {A, C, 1, "→C"},
            {A, D, 4, "→D"},
            {B, E, 2, "→E"},
            {C, E, 5, "→E"},
            {D, E, 6, "→E"}};

    std::vector<Edge> edges;

    std::transform(edgeWithInfo.begin(), edgeWithInfo.end(), std::back_inserter(edges),
                   [](auto ei) {
                       return std::make_pair(ei.nodeS, ei.nodeE);
                   });

    const Graph g(edges.begin(), edges.end(), edgeWithInfo.begin(), N);

    std::ofstream file("test.dot");
    boost::write_graphviz(file,
                          g,
                          boost::make_label_writer(name),
                          [](auto &graph_) {
                              return [&graph_](std::ostream &out, auto edge) {
                                  const EdgeWithInfo &ewi =
                                      *reinterpret_cast<const EdgeWithInfo *>(&boost::get(boost::edge_all, graph_, edge));
                                  out << "[";
                                  out << "weight=" << ewi.weight << ",";
                                  out << "label=" << ewi.name;
                                  out << "]";
                              };
                          }(g));
}

digraph G {
0[label=A];
1[label=B];
2[label=C];
3[label=D];
4[label=E];
0->1 [weight=3,label=→B];
0->2 [weight=1,label=→C];
0->3 [weight=4,label=→D];
1->4 [weight=2,label=→E];
2->4 [weight=5,label=→E];
3->4 [weight=6,label=→E];
}
正攻法ではない気がするけど、まあ良しとしよう。
PR
【2019/05/04 09:22 】 | C/C++ | 有り難いご意見(3)
                                    
メディアンカット(3)
とありあえず、ええ感じになったのでwindows版のしょぼいbmpからpngに変換するツールを公開

bmp2png.exe (元ファイル).bmp (先ファイル).png [カラー色数]

(制約)RGBカラーのみ対応。カラー色数は1~256。動作保証・損害責任なし。
   別途zlib1.dll・libpng12.dllが必要。

ダウンロード(v1)カットしたまま(速い)
ダウンロード(v2)カットして近い色(遅い)

ライセンスは下記条件を満たせばフリー。

・コメントで使用した旨のメッセージ、または当記事へのブログからのリンク等
 他への紹介するメディアを所持している場合、紹介すること。

・同等の機能を満たすより良いフリーのツールが見つかったら教えてくらさい。

【2013/07/24 07:30 】 | C/C++ | 有り難いご意見(0)
                                    
メディアンカット(2)
実際にメディアンカットを実装してみた。

●オリジナル


●gimpのインデックスカラー256色


●メディアンカットv1(直方体のまま)


●メディアンカットv2(球で一番近いもの)


メディアンカットはすべてのR・G・Bで最も長いものをミディアンで切る実装。
オリジナルがなぜかWeb上では青が紫に見えてしまう。
なんか設定で変えられるのかも・・・
ローカルに保存すると青は青だ。

gimpさんはすごいです。もしかしたらパレット操作だけでなく
何か別の操作をしてるのかも。
【2013/07/22 06:42 】 | C/C++ | 有り難いご意見(0)
                                    
gccリンカの謎(2)
ldのmanに書いてあった。
           The linker will search an archive only once, at the location where
           it is specified on the command line.  If the archive defines a
           symbol which was undefined in some object which appeared before the
           archive on the command line, the linker will include the
           appropriate file(s) from the archive.  However, an undefined symbol
           in an object appearing later on the command line will not cause the
           linker to search the archive again.

           See the -( option for a way to force the linker to search archives
           multiple times.

           You may list the same archive multiple times on the command line.

           This type of archive searching is standard for Unix linkers.
           However, if you are using ld on AIX, note that it is different from
           the behaviour of the AIX linker.
というか、AIXだと違うのか!?
【2013/02/17 07:42 】 | C/C++ | 有り難いご意見(0)
                                    
gccリンカの謎
gccの-lオプションが効かない時があるのでその原因を確かめてみた。


$ gcc  pp4.c pp.c pp2.c
/tmp/ccj9EogJ.o: In function `func':
pp2.c:(.text+0x7): undefined reference to `link2'
/tmp/cchGaury.o: In function `main':
pp.c:(.text+0x11): undefined reference to `link1'
collect2: ld はステータス 1 で終了しました

こんなソースがある場合、link1とlink2を含むlibpp3.soで解決する必要がある
当初、ソース1個以上指定した後の-lオプションのみが有効かと思いきや
リンクメッセージがないと-lが効かないという話を教えてもらったので試してみた。

$ gcc  pp4.c -l pp3 pp.c pp2.c
/tmp/ccj9EogJ.o: In function `func':
pp2.c:(.text+0x7): undefined reference to `link2'
/tmp/cchGaury.o: In function `main':
pp.c:(.text+0x11): undefined reference to `link1'
collect2: ld はステータス 1 で終了しました

あら、ほんとだ。pp4.cはlink1もlink2も依存していないため
これでもエラーが起こる・・・。

$ gcc  pp4.c pp.c -l pp3 pp2.c


では、link1に依存するpp.cの後に-l pp3を移動させると
エラーはなくなった~

てっきり
/tmp/ccj9EogJ.o: In function `func':
pp2.c:(.text+0x7): undefined reference to `link2'
みたいなのが出ると思ったのだけどそうでもないらしい。
つまり・・・
-lオプションは最後に書けということですなぁ。

バージョンによっては直ってるgccもあるらしい。
【2013/02/16 20:23 】 | C/C++ | 有り難いご意見(0)
                                    
| ホーム | 次ページ>>