剧情提要:
[机器小伟]在[工程师阿伟]的陪同下进入练气期第五层功法的修炼,
这次要修炼的目标是[测量]。
既然有这么些路径可以选择,但是哪条最短呢?
嗯嗯,小伟终于知道从自己家去哪要走哪条路了,不错。
怎么得到这个结果的呢?是这样的:
可以看出来他们的选择很多,这桥还是很结实的。
学得差不多了,小伟该去玩一会了。
[机器小伟]在[工程师阿伟]的陪同下进入练气期第五层功法的修炼,
这次要修炼的目标是[测量]。
正剧开始:
星历2016年01月13日 09:39:56, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究测量的技术。
09:41:39, 小伟认识了毫米和分米。
还有厘米
小伟拿出了自己的尺子:
<span style="font-size:18px;">function myDraw() {
var config = new PlotConfiguration();
config.init();
config.setPreference();
//config.setSector(1,1,1,1);
//config.axis2D(0, 0, 180);
//图片
var image = new Image();
image.src = "./1.jpg";
var ruler = new Ruler();
image.onload = function() {
plot.save()
.scale(1.07, 1)
.drawImage(image)
.restore();
ruler.ruler(10, 128, 280, 0);
}
}</span>
小伟看到了分米
接着做了一次测量长度的练习:
接着认识千米
接着小伟看到了[人叫板老师]举的一个例子,让小伟选择路径,小伟兴奋起来了:
来看看小伟从家到体育场有几种路线选择吧:
<span style="font-size:18px;">小伟家-->学校-->医院-->体育场
小伟家-->小年宫-->医院-->体育场
小伟家-->小年宫-->公园-->体育场
小伟家-->学校-->医院-->小年宫-->公园-->体育场</span>
<span style="font-size:18px;">/**
* @usage 打印给定两个地点间所有路径
* @author mw
* @date 2016年01月13日 星期三 09:50:23
* @param
* @return
*
*/
function myDraw() {
var config = new PlotConfiguration();
config.init();
config.setPreference();
//config.setSector(1,1,1,1);
//config.axis2D(0, 0, 180);
/*
求解以下问题:
(1)有六个地点,编号1-6,地点之间的连通情况为边数组
*/
//顶点数量
var vertexNum = 6;
var edge = [[1,6],[1,2],[2,5],[2,3],[3,4],[4,5],[5,6]];
var edges = edge.length;
var pathMap = new Map();
for (var i = 0; i < edges; i++) {
pathMap.put(edge[i][0], edge[i][1]);
pathMap.put(edge[i][1], edge[i][0]);
}
pathMap.sort();
/*
(2)现在要求给出两点(6,3),
求出所有能从地点6到达地点3的选择
*/
var begin = 6;
var end = 3;
//可增长的路径
var pathArray = new Array();
//pathArray中的一个选择
var choice = new Array();
//choice前提下的下一步选择
var newChoice = new Array();
//有效路径
var effectivePath = new Array();
//临时变量
var tmp = 0, len = 0, len1 = 0;
var count = 0;
//把起点压入栈
pathArray.push([begin]);
while (pathArray.length > 0) {
//每次从选择集合中取出第一个选择
choice = pathArray.shift();
len = choice.length;
if (len >= vertexNum)
break;
//选择的最后一个元素
tmp = choice[len-1];
newChoice = pathMap.get(tmp);
//document.write(choice.join(',')+'------'+newChoice.join(',')+'<br/>');
len1 = newChoice.length;
for (var i = 0; i < len1; i++) {
for (var j = 0; j < len; j++) {
//元素重复了
if (newChoice[i] == choice[j]) {
break;
}
//无重复元素
if (j >= len-1) {
if (newChoice[i] == end) {
effectivePath.push(choice.concat(newChoice[i]));
}
else {
pathArray.push(choice.concat(newChoice[i]));
//document.write(choice.concat(newChoice[i]).join(',')+'<br/>');
}
}
}
}
}
var addressString = ['学校', '医院', '体育场', '公园', '小年宫', '小伟家'];
var s = '';
len = effectivePath.length;
for (var i = 0; i < len; i++) {
s = '';
choice = effectivePath[i];
len1 = choice.length;
for (var j = 0; j < len1; j++) {
s +=addressString[choice[j]-1];
if (j < len1-1) {
s += '-->';
}
}
document.write(s+'<br/>');
}
}
</span>
既然有这么些路径可以选择,但是哪条最短呢?
先来看结果:
<span style="font-size:18px;">>>>
选择的路线是:
小伟家-->小年宫-->公园-->体育场 ,这条路线总长为920米</span>
<span style="font-size:18px;">###
# @usage 求两个给定地点,所有路径中的最短值
# @author mw
# @date 2016年01月13日 星期三 09:50:23
# @param
# @return
#
###
class DijkstraPath():
#初始化
def __init__(self, node_map):
self.node_map = node_map;
self.node_length = len(node_map);
self.used_node_list = [];
self.collected_node_dict = {};
#调用函数
def __call__(self, from_node, to_node):
self.from_node = from_node;
self.to_node = to_node;
self._init_dijkstra();
return self._format_path();
def _init_dijkstra(self):
self.used_node_list.append(self.from_node);
self.collected_node_dict[self.from_node] = [0, -1];
for index1, node1 in enumerate(self.node_map[self.from_node]):
if node1:
self.collected_node_dict[index1] = [node1, self.from_node];
self._foreach_dijkstra();
def _foreach_dijkstra(self):
#保证每个点最多只到一次
if len(self.used_node_list) == self.node_length - 1:
return;
#由于items()方法会改变原字典内容,所以此处拷贝副本
collected_node_dict = dict(self.collected_node_dict);
# 遍历已有权值节点
for key, val in collected_node_dict.items():
if key not in self.used_node_list and key != to_node:
self.used_node_list.append(key);
else:
continue;
# 对节点进行遍历
for index1, node1 in enumerate(self.node_map[key]):
# 如果节点在权值节点中并且权值大于新权值
if node1 and index1 in self.collected_node_dict \
and self.collected_node_dict[index1][0] > node1 + val[0]:
# 更新权值
self.collected_node_dict[index1][0] = node1 + val[0]
self.collected_node_dict[index1][1] = key;
elif node1 and index1 not in self.collected_node_dict:
self.collected_node_dict[index1] = [node1 + val[0], key];
#递归
self._foreach_dijkstra();
def _format_path(self):
node_list = [];
temp_node = self.to_node;
node_list.append((temp_node, self.collected_node_dict[temp_node][0]));
while self.collected_node_dict[temp_node][1] != -1:
temp_node = self.collected_node_dict[temp_node][1];
node_list.append((temp_node, self.collected_node_dict[temp_node][0]));
node_list.reverse();
return node_list;
def pathString(self, node):
node_list = self._format_path();
size = len(node_list);
s = '选择的路线是:\n';
for i in range(size):
if i < size-1:
s += str(node[node_list[i][0]])+'-->';
else:
s += str(node[node_list[i][0]]);
s+= ' ,这条路线总长为{0}米'.format(node_list[size-1][1]);
return s;
def set_node_map(node_map, node, node_list):
for x, y, val in node_list:
node_map[node.index(x)][node.index(y)] = node_map[node.index(y)][node.index(x)] = val
if __name__ == "__main__":
#节点表
node = [1, 2, 3, 4, 5, 6];
addressString = ['学校', '医院', '体育场', '公园', '小年宫', '小伟家'];
#带权重的边表
node_list = [(1,6,250), (1,2,300), (5,6,300), (4,5,470),
(3,4,150), (2,3,450),(2,5,250)];
#节点数量的平方
node_map = [[0 for val in range(len(node))] for val in range(len(node))];
#预设节点表
set_node_map(node_map, node, node_list);
#Demo 求A --> D 的最短距离
from_node = node.index(6);
to_node = node.index(3);
#求取路径
dijkstrapath = DijkstraPath(node_map);
#路径字符串
path = dijkstrapath(from_node, to_node);
print(dijkstrapath.pathString(addressString));
</span>
嗯嗯,小伟终于知道从自己家去哪要走哪条路了,不错。
接着小伟认识了吨和千克:
来做一做这个题吧:
<span style="font-size:18px;">>>>
卡车一可以装600, 400, 800, , 另一辆卡车装1000, 700,
卡车一可以装600, 1000, , 另一辆卡车装400, 800, 700,
卡车一可以装800, 1000, , 另一辆卡车装600, 400, 700,
卡车一可以装600, 400, 700, , 另一辆卡车装800, 1000,
卡车一可以装400, 800, 700, , 另一辆卡车装600, 1000,
卡车一可以装1000, 700, , 另一辆卡车装600, 400, 800, </span>
怎么得到这个结果的呢?是这样的:
<span style="font-size:18px;">def tmp():
N = 5;
array = [0]*N;
weight = [600,400,800,1000,700];
totalWeight = 0;
firstTruck = 0;
#所有货物的总重量
for i in range(len(weight)):
totalWeight+=weight[i];
while (array[N-1] < 2):
firstTruck = 0;
for i in range(len(weight)):
firstTruck += weight[i]*array[i];
if firstTruck < 2000 and firstTruck > totalWeight-2000:
s1 = '卡车一可以装';
s2 = '另一辆卡车装';
for i in range(len(weight)):
if array[i] != 0:
s1 += str(weight[i])+', ';
else:
s2 += str(weight[i])+', ';
print(s1+', '+s2);
array[0]+=1;
for i in range(N-1):
if array[i] > 1:
array[i+1]+=1;
array[i] = 0;
return;</span>
这几位动物怎么过河呢,小伟给出了解答:
<span style="font-size:18px;">>>>
第一批过河的:熊, 总共340千克,, 另一批过河的:山羊, 兔, 牛, 总共900千克,
第一批过河的:熊, 山羊, 总共580千克,, 另一批过河的:兔, 牛, 总共660千克,
第一批过河的:熊, 兔, 总共500千克,, 另一批过河的:山羊, 牛, 总共740千克,
第一批过河的:山羊, 兔, 总共400千克,, 另一批过河的:熊, 牛, 总共840千克,
第一批过河的:熊, 山羊, 兔, 总共740千克,, 另一批过河的:牛, 总共500千克,
第一批过河的:牛, 总共500千克,, 另一批过河的:熊, 山羊, 兔, 总共740千克,
第一批过河的:熊, 牛, 总共840千克,, 另一批过河的:山羊, 兔, 总共400千克,
第一批过河的:山羊, 牛, 总共740千克,, 另一批过河的:熊, 兔, 总共500千克,
第一批过河的:兔, 牛, 总共660千克,, 另一批过河的:熊, 山羊, 总共580千克,
第一批过河的:山羊, 兔, 牛, 总共900千克,, 另一批过河的:熊, 总共340千克,</span>
可以看出来他们的选择很多,这桥还是很结实的。
<span style="font-size:18px;">def tmp():
N = 4;
array = [0]*N;
weight = [340,240,160, 500];
name = ['熊', '山羊', '兔', '牛'];
totalWeight = 0;
firstTeam = 0;
#所有过河者的总重量
for i in range(len(weight)):
totalWeight+=weight[i];
while (array[N-1] < 2):
firstTeam = 0;
for i in range(len(weight)):
firstTeam += weight[i]*array[i];
if firstTeam < 1000 and firstTeam > totalWeight-1000:
s1 = '第一批过河的:';
s2 = '另一批过河的:';
for i in range(len(weight)):
if array[i] != 0:
s1 += str(name[i])+', ';
else:
s2 += str(name[i])+', ';
s1 += '总共'+str(firstTeam)+'千克,';
s2 += '总共'+str(totalWeight-firstTeam)+'千克,';
print(s1+', '+s2);
array[0]+=1;
for i in range(N-1):
if array[i] > 1:
array[i+1]+=1;
array[i] = 0;
return;</span>
学得差不多了,小伟该去玩一会了。
本节到此结束,欲知后事如何,请看下回分解。