#--
# Copyright (c) 2006 Shawn Patrick Garbett
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice(s),
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of the Shawn Garbett nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#++
module GRATR
module Graph
module Comparability
# A comparability graph is an UndirectedGraph that has a transitive
# orientation. This returns a boolean that says if this graph
# is a comparability graph.
def comparability?() gamma_decomposition[1]; end
# Returns an array with two values, the first being a hash of edges
# with a number containing their class assignment, the second valud
# is a boolean which states whether or not the graph is a
# comparability graph
#
# Complexity in time O(d*|E|) where d is the maximum degree of a vertex
# Complexity in space O(|V|+|E|)
def gamma_decomposition
k = 0; comparability=true; classification={}
edges.map {|edge| [edge.source,edge.target]}.each do |e|
if classification[e].nil?
k += 1
classification[e] = k; classification[e.reverse] = -k
comparability &&= gratr_comparability_explore(e, k, classification)
end
end; [classification, comparability]
end
# Returns one of the possible transitive orientations of
# the UndirectedGraph as a Digraph
def transitive_orientation(digraph_class=Digraph)
raise NotImplementError
end
private
# Taken from Figure 5.10, on pg. 130 of Martin Golumbic's, _Algorithmic_Graph_
# _Theory_and_Perfect_Graphs.
def gratr_comparability_explore(edge, k, classification, space='')
ret = gratr_comparability_explore_inner(edge, k, classification, :forward, space)
gratr_comparability_explore_inner(edge.reverse, k, classification, :backward, space) && ret
end
def gratr_comparability_explore_inner(edge, k, classification, direction,space)
comparability = true
adj_target = adjacent(edge[1])
adjacent(edge[0]).select do |mt|
(classification[[edge[1],mt]] || k).abs < k or
not adj_target.any? {|adj_t| adj_t == mt}
end.each do |m|
e = (direction == :forward) ? [edge[0], m] : [m,edge[0]]
if classification[e].nil?
classification[e] = k
classification[e.reverse] = -k
comparability = gratr_comparability_explore(e, k, classification, ' '+space) && comparability
elsif classification[e] == -k
classification[e] = k
gratr_comparability_explore(e, k, classification, ' '+space)
comparability = false
end
end; comparability
end # gratr_comparability_explore_inner
end # Comparability
end # Graph
end # GRATR
syntax highlighted by Code2HTML, v. 0.9.1