reduce 一个 笛卡尔积_图的笛卡尔积的Maple实现

本文介绍了图的笛卡尔积的概念,详细阐述了其理论基础,并通过Maple展示了如何实现图的笛卡尔积,包括一些基本性质和操作的可视化效果。同时,讨论了在处理密集图时的绘图策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

d9d986134a05006d8144148cd31765bd.png

图的笛卡尔积 Cartesian product 是一类重要的图的运算。

1 理论基础

下面是标准的图的笛卡尔积 Cartesian product 定义。

In graph theory , the Cartesian product

of graphs
and
is a graph such that the vertex set of
is the Cartesian product
; and two vertices
and
are adjacent in
if and only if either
  • and
    is adjacent to
    in
    or
  • and
    is adjacent to
    in
    .

75a27c06f38f5ac5dd5c86e4445d578e.png

对于新图的顶点集合怎么得到并不难,不过是做一个简单的顶点集合的笛卡尔积,

bca27d783b8ecd3fd7f1bbe4bce8c71e.png

首先假设

的顶点集合为
,
的顶点集合为
. 那么
的顶点集合为 :

关键在于新图的边的构造方式的理解。我们单纯看构造边的两个条件,这两个条件地位相等。我们将上述

顶点集合按照逐行考虑,
的连边方式是按照
的连边规则,下面的
行均是如此,然后考虑每一列,第一列连边规则按照
的连边方式,依次类推。

例子1

f12c6d3e8ca16a01e42addebf52b8b75.png

例子2

cdef202d399ddc5a8443d14e5ebab4e6.png

例子3

d5017f313a1285ceece6190fec305521.png

有关Cartesian product 性质有很多,不同小方向关心的性质也侧重点也不同,基本的有一些:

The Cartesian product of graphs is sometimes called the box product of graphs [Harary 1969].

The operation is associative, as the graphs

and
are naturally isomorphic. The operation is commutative as an operation on isomorphism classes of graphs, and more strongly the graphs
and
are naturally isomorphic, but it is not commutative as an operation on labeled graphs.

The notation G × H has often been used for Cartesian products of graphs, but is now more commonly used for another construction known as thetensor product of graphs. The square symbol is an intuitive and unambiguous notation for the Cartesian product, since it shows visually the four edges resulting from the Cartesian product of two edges.

2 Maple实现

with(GraphTheory):
G := CycleGraph([v__1,v__2,v__3,v__4]);
H:=Graph({{u__1,u__2}}):
DrawGraph(C,size=[250,250],stylesheet=[vertexborder=false,vertexpadding=10,
                                        edgecolor = "red",vertexcolor="Orange",
                                        edgethickness=3]);
DrawGraph(H,size=[250,250],stylesheet=[vertexborder=false,vertexpadding=10,
                                        edgecolor = "Blue",vertexcolor="Cyan",
                                        edgethickness=3]);

94e30a835330051275df3a1584161874.png

dc91c4dfd2ffc62a48dcad9bf8af7d0a.png
GH:=CartesianProduct(G,H):
plots:-display(
  DrawGraph(GH,style=spring,
            stylesheet=[vertexborder=false,vertexpadding=4,
                        vertexcolor="Orange",edgethickness=3]),
  DrawGraph(GH,style=spring,
            stylesheet=[vertexborder=false,vertexpadding=14,
                        vertexcolor="Cyan",edgethickness=3])
);

11cb587c41647f23cc00c503479d30ca.png

为了便于观察,我们进行了简易修改,这里没有用代码修改了。选中图片右击属性进行适当修改颜色。

d3e6af6efee34cf8529aeccd51165932.png

这样图的笛卡尔积演示就出现比较不错的效果。但是达不到题图那样漂亮的效果,我们可以采用下面稍微复杂的代码。

restart:
with(GraphTheory):
with(plots):
randomize():
G1 := Graph({{a, b},{b, c},{c, a}}):
g1 := DrawGraph(G1):

G2 := Graph({{A,B},{B,C}}):
g2 := DrawGraph(G2):

G3 := CartesianProduct(G1, G2):
g3 := DrawGraph(G3):

# Select  the PLOT commands of the edges of each graph
# op(g1) and op(g2) are structured this way:
#   as many POLYGONS commands as vertices
#   as many TEXT commands as vertices
#   as many POLYGONS commands as edges
#   a SCALING command
#   an AXESSTYLE command
#
# Un comment the line below to visualize this
# op(g1);

ne1 := numelems(Edges(G1)):
no1 := nops(g1):
ed1 := op(no1-ne1-1..no1, g1):
PLOT(ed1):

ne2 := numelems(Edges(G2)):
no2 := nops(g2):
ed2 := op(no2-ne2-1..no2, g2):
PLOT(ed2):

ne3 := numelems(Edges(G3)):
no3 := nops(g3):
ed3 := op(no3-ne3-1..no3, g3):
PLOT(ed3):

