好玩的Prim算法

  这段时间学算法,用JS实现了一个Prim,用于在连通图中找出最小树,具体内容、代码解析周末会不上,现在先把源码献上:

  1 <!DOCTYPE html>
  2 <html charset=‘GB2312‘>
  3
  4 <head>
  5     <title>最小树生成算法</title>
  6     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  7
  8     <style type="text/css">
  9     body>canvas {
 10         border: 1px solid black;
 11         padding: 10px;
 12         margin: 10px auto;
 13     }
 14     </style>
 15 </head>
 16
 17 <body>
 18     <canvas id="canvas" width="1000px" height="400px"></canvas>
 19     <canvas id="sub-canvas" width="1000px" height="400px"></canvas>
 20     <script type="text/javascript">
 21     !(function() {
 22         var canvas_context = document.getElementById(‘canvas‘).getContext(‘2d‘),
 23             sub_ctx = document.getElementById(‘sub-canvas‘).getContext(‘2d‘),
 24             _getRandom = function(max, min) {
 25                 max = max || 100;
 26                 min = min || 0;
 27                 return Math.round(Math.random() * (max - min) + min);
 28             },
 29             _getRandomMatix = function(nodes) {
 30                 var matix = [],
 31                     power = 0,
 32                     max = 10,
 33                     min = 0,
 34                     tmp = 0;
 35                 for (var i = 0; i < nodes; i++) {
 36                     for (var j = i; j < nodes; j++) {
 37                         power = _getRandom(max, min);
 38                         matix[i] = matix[i] || [];
 39                         matix[j] = matix[j] || [];
 40                         tmp = i === j ? 0 : (Math.random() > 0.6 ? 1 : 0) * power;
 41                         matix[i][j] = matix[j][i] = tmp;
 42                     }
 43                     console.log(matix[i].join(‘,‘))
 44                 }
 45
 46                 // 构造连通图
 47                 for (var i = 0; i < matix.length; i++) {
 48                     var isValid = true;
 49                     for (var j = 0; j < matix[i].length; j++) {
 50                         isValid = isValid && matix[i][j] !== 0;
 51                     }
 52                     if (!isValid) {
 53                         var rindex = _getRandom(matix[i].length - 1, 0),
 54                             v = _getRandom(max, min + 1);
 55                         matix[i][rindex] = matix[rindex][i] = v;
 56                     }
 57                 }
 58                 return matix;
 59             },
 60             _matix2graph = function(matix) {
 61                 var len = matix.length,
 62                     row = null,
 63                     cell = null,
 64                     graph = {},
 65                     x,
 66                     y;
 67                 canvas_context.font = cycle_width / 2 + ‘px Arial bold‘;
 68                 canvas_context.textAlign = ‘center‘;
 69                 for (var i = 0; i < len; i++) {
 70                     x = _getRandom(pain_rect.x2, pain_rect.x1);
 71                     y = _getRandom(pain_rect.y2, pain_rect.y1);
 72
 73                     graph[i] = {
 74                         x: x,
 75                         y: y,
 76                         powers: matix[i]
 77                     }
 78                 }
 79                 return graph;
 80             },
 81             _getMinTree = function(graph) {
 82                 var point1 = graph[0],
 83                     min_tree = {
 84                         x: point1.x,
 85                         y: point1.y,
 86                         index: 0,
 87                         sub: []
 88                     },
 89                     min_x = -1,
 90                     min_y = -1,
 91                     min = Number.MAX_VALUE,
 92                     index_inTree = [0],
 93                     node = null,
 94                     _findNode = function(index, roots) {
 95                         if (roots.length === 0) return null;
 96
 97                         var subRoots = [];
 98                         for (var i in roots) {
 99                             if (roots[i].index === index) return roots[i];
100                             else subRoots = subRoots.concat(roots[i].sub);
101                         }
102                         return _findNode(index, subRoots);
103                     };
104
105                 for (var k in graph) {
106                     min_x = -1;
107                     min_y = -1;
108                     min = Number.MAX_VALUE;
109                     for (var i = 0; i < index_inTree.length; i++) {
110                         point1 = graph[index_inTree[i]];
111                         for (var j = 1; j < point1.powers.length; j++) {
112                             if (index_inTree.indexOf(j) >= 0) continue;
113                             else if (point1.powers[j] > 0 && point1.powers[j] < min) {
114                                 min_x = point1.index;
115                                 min_y = j;
116                                 min = point1.powers[j]
117                             }
118                         }
119                     }
120                     if (min_x >= 0) {
121                         index_inTree.push(min_y);
122                         point1 = graph[min_y];
123                         node = _findNode(graph[min_x].index, [min_tree]);
124                         if ( !! node) node.sub.push({
125                             x: point1.x,
126                             y: point1.y,
127                             index: min_y,
128                             power: min,
129                             sub: []
130                         });
131                     }
132                     console.log(‘min tree node count: ‘ + index_inTree.length + ‘ ; ‘ + node);
133                 }
134                 return min_tree;
135             },
136             canva_width = 1000,
137             canva_height = 400,
138             x_range = 490,
139             y_range = 190,
140             pain_rect = {
141                 x1: canva_width / 2 - x_range,
142                 x2: canva_width / 2 + x_range,
143                 y1: canva_height / 2 - y_range,
144                 y2: canva_height / 2 + y_range
145             },
146             cycle_width = 10,
147             _renderGraph = function(graph) {
148                 var point1,
149                     point2,
150                     count = 0;
151                 for (var i in graph) {
152                     point1 = graph[i];
153                     i = i - 0;
154                     point1.index = i;
155                     for (var j = 0; j < point1.powers.length; j++) {
156                         point2 = graph[j];
157                         point2.index = j;
158
159                         _renderPoint(point1);
160                         _renderPoint(point2);
161                         if ( !! point1.powers[j]) {
162                             _renderLine(point1, point2, point1.powers[j]);
163                             console.log(‘graph ‘ + i + ‘ to ‘ + j + ‘: ‘ + point1.powers[j]);
164                             count += point1.powers[j];
165                         }
166                     }
167                 }
168                 console.log(‘end graph :‘ + count);
169                 return graph;
170             },
171             _renderTree = function(tree) {
172                 var _count = 0,
173                     _renderer = function(root) {
174                         var point1 = root,
175                             point2 = null;
176                         _renderPoint(point1, sub_ctx);
177                         for (var i = 0; i < root.sub.length; i++) {
178                             point2 = root.sub[i];
179                             _renderLine(point1, point2, point2.power, sub_ctx);
180                             _renderer(point2);
181                             _count += point2.power;
182                             console.log(‘tree ‘ + point1.index + ‘ to ‘ + point2.index + ‘ : ‘ + point2.power);
183                         }
184                     };
185                 _renderer(tree);
186
187                 console.log(‘end tree :‘ + _count)
188             },
189             _renderPoint = function(point1, ctx) {
190                 ctx = ctx || canvas_context;
191                 requestAnimationFrame(function() {
192                     // 画点
193                     ctx.beginPath();
194                     ctx.fillStyle = ‘red‘;
195                     ctx.arc(point1.x, point1.y, cycle_width, 0, Math.PI * 2, true);
196                     ctx.fill();
197                     ctx.closePath();
198
199                     // 点中间的字——点的序号
200                     ctx.beginPath();
201                     ctx.fillStyle = ‘white‘;
202                     ctx.fillText(point1.index, point1.x, point1.y + cycle_width / 4);
203                     ctx.closePath();
204                 });
205             },
206             _renderLine = function(point1, point2, power, ctx) {
207                 ctx = ctx || canvas_context;
208
209                 requestAnimationFrame(function() {
210                     // 点与点间的连线
211                     ctx.beginPath();
212                     ctx.moveTo(point1.x, point1.y);
213                     ctx.lineTo(point2.x, point2.y);
214                     ctx.closePath();
215                     ctx.stroke();
216
217                     // 点与点间连线的字——权重
218                     ctx.beginPath();
219                     ctx.fillStyle = ‘red‘;
220                     var x1 = Math.min(point1.x, point2.x),
221                         x2 = Math.max(point1.x, point2.x),
222                         y1 = Math.min(point1.y, point2.y),
223                         y2 = Math.max(point1.y, point2.y);
224                     ctx.fillText(power, 0.5 * x2 + 0.5 * x1, 0.5 * y2 + 0.5 * y1);
225                     ctx.closePath();
226                 });
227             };
228
229         var graph = _renderGraph(_matix2graph(_getRandomMatix(9)));
230         _renderTree(_getMinTree(graph))
231     })();
232     </script>
233 </body>
234
235 </html>

  这里可以在线运行哦:http://www.w3cfuns.com/home.php?mod=space&uid=5446932&do=blog&quickforward=1&id=5398698

