Matlab 如何为图论应用程序生成仅包含0和1的所有可能(10x10)矩阵以及其他限制
编辑要求6并添加新要求Matlab 如何为图论应用程序生成仅包含0和1的所有可能(10x10)矩阵以及其他限制,matlab,matrix,while-loop,graph-theory,adjacency-matrix,Matlab,Matrix,While Loop,Graph Theory,Adjacency Matrix,编辑要求6并添加新要求 6) 只有4列/行的度数必须为3。 7) 阶数为3的两个顶点不相邻 我的目标: 生成并保存满足特定要求的所有矩阵。然后将每个矩阵与之前手动输入的其他矩阵进行比较,以检查特定的相似性。如果有人认为有帮助,我可以补充更多细节。我相信我已经整理好了代码的比较方面,所以我正在等待矩阵生成部分。我需要对多种尺寸进行此操作,但我会将此问题集中在10x10机箱上 具体要求: 1) 必须是10x10矩阵(表示10个顶点上的图形)。 2) 必须对称(表示邻接矩阵)。 3) 对角线为0(无循
6) 只有4列/行的度数必须为3。
7) 阶数为3的两个顶点不相邻 我的目标:
生成并保存满足特定要求的所有矩阵。然后将每个矩阵与之前手动输入的其他矩阵进行比较,以检查特定的相似性。如果有人认为有帮助,我可以补充更多细节。我相信我已经整理好了代码的比较方面,所以我正在等待矩阵生成部分。我需要对多种尺寸进行此操作,但我会将此问题集中在10x10机箱上 具体要求:
1) 必须是10x10矩阵(表示10个顶点上的图形)。
2) 必须对称(表示邻接矩阵)。
3) 对角线为0(无循环)。
4) 只有1和0(简单图形)。
5) 整个矩阵必须正好有48个1(图形有24条边)。
6) 每个列/行必须有3或6个1(每个节点的阶数为3或6) 应用:
我正在研究一个猜想,我相信我已经找到了一个可能的解决方案,可以把这个猜想分解成更小的部分,并可能证明一些方面。我想用暴力来证明我的想法是否适用于一个小的具体案例。同时,拥有一个基础代码可以允许将来的修改来测试其他可能的案例或想法。 想法和思维过程:
- 我使用图形的边手动输入比较集。例如:
G9=图形([1 1 1 2 3 4 5 6 6 3 3 9 2 2 7 8],[2 3 4 4 5 7 7 7 7 7 7 9 10 9])代码>
- 我认为这是唯一一个符合前面列出的要求的同构图
- 我最初的想法是创建满足给定条件的可能矩阵,然后将它们与我的比较集进行比较。我仍然认为这是最好的办法
- 我愚蠢地试图生成随机矩阵,完全忽略了大量的可能性。使用while循环,我首先生成了一个满足前四个需求的随机矩阵。然后在单独的嵌套for语句中,我使用numedes()检查了需求5,使用all(mod(degree())检查了需求6。这是一个很糟糕的方法,有几个很明显的原因,但我在这个过程中学到了很多东西,这让我找到了应该进行最终比较的代码
- 这是我第一次使用Matlab,所以我边学边用。我已经为这一个代码工作了将近两周,不知道我想出的是否“好”,但我为我自己能够做到的感到骄傲。我已经到了需要外界建议的地步。我愿意接受任何建议和任何级别的帮助。如能参考源代码、功能建议、其他方法或带有“即插即用”代码的完整解决方案,将不胜感激。我毫不避讳地努力实现我的目标。
我感谢您的反馈李>
如果你想强行使用它,你有3773655750150种可能的配置来测试3或6连通性。我想你可能需要更强大的数学(波利亚枚举定理?或其他一些我可能忘记的组合定理)来解决这个问题
编辑:这种递归解决方案更受约束,可能在下个世纪完成
E = containers.Map('KeyType', 'int32', 'ValueType', 'any');
for k = 0:9
E(k) = [];
end
foo(E, 3, 0);
foo(E, 6, 0);
function E = foo(E, D, n)
% E : graph edges (map)
% D : degree (3 or 6)
% n : current node
if (n == 9)
e_degree = cellfun(@length,E.values);
if all(e_degree) && all(~mod(e_degree,3))
print_E(E)
end
return
end
e = E(n); % existing edges
m = setdiff((n+1:9), e); % candidate new edges
K = D - length(e);
% if too many edges, return early
if (K < 0)
return
end
C = combnk(m, K);
N = size(C, 1);
for k = 1:N
c = C(k,:);
E(n) = unique([e, c]);
for kv = 1:K
v = c(kv);
E(v) = unique([E(v), n]);
end
% down the rabbit hole
E = foo(E, D, n + 1);
for D = 3:3:6
E = foo(E, D, n + 1);
end
% remove edges added in this loop
E(n) = setdiff(E(n), c);
for kv = 1:K
v = c(kv);
E(v) = setdiff(E(v), n);
end
end
end
function print_E(E)
for k = 0:9
fprintf('%i: ',k);
fprintf('%i ', E(k));
fprintf('\n');
end
fprintf('\n');
end
E=containers.Map('KeyType','int32','ValueType','any');
对于k=0:9
E(k)=[];
结束
foo(E,3,0);
foo(E,6,0);
函数E=foo(E,D,n)
%图边(地图)
%D:学位(3或6)
%n:当前节点
如果(n==9)
e_度=cellfun(@length,e.values);
如果全部(e_学位)和全部(~mod(e_学位,3))
打印(E)
结束
返回
结束
e=e(n);%现有边
m=setdiff((n+1:9),e);%候选新边
K=D——长度(e);
%如果边缘太多,请提前返回
if(K<0)
返回
结束
C=combnk(m,K);
N=尺寸(C,1);
对于k=1:N
c=c(k,:);
E(n)=唯一([E,c]);
对于kv=1:K
v=c(千伏);
E(v)=唯一([E(v),n]);
结束
%下兔子洞
E=foo(E,D,n+1);
对于D=3:3:6
E=foo(E,D,n+1);
结束
%删除在此循环中添加的边
E(n)=setdiff(E(n),c);
对于kv=1:K
v=c(千伏);
E(v)=setdiff(E(v),n);
结束
结束
结束
功能打印(E)
对于k=0:9
fprintf(“%i:”,k);
fprintf('%i',E(k));
fprintf('\n');
结束
fprintf('\n');
结束
我不是数学家,我不确定您所说的需求2是什么意思,但也许可以利用它来减少问题……我仍在努力缩短计算时间,但同时,我认为我至少有一个解决方案满足您的约束,并且与您的解不同构:([1 1 1 2 5 3 5 6 3 5 7 4 5 6 7 8 9],[2 3 4 5 6 7 7 7 8 8 8 9 9 9 9 9 9 9 1 0 1 0 1 0 1 0 1 0]
。如果有24条边,并且所有节点都是3度或6度,唯一有效的配置是有4个3度节点和6个6度节点(这是我加速函数的方法之一)但是,在K_4子图中可以有3度节点中的节点。除非允许有断开连接的子图,否则不是所有节点。这让我意识到,我没有限制我的函数只生成连接图。:)我基本上是使用蛮力/回溯来生成带有两个opt的有效图首先,我们知道对于10个节点的情况,我们需要4个3度节点和6个4度节点