# Get positions of vertices of each graph

v1 := GetVertexPositions(G1):
v2 := GetVertexPositions(G2):
v3 := GetVertexPositions(G3):

# Get the lengths of the edges of each graph


getlengths := proc(g, no, ne)
  local le, n:
  le := NULL:
  for n from no-ne-1 to no-2 do
    le := le, sqrt(add((`-`(op(op([n, 1], g))))^~2));
  end do:
  return [le]
end proc:
le1 := getlengths(g1, no1, ne1):
le2 := getlengths(g2, no2, ne2):
le3 := getlengths(g3, no3, ne3):

# Find the minimimum lengts  of each graph

mle1 := min(le1):
mle2 := min(le2):
mle3 := min(le3):

# Define the radius of the disk that is going to represent the vertices of each graph

shrink := 4: # to adjust
r1 := mle1 / shrink:
r2 := mle3 / shrink:
r3 := mle3 / shrink:

# Define the colors of these disks for G1 and G2


nv1  := numelems(Vertices(G1)):
col1 := seq([rand()/10^12, rand()/10^12, 0], i=0..nv1-1):
nv2  := numelems(Vertices(G2)):
col2 := seq([rand()/10^12, 0, rand()/10^12], i=0..nv2-1):
nv3  := numelems(Vertices(G3)):

# Vertex disks for G1 and G2

vd1 := display(seq(plottools:-disk(v1[n], r1, color=ColorTools:-Color(col1[n])), n=1..nv1)):
vd2 := display(seq(plottools:-disk(v2[n], r2, color=ColorTools:-Color(col2[n])), n=1..nv2)):

# Vizualize

display(vd1, PLOT(ed1)):
display(vd2, PLOT(ed2)):

# Case of G3: each vertex disk is made of two half disks 
# (the cut is choosen to be vertical)

V1 := Vertices(G1):
V2 := Vertices(G2):
V3 := Vertices(G3):

k   := 1:
vd3 := NULL:
for n3 in V3 do
  n1, n2 := StringTools:-Split(op(n3), ":")[]:
  pos1   := ListTools:-Search(parse(n1), V1): 
  pos2   := ListTools:-Search(parse(n2), V2): 
  vd3    := vd3, 
            display(
               plottools:-sector(v3[k], r3, Pi/2..3*Pi/2, color=ColorTools:-Color(col1[pos1])),
               plottools:-sector(v3[k], r3, -Pi/2..Pi/2 , color=ColorTools:-Color(col2[pos2]))
            ):
  k := k+1:
end do:

display(vd3, PLOT(ed3)):

# Compute the rescaling factor of each graph

S1 := sqrt(max(seq(seq(add((v1[i]-~v1[j])^~2), i=j+1..nv1), j=1..nv1-1)));
S1 := sqrt(max(seq(seq(add((v2[i]-~v2[j])^~2), i=j+1..nv2), j=1..nv2-1)));
S1 := sqrt(max(seq(seq(add((v3[i]-~v3[j])^~2), i=j+1..nv3), j=1..nv3-1)));


# Final result

DocumentTools:-Tabulate(
  [
    display(vd1, PLOT(ed1)),
    display(textplot([0, 0, "X"], font=[Tahoma, bold, 20], axes=none)),
    display(vd2, PLOT(ed2)),
    display(textplot([0, 0, "="], font=[Tahoma, bold, 20], axes=none)),
    display(vd3, PLOT(ed3))
  ],
  width=90, 
  weights=[4, 1, 4, 1, 8]
):

3d4571f9d45e01b9e3eaf757f3b59217.png

代码源自于

https://www.mapleprimes.com/questions/230579-Two-Colors-Dye-The-Same-Vertex-Of-Graph?reply=reply​www.mapleprimes.com

这些演示虽然可能不是研究的重心,真正关心的往往是图运算后一些本质的特征。不过这些基础性的绘图有时候能更好帮助我们理解。

有的图做笛卡尔积之后非常密集,在绘图上几乎看不出连接关系。我们可以采取一些方法。当然这种方案也不是只适用于图笛卡尔积作图。

V := Vertices(GH);
P := [];
flag := 0;
f := proc(K::string) local L; global P; L := Split(K, ":"); P := [op(P), cat("(", L[1], ",", L[2], ")")]; end proc;
if flag = 0 then
    for i to NumberOfVertices(GH) do f(V[i]); end do;
end if;
GH := RelabelVertices(GH, P);
DrawGraph(GH, stylesheet = "legacy")

c359bc07ac81531b9dfcc77f22845185.png
DGR:=DrawGraph(GH, stylesheet = "legacy"):
plots:-display(DGR,scaling=unconstrained,size=[1800,default]);

398fec3d9345f30fb919fb87ca6e1195.png

这一做法归功于

https://www.mapleprimes.com/questions/230023-Need-Help-To-Help-DrawGraph-In-Better​www.mapleprimes.com
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值