好玩的Prim算法

时间: 2024-10-28 16:00:15

好玩的Prim算法的相关文章

最小生成树问题(prim算法)POJ-1258 Agri-Net

/* 这个题很水,但是,莫名其妙runtime error一晚上,重写了一遍就又没了,很伤心! 题意很简单,大致为n个村庄,连光缆,要求连上所有村庄的长度最短. 输入n,接着是n*n的矩阵,直接用prim算法写就行: */ #include<iostream> #include<cstdlib> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath>

杭电1162--Eddy&#39;s picture(Prim()算法)

Eddy's picture Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8070    Accepted Submission(s): 4084 Problem Description Eddy begins to like painting pictures recently ,he is sure of himself to b

hihocoder1097最小生成树(prim算法)

prim算法描述: prim算法的思想和代码都跟dijkstra算法非常相似. 在dijkstra算法中,我们用每次取出未标记集合中到源点最近的点进行标记并更新其邻接点到源点的距离:当d[x]+w<d[y]时更新d[y]=d[x]+w. 而在prim算法中,我们只需要对dijkstra算法稍作改动即可,即只需要改变一下更新操作:当w<d[y]时更新d[y]=w,此时d[y]的含义是节点y连接到最小生成树的边的最小取值.也就是说,从图中某个节点发出了边可能有若干条,而最终将该节点连接到最小生成树

