←
▼
▲
Function CreateGraphVertex( in_out_Graph as array of GraphVertexClass ) as GraphVertexClass
グラフの頂点を生成して、グラフに追加します。
【引数】
in_out_Graph
生成した頂点を追加するグラフ
返り値
生成した頂点
ソース
→ vbslib.vbs
生成された頂点のオブジェクトは、in_out_Graph 配列の最後に追加されます。
返り値の GraphVertexClass::Index 変数には、その配列番号が代入されます。
返り値の GraphVertexClass::Item 変数には、Empty が代入されます。
→ T_Tree.vbs
テスト
T_GraphVertexClass
サンプル
graph = Array( )
Set vertex1 = CreateGraphVertex( graph )
Set vertex = new UserDefinedVertexClass
Set vertex1.Item = vertex
Assert graph( vertex1.Index ) is vertex1
CreateGraphVertex
←
▼
▲
Sub SetNDEdgeInGraph( in_out_Graph as array of GraphVertexClass,
in_BaseIndex as integer, in_TargetIndex as integer, in_EdgeObject as variant )
グラフの辺にあたる変数に値を設定します。(無向グラフ)
【引数】
in_out_Graph
設定対象のグラフ
in_BaseIndex
辺の頂点番号。
ソース
→ vbslib.vbs
in_TargetIndex
辺のもう片方の頂点番号
in_EdgeObject
辺にあたる変数に格納する値やオブジェクト
ND は、無向グラフの略語です。
双方向に頂点の参照を設定します。
in_BaseIndex と in_TargetIndex には、CreateGraphVertex で登録された頂点番号を指定してください。
in_EdgeObject には、数値、文字列、Empty なども指定可能です。
1つの辺に、有向グラフと無向グラフを共存することはできません。 異なる辺ならできます。
→ T_Tree.vbs
テスト
T_GraphVertexClass
関連
有向グラフ版
サンプル
graph = Array( )
Set vertex1 = CreateGraphVertex( graph )
Set vertex1.Item = new UserDefinedVertexClass
Set vertex2 = CreateGraphVertex( graph )
Set vertex2.Item = new UserDefinedVertexClass
Set new_edge = new UserDefinedEdgeClass
SetNDEdgeInGraph graph, vertex1.Index, vertex2.Index, new_edge
Set edge = GetNDEdgeInGraph( graph, vertex1.Index, vertex2.Index, Empty )
Assert edge is new_edge
SetNDEdgeInGraph
←
▼
▲
Sub SetEdgeInGraph( in_out_Graph as array of GraphVertexClass,
in_BaseIndex as integer, in_TargetIndex as integer, in_EdgeObject as variant )
グラフの辺にあたる変数に値を設定します。(有向グラフ)
【引数】
in_out_Graph
設定対象のグラフ
in_BaseIndex
辺の元の頂点番号
ソース
→ vbslib.vbs
in_TargetIndex
辺の先の頂点番号
in_EdgeObject
辺にあたる変数に格納する値やオブジェクト
→ T_Tree.vbs
テスト
T_GraphVertexClass
関連
無向グラフ版
片方向の頂点の参照を設定します。 逆方向には辺が存在しないようにできます。
in_BaseIndex と in_TargetIndex には、CreateGraphVertex で登録された頂点番号を指定してください。
in_EdgeObject には、数値、文字列、Empty なども指定可能です。
1つの辺に、有向グラフと無向グラフを共存することはできません。 異なる辺ならできます。
サンプル
graph = Array( )
Set vertex1 = CreateGraphVertex( graph )
Set vertex1.Item = new UserDefinedVertexClass
Set vertex2 = CreateGraphVertex( graph )
Set vertex2.Item = new UserDefinedVertexClass
Set new_edge = new UserDefinedEdgeClass
SetEdgeInGraph graph, vertex1.Index, vertex2.Index, new_edge
Set edge = GetEdgeInGraph( graph, vertex1.Index, vertex2.Index, Empty )
Assert edge is new_edge
SetEdgeInGraph
←
▼
▲
Function GetNDEdgeInGraph( in_out_Graph as array of GraphVertexClass,
in_BaseIndex as integer, in_TargetIndex as integer, in_EdgeIfNotFound as variant ) as variant
グラフの辺にあたる変数に格納されている値を返します。(無向グラフ)
【引数】
in_out_Graph
対象のグラフ
in_BaseIndex
辺の頂点番号
ソース
→ vbslib.vbs
in_TargetIndex
辺のもう片方の頂点番号
返り値
辺にあたる変数に格納されている値やオブジェクト
→ T_Tree.vbs
テスト
T_GraphVertexClass
ND は、無向グラフの略語です。
in_BaseIndex と in_TargetIndex を入れ替えても同じ変数を参照します。
1つの辺に、有向グラフと無向グラフを共存することはできません。 異なる辺ならできます。
in_BaseIndex と in_TargetIndex が in_out_Graph の配列番号の範囲外であったときは、エラーになります。
in_EdgeIfNotFound に指定する値を、辺がオブジェクトなら Empty、オブジェクトでないなら Nothing に
すると、返り値を格納するときに Set か Let (Setなし) の違いによって、エラーを発生させることが
できます。
関連
有向グラフ版
サンプル
Set edge = GetNDEdgeInGraph( graph, vertex1.Index, vertex2.Index, Empty )
in_EdgeIfNotFound
辺が見つからなかったときの返り値
←
▼
▲
Function GetEdgeInGraph( in_out_Graph as array of GraphVertexClass,
in_BaseIndex as integer, in_TargetIndex as integer, in_EdgeIfNotFound as variant ) as variant
グラフの辺にあたる変数に格納されている値を返します。(有向グラフ)
【引数】
in_out_Graph
対象のグラフ
in_BaseIndex
辺の元の頂点番号
ソース
→ vbslib.vbs
in_TargetIndex
辺の先の頂点番号
返り値
辺にあたる変数に格納されている値やオブジェクト
→ T_Tree.vbs
テスト
T_GraphVertexClass
関連
無向グラフ版
1つの辺に、有向グラフと無向グラフを共存することはできません。 異なる辺ならできます。
辺が存在しなければ、エラーになります。 逆方向には辺が存在しないことがあります。
in_BaseIndex と in_TargetIndex が in_out_Graph の配列番号の範囲外であったときは、エラーになります。
in_EdgeIfNotFound に指定する値を、辺がオブジェクトなら Empty、オブジェクトでないなら Nothing に
すると、返り値を格納するときに Set か Let (Setなし) の違いによって、エラーを発生させることが
できます。
サンプル
Set edge = GetEdgeInGraph( graph, vertex1.Index, vertex2.Index, Empty )
in_EdgeIfNotFound
辺が見つからなかったときの返り値
←
▼
▲
Function GetDirectionIndex( in_TargetVertexIndex as intege, in_OppositeVertexIndex as intege )
辺の変数の中にある頂点に対応する配列の配列番号 0 か 1 のどちらかを返します。
【引数】
in_TargetVertexIndex
対象の頂点に対応するグラフ全体の頂点配列番号
in_OppositeVertexIndex
反対側の頂点に対応するグラフ全体の配列番号
ソース
→ vbslib.vbs
返り値
辺の変数の中にある頂点に対応する配列の配列番号 0 か 1
辺ごとに異なる頂点のデータは、辺の中にある要素数2の配列に格納しますが、
どちらの頂点がどちらの配列要素に対応するかを、本関数で調べます。
グラフの配列番号が小さいほうを配列番号0、大きいほうを配列番号1としています。 これは、有向
グラフでも無向グラフでも同じです。
辺ごとに異なることがない頂点のデータは、頂点のクラスのメンバーにします。
1
0
2
3
4
Class TrainLineClass
Public TrainTime '// 発車時刻 as array(0..1) of Date
Private Sub Class_Initialize()
Me.TrainTime = Array( Empty, Empty )
End Sub
End Class
Set edge = new TranLineClass
edge.TrainTime( GetDirectionIndex( 2, 4 ) ) = CDate( "12:00" )
SetNDEdgeInGraph graph, 2, 4, edge
Set edge = GetNDEdgeInGraph( graph, 4, 2, Empty )
Assert edge.TrainTime( GetDirectionIndex( 2, 4 ) ) = CDate( "12:00" )
サンプル
番号は、グラフ全体の頂点配列番号
12:00発
→ T_Tree.vbs
テスト
T_GraphVertexClass
GetDirectionIndex
GetDirectionIndex
←
▼
▲
Sub BreadthFirstSearch( in_Array as array of GraphVertexClass, in_FirstIndex as integer,
out_QueuedNodes as array of integer,
in_CompareFunction as function, ref_ParameterOfCompareFunction as variant,
in_Option as Empty or boolean )
幅優先探索(最短経路探索)を行います。 頂点ごとにコールバック関数を呼び出します。
【引数】
in_Array
頂点の配列
in_FirstIndex
開始頂点の(in_Array の)配列番号
頂点を探索するときにコールバックされる
in_CompareFunction
(出力) 探索した/探索予定の頂点の配列番号の配列
out_QueuedNodes
in_CompareFunction の第3引数
in_Option
Empty または g_VBS_Lib.NotResetFoundFlag
ref_ParameterOfCompareFunction
テスト
→ T_Tree.vbs
T_BreadthFirstSearch
ソース
→ vbslib.vbs
an_array(0).Item
an_array(4).Item
an_array(5).Item
an_array(3).Item
an_array(1).Item
an_array(2).Item
ReDim an_array( 5 )
For Each t In DicTable( Array( _
"Index", "AdjacentIndexes", "ParentIndex", Empty, _
0, Array( 1, 3, 2 ), Null, _
1, Array( 5, 4 ), 0, _
2, Array( ), 0, _
3, Array( ), 0, _
4, Array( ), 1, _
5, Array( ), 1 ) )
i = t("Index")
Set an_array(i) = new GraphVertexClass
Set an_array(i).Item = Nothing
an_array(i).AdjacentIndexes = t("AdjacentIndexes")
Next
BreadthFirstSearch an_array, 0, queued, Empty, Empty, Empty
'//(out) queued
Assert IsSameArray( queued, Array( 0, 1, 3, 2, 5, 4 ) )
サンプル
相互参照しているとき、すでに探索済みの頂点は、探索しません。 エラーにもなりません。
コールバック関数 in_CompareFunction の第1引数と第2引数には、in_Array 配列の要素である
GraphVertexClass 型のオブジェクトが渡ります。 第2引数より第1引数のほうが、探索開始頂点に
近いです。 ただし、最初のコールバックでは、第1引数は Empty、第2引数は探索開始頂点です。
コールバック関数で 0 を返すと、探索を途中で終了します。
見つかった頂点を出力するときは、コールバック関数の第3引数経由で出力してください。 第3引数は、
ref_ParameterOfCompareFunction 引数の参照なので、出力できます。
参考
→ 幅優先探索 (グラフ)
in_Array 引数に、GraphVertexClass の Item, AdjacentIndexes メンバー変数が設定済みのオブジェクトの
配列を指定します。
か Empty
コールバック関数が呼び出されると、コールバック関数が呼び出されたときの対象頂点の
out_QueuedNodes 引数に指定した変数には、コールバック関数が呼び出されたときの対象頂点と、
それに隣接する頂点が格納されます。 重複する頂点は格納されません。 対象頂点と隣接する
頂点とは、たとえば、下記の頂点 2 についてコールバックされたとき、0, 1, 4 が隣接する頂点です。
0, 2, 1 と探索して終了した場合、out_QueuedNodes 引数に指定した変数には、0, 2, 1, 4 が格納
されますが、探索済みの頂点は、0, 2, 1 のみです(判別方法は後述)。
どうかを判定できます。 開始頂点の ParentIndex は Null が設定されます。 上記のグラフで、0, 2, 1
と探索して終了した場合、各頂点の ParentIndex は、次のようになります。
::ParentIndex が設定されます。 この変数が Empty でないかどうかで、探索済みか
BreadthFirstSearch
in_Option 引数に g_VBS_Lib.NotResetFoundFlag を指定すると、内部の先頭で
を呼び出さなくなります。
1
0
2
3
4
out_QueuedNodes = Array( 0, 2, 1, 4 )
Vertex(0).ParentIndex = Null
Vertex(1).ParentIndex = 2
Vertex(2).ParentIndex = 0
Vertex(3).ParentIndex = Empty
Vertex(4).ParentIndex = Empty
関連
→ 幅優先探索 (グラフ)
コールバック関数 in_CompareFunction で 0 を返すと、探索を終了します。
0
1
2
3
4
5
赤色の数字は、コールバック
される順番を表します。
←
▼
▲
Sub DepthFirstSearch( in_Array as array of GraphVertexClass, in_FirstIndex as integer,
in_CompareFunction as function, ref_ParameterOfCompareFunction as variant,
in_Option as Empty or boolean )
深さ優先探索を行います。 頂点ごとにコールバック関数を呼び出します。
【引数】
in_Array
頂点の配列
in_FirstIndex
開始頂点の(in_Array の)配列番号
頂点を探索するときにコールバックされる
in_CompareFunction
in_CompareFunction の第3引数
in_Option
Empty または g_VBS_Lib.NotResetFoundFlag
ref_ParameterOfCompareFunction
in_Array 引数に、GraphVertexClass の Item, AdjacentIndexes メンバー変数が設定済みのオブジェクトの
配列を指定します。
か Empty
参考
→ 深さ優先探索 (グラフ)
テスト
ソース
→ T_Tree.vbs
T_DepthFirstSearch
→ vbslib.vbs
コールバック関数 in_CompareFunction の第1引数と第2引数には、in_Array 配列の要素である
GraphVertexClass 型のオブジェクトが渡ります。 第2引数より第1引数のほうが、探索開始頂点に
近いです。 ただし、最初のコールバックでは、第1引数は Empty、第2引数は探索開始頂点です。
コールバック関数で 0 を返すと、探索を途中で終了します。
見つかった頂点を出力するときは、コールバック関数の第3引数経由で出力してください。 第3引数は、
ref_ParameterOfCompareFunction 引数の参照なので、出力できます。
コールバック関数 in_CompareFunction で 0 を返すと、探索を終了します。
相互参照しているとき、すでに探索済みの頂点は、探索しません。 エラーにもなりません。
in_Option 引数に g_VBS_Lib.NotResetFoundFlag を指定すると、内部の先頭で
を呼び出さなくなります。
an_array(0).Item
an_array(5).Item
an_array(4).Item
an_array(2).Item
an_array(1).Item
an_array(3).Item
ReDim an_array( 5 )
For Each t In DicTable( Array( _
"Index", "AdjacentIndexes", "ParentIndex", Empty, _
0, Array( 1, 3, 2 ), Null, _
1, Array( 5, 4 ), 0, _
2, Array( ), 0, _
3, Array( ), 0, _
4, Array( ), 1, _
5, Array( ), 1 ) )
i = t("Index")
Set an_array(i) = new GraphVertexClass
Set an_array(i).Item = Nothing
an_array(i).AdjacentIndexes = t("AdjacentIndexes")
Next
DepthFirstSearch an_array, 0, Empty, Empty, Empty
Assert IsSameArray( queued, Array( 0, 1, 5, 4, 3, 2 ) )
サンプル
DepthFirstSearch
0
1
4
5
2
3
コールバック関数が呼び出されると、コールバック関数が呼び出されたときの対象頂点の
どうかを判定できます。 開始頂点の ParentIndex は Null が設定されます。
::ParentIndex が設定されます。 この変数が Empty でないかどうかで、探索済みか
赤色の数字は、コールバック
される順番を表します。
←
▼
▲
Function SearchSubGraphs( in_Array as array of GraphVertexClass, in_Empty as Empty )
as array of array of integer
すべての部分グラフと、辺がない頂点を列挙します。
【引数】
in_Array
頂点の配列
in_Empty
Empty を指定してください
返り値
すべての部分グラフと辺がない頂点を構成する頂点番号の配列の配列
sub_graphs = SearchSubGraphs( a_graph, Empty )
sub_graphs(0), Array( 0, 2, 4, 6 )
sub_graphs(1), Array( 1, 3, 5, 9 )
sub_graphs(2), Array( 7 )
sub_graphs(3), Array( 8 )
サンプル
→ vbslib.vbs
テスト
ソース
→ T_Tree.vbs
T_SearchSubGraphs
2
0
4
3
6
1
5
9
←
▼
▲
Function GetDistanceInGraph( in_Array as array of GraphVertexClass, in_Index as integer )
as integer
検索を開始した頂点から、指定した頂点までの間にある辺の数を返します。
【引数】
in_Array
頂点の配列
in_Index
頂点
返り値
辺の数
テスト
ソース
→ T_Tree.vbs
T_DepthFirstSearch
→ vbslib.vbs
←
▼
▲
Sub ResetSearchDataOfGraphVertex( in_out_Graph as array of GraphVertexClass )
前回探索した結果を格納する内部変数をリセットします。
【引数】
in_out_Graph
操作対象のグラフ
ソース
→ vbslib.vbs
探索を行う関数の内部から呼ばれます。
::ParentIndex を Empty に設定します。
テスト
→ T_Tree.vbs
T_BreadthFirstSearch
←
▼
▲
未対応
←
▼
▲
Sub RemoveNDEdgeInGraph( in_out_Graph as array of GraphVertexClass,
in_BaseIndex as integer, in_TargetIndex as integer )
グラフの辺にあたる変数を削除します。(無向グラフ)
【引数】
in_out_Graph
対象のグラフ
in_BaseIndex
辺の頂点番号
ソース
→ vbslib.vbs
in_TargetIndex
辺のもう片方の頂点番号
未対応。 AdjacentIndexes の調整ができていません。
ND は、無向グラフの略語です。
1つの辺に、有向グラフと無向グラフを共存することはできません。 異なる辺ならできます。
関連
有向グラフ版
←
▼
▲
Sub RemoveEdgeInGraph( in_out_Graph as array of GraphVertexClass,
in_BaseIndex as integer, in_TargetIndex as integer )
グラフの辺にあたる変数を削除します。(有向グラフ)
【引数】
in_out_Graph
対象のグラフ
in_BaseIndex
辺の元の頂点番号
ソース
→ vbslib.vbs
in_TargetIndex
辺の先の頂点番号
未対応。 AdjacentIndexes の調整ができていません。
関連
無向グラフ版
1つの辺に、有向グラフと無向グラフを共存することはできません。 異なる辺ならできます。
←
▼
▲
ツリー構造を持ったコレクションです。
TreeA_NodeClass の Item メンバーに、ユーザーが使うオブジェクトを設定します。
TreeA_NodeClass
TreeA_NodeClass
TreeA_NodeClass
TreeA_NodeClass
Item
Item
Item
Item
Item
TreeA_Class のオブジェクト(ルート)のみ
のハンドルを持っているため、TreeA_Class の
オブジェクトが参照されなくなったときに、すべてのノードが削除されます。
Class SampleClass
Public TreeNode
End Class
Sub Main()
Set tree = new_TreeA_Class( new SampleClass )
Set tree.Item.TreeNode = tree.TreeNode '// Don't set "tree"
Set child_item = new SampleClass
Set child_item.TreeNode = Me.TreeNode.AddNewNode( child_item )
End Sub
サンプル
参考
テスト
→ T_Tree.vbs
T_TreeA_1
ソース
→ vbslib.vbs
のキーや配列番号で参照することで、オブジェクト同士の直接の相互参照をしなければ、
TreeA_Class を使用しなくてもよいかもしれません。
注意
←
▼
▲
Function new_TreeA_Class( Item ) as TreeA_Class
ツリーのルートを生成します。
【引数】
Item
ルートのノードと関連付けるオブジェクト、または、Nothing
返り値
ツリーのルート
ソース
→ vbslib.vbs
←
▼
▲
.TreeNode
ツリー構造のルート。
相互参照するときのルート ノード
.Item
ノードと関連するオブジェクト
.ParentNode
Nothing
.ChildNodes
直下の子ノードの配列
.ParentItems
親ノードの Item の配列。 Me のノードは含まない。 最後はルート。
.ChildItems
末端まで含めた子ノードの配列
TreeA_Class のオブジェクト(ルート)のみ
のハンドルを持っているため、TreeA_Class の
オブジェクトが参照されなくなったときに、すべてのノードが削除されます。 (参照されていないノードのみ)
ソース
→ vbslib.vbs
←
▼
▲
ツリー構造のノード。 ルート(根ノード)、ブランチ(内部ノード)、リーフ(葉ノード)。
.TreeNode
相互参照するときのルート ノード。 Me と同じ
.Item
ノードと関連するオブジェクト
.ParentNode
親ノード
.ChildNodes
直下の子ノードの配列
.ParentItems
親ノードの Item の配列。 Me のノードは含まない。 最後はルート。
.ChildItems
末端まで含めた子ノードの配列
ソース
→ vbslib.vbs
←
▼
▲
テスト
ソース
→ T_CrossFind.vbs
→ ToolsLib.vbs
CrossFindClass
.Projects
.OutElements
.OutModuleTypes
ArrayClass of
dictionary of
サンプル
<Root>
<Project name="p1">
<Module name="t11">a1, a2</Module> <Module name="t12">b1, b2</Module>
</Project>
<Project name="p2">
<Module name="t21">a1, a2</Module> <Module name="t22">b1, b2</Module>
</Project>
<Project name="p3">
<Module name="t31">a1, b1</Module> <Module name="t32">a2</Module>
<Module name="t33">b2</Module>
</Project>
<Answer>
<Element name="a1">
<ModuleType names="t11, t21">a1, a2</ModuleType>
<ModuleType names="t31">a1, b1</ModuleType>
</Element>
<Element name="a2">
<ModuleType names="t11, t21, t32">a1, a2</ModuleType>
</Element>
<Element name="b1">
<ModuleType names="t12, t22">b1, b2</ModuleType>
<ModuleType names="t31">a1, b1</ModuleType>
</Element>
<Element name="b2">
<ModuleType names="t12, t22, t33">b1, b2</ModuleType>
</Element>
</Answer>
</Root>
モジュールを構成する要素が同じかどうかで分類します。
分類したものをモジュール タイプと呼びます。
モジュール名と要素名(モジュールを構成する要素の名前)が、プロジェクトで1つである
状況で使えます。
下記サンプルの <Project> は分類する前のモジュールの構成を表します。
<Answer> は、CrossFindClass で解析した結果を表しています。
<Answer> の子要素である <Element> は、要素ごとに、所属しているモジュール タイプを
子要素に持っています。
たとえば、a1 という要素は、
・プロジェクト p1 に含まれる t11 モジュール
・プロジェクト p2 に含まれる t21 モジュール
・プロジェクト p3 に含まれる t31 モジュール
に含まれていますが、これらのモジュールは、構成要素ごとに、
・{ a1, a2 } から構成されるモジュール タイプ
・{ a1, b1 } から構成されるモジュール タイプ
に分類されます。
<Module name="t11">a1, a2</Module>
<ModuleType names="t11, t21">a1, a2</ModuleType>
→ T_CrossFind.vbs - Variable: A1.xml
参考
Set find_ = new CrossFindClass
Set project = find_.AddProject( "p1" )
project.AddModule "t11", Array( "a1", "a2" )
project.AddModule "t12", Array( "b1", "b2" )
Set project = find_.AddProject( "p2" )
project.AddModule "t21", Array( "a1", "a2" )
project.AddModule "t22", Array( "b1", "b2" )
Set project = find_.AddProject( "p3" )
project.AddModule "t31", Array( "a1", "b1" )
project.AddModule "t32", Array( "a2" )
project.AddModule "t33", Array( "b2" )
For Each element_name In find_.OutElements.Keys
echo "element_name = "+ element_name
Set element = find_.OutElements.Item( element_name )
For k=0 To element.OutModuleTypes.Count - 1
Set module_type = element.OutModuleTypes.Item(k)
echo vbTab +"module_type.Names = "+ module_type.Name
echo vbTab +"Elements = "+ new_ArrayClass( module_type.Delegate.Elements ).CSV
echo ""
Next
Next
データのサンプル:
コードのサンプル:
主な処理は、
.ModuleTypesByElement
dictionary array NameOnlyClass
(.vbs)
(.vbs)
(.vbs)
(.vbs)