回答編集履歴
2
探索処理を追記しておく
answer
CHANGED
@@ -43,4 +43,89 @@
|
|
43
43
|
【効率が良い(?)チェック処理 と それを用いるフロー という複数個の要素を同時並行的に用意する】
|
44
44
|
のが厄介であれば,それよりも,
|
45
45
|
【「細部がとりあえず版だけども全体が動く状態」を一旦作ってから → その後で「とりあえず」部分をよりマシな実装に置き換える】
|
46
|
-
という手順にした方が,一度に相手にする要素が減るので楽になるのでは? という話です.
|
46
|
+
という手順にした方が,一度に相手にする要素が減るので楽になるのでは? という話です.
|
47
|
+
|
48
|
+
---
|
49
|
+
|
50
|
+
---
|
51
|
+
|
52
|
+
[追記]
|
53
|
+
|
54
|
+
The code example shown below finds the "minimum vertex cover" using the above method.
|
55
|
+
With this search process using queue, the "vertex cover" first found becomes (one of) the "minimum vertex cover".
|
56
|
+
|
57
|
+
```C++
|
58
|
+
//これは単に頂点群を表示するだけの作業関数
|
59
|
+
inline void ShowVtxs( const std::vector<int> &Vtxs )
|
60
|
+
{
|
61
|
+
std::cout << "{ ";
|
62
|
+
for( auto i : Vtxs ){ std::cout << i << " "; }
|
63
|
+
std::cout << "}";
|
64
|
+
}
|
65
|
+
|
66
|
+
//探索処理用のデータ
|
67
|
+
struct WorkData
|
68
|
+
{
|
69
|
+
std::vector< int > CurrVtxs; //頂点被覆か否かを調べる頂点集合
|
70
|
+
std::vector< int > RestVtxs; //CurrVtxが頂点被覆ではなかった場合にCurrVtxsに追加する頂点候補群
|
71
|
+
};
|
72
|
+
|
73
|
+
int main(void)
|
74
|
+
{
|
75
|
+
//とりあえず接続行列があるとして…
|
76
|
+
con_matrix M;
|
77
|
+
|
78
|
+
//--------------------------
|
79
|
+
//Queueを用いた幅優先探索
|
80
|
+
//
|
81
|
+
// 頂点個数が少ない側からチェックしていけば
|
82
|
+
// 最初に見つかった頂点被覆は最小頂点被覆(のひとつ)である
|
83
|
+
|
84
|
+
std::queue< WorkData > Queue;
|
85
|
+
{//Queueに探索処理のとっかかりとなるような最初のデータを入れる
|
86
|
+
WorkData WD;
|
87
|
+
{//最初のデータは{CurrVtxsが空で,RestVtxsが全ての頂点の集合}となるデータ
|
88
|
+
int n = M.get_vertex_num();
|
89
|
+
WD.RestVtxs.resize(n);
|
90
|
+
for( int i=0; i<n; ++i )WD.RestVtxs[i] = i;
|
91
|
+
}
|
92
|
+
Queue.push( WD );
|
93
|
+
}
|
94
|
+
|
95
|
+
while( !Queue.empty() )
|
96
|
+
{
|
97
|
+
WorkData &WD = Queue.front();
|
98
|
+
|
99
|
+
{//WDの中身を表示
|
100
|
+
std::cout << "Curr";
|
101
|
+
ShowVtxs( WD.CurrVtxs );
|
102
|
+
std::cout << " , Rest";
|
103
|
+
ShowVtxs( WD.RestVtxs );
|
104
|
+
std::cout << "\n";
|
105
|
+
}
|
106
|
+
|
107
|
+
//WD.CurrVtxsが頂点被覆かどうかをチェック
|
108
|
+
if( M.Is_Covering( WD.CurrVtxs ) )
|
109
|
+
{ //頂点被覆が見つかったらその時点で探索終了
|
110
|
+
std::cout << " Found !!\n";
|
111
|
+
break;
|
112
|
+
}
|
113
|
+
|
114
|
+
//WD.CurrVtxsが頂点被覆でなかった場合:
|
115
|
+
//{WD.RestVtxs内の頂点の1つをWD.CurrVtxs側に移した形のデータ}群 をQueueに入れる
|
116
|
+
for( auto i=WD.RestVtxs.begin(); i!=WD.RestVtxs.end(); ++i )
|
117
|
+
{
|
118
|
+
WorkData NextPtn;
|
119
|
+
NextPtn.CurrVtxs = WD.CurrVtxs;
|
120
|
+
NextPtn.CurrVtxs.push_back( *i );
|
121
|
+
NextPtn.RestVtxs.assign( i+1, WD.RestVtxs.end() ); //※以降の探索に重複パターンを作らないようにRestVtxsの中身を絞っておく
|
122
|
+
Queue.push( NextPtn );
|
123
|
+
}
|
124
|
+
|
125
|
+
Queue.pop();
|
126
|
+
}
|
127
|
+
|
128
|
+
std::cout << "END" << std::endl;
|
129
|
+
return 0;
|
130
|
+
}
|
131
|
+
```
|
1
誤変換修正
answer
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
---
|
4
4
|
|
5
|
-
とりあえず con_matrix が持っている行列の値を外部から見る方法が設けられていない様子ですので, con_matrix に「ある頂点集合が頂点被覆か否かを調べる」というメソッドを追加することを考えて
|
5
|
+
とりあえず con_matrix が持っている行列の値を外部から見る方法が設けられていない様子ですので, con_matrix に「ある頂点集合が頂点被覆か否かを調べる」というメソッドを追加することを考えてみます.
|
6
6
|
例えば…
|
7
7
|
|
8
8
|
```C++
|
@@ -38,7 +38,7 @@
|
|
38
38
|
というのは出てきていません.
|
39
39
|
|
40
40
|
おそらくはこのコード例みたいな「最も愚直なチェック」よりも何かしらの意味でマシな方法論を考えておられる(配列はその話の中で出てくる)のだろうと推測しますが,
|
41
|
-
それをすぐに実装できないのであれば,**とりあえず今考えているその方法の実装は保留とし,このような「力業で効率悪そうだけどまずは動くんじゃない?」という代替実装を用意して,
|
41
|
+
それをすぐに実装できないのであれば,**とりあえず今考えているその方法の実装は保留とし,このような「力業で効率悪そうだけどまずは動くんじゃない?」という代替実装を用意して,先に全体の処理フローを完成させる** ことを行ってはどうでしょうか.
|
42
42
|
|
43
43
|
【効率が良い(?)チェック処理 と それを用いるフロー という複数個の要素を同時並行的に用意する】
|
44
44
|
のが厄介であれば,それよりも,
|