prim算法模板

var g:array[1..10,1..10] of longint; d:array[1..10] of longint; f:array[1..10] of boolean; procedure prim; var i,j,k,min:longint; begin fillchar(g,sizeof(g),0); fillchar(f,sizeof(f),0); for i:=1 to n do d[i]:=g[1,i]; f[1]:=true; for i:=2 to n do begi

最小生成树(prim算法,Kruskal算法)c++实现

1.生成树的概念 连通图G的一个子图如果是一棵包含G的所有顶点的树,则该子图称为G的生成树. 生成树是连通图的极小连通子图.所谓极小是指:若在树中任意增加一条边,则将出现一个回路:若去掉一条边,将会使之变成非连通图. 生成树各边的权值总和称为生成树的权.权最小的生成树称为最小生成树. 2.最小生成树的性质用哲学的观点来说,每个事物都有自己特有的性质,那么图的最小生成树也是不例外的.按照生成树的定义,n 个顶点的连通网络的生成树有 n 个顶点.n-1 条边. 3.构造最小生成树,要解决以下两个问题

Prim算法(一)之 C语言详解

本章介绍普里姆算法.和以往一样,本文会先对普里姆算法的理论论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 普里姆算法介绍 2. 普里姆算法图解 3. 普里姆算法的代码说明 4. 普里姆算法的源码 转载请注明出处:http://www.cnblogs.com/skywang12345/ 更多内容:数据结构与算法系列 目录 普里姆算法介绍 普里姆(Prim)算法,和克鲁斯卡尔算法一样,是用来求加权连通图的最小生成树的算法. 基本思想 对于图G而言,V是所

HDU 5253 Prim算法

http://acm.hdu.edu.cn/showproblem.php?pid=5253 Prim算法是 1.每次选出 (已经选出的)点集 能够连接 边权值最小的点 2.使用新找出的点能带来的新的更小的边权,来更新旧的较大的边权 3.重复,直到连接所有点 的贪心算法 使用优先权队列优化 查找 边权值最小的点 的步骤. #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ios

最小生成树--prim算法

一个无向图G的最小生成树就是由该图的那些连接G的所有顶点的边构成的树,且其总价值最低,因此,最小生成树存在的充分必要条件为图G是连通的,简单点说如下: 1.树的定义:有n个顶点和n-1条边,没有回路的称为树 生成树的定义:生成树就是包含全部顶点,n-1(n为顶点数)条边都在图里就是生成树 最小:指的是这些边加起来的权重之和最小 2.判定条件:向生成树中任加一条边都一定构成回路 充分必要条件:最小生成树存在那么图一定是连通的,反过来,图是连通的则最小生成树一定存在 上图的红色的边加上顶点就是原图的

[迷宫中的算法实践]迷宫生成算法&mdash;&mdash;Prim算法

       普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小.该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(英语:Vojtěch Jarník)发现:并在1957年由美国计算机科学家罗伯特·普里姆(英语:Robert C. Prim)独立发现:1959年,艾兹格·迪科斯彻再次发现了该算法.因此,在某些场合,普里姆