java图论
A. 一个java的多目的地最短路径规划的算法,大家帮忙看一下,给解释解释,在线等,多谢多谢。
最短路径规范是图论的入门第一课,还是去学学理论吧。
B. 求图论算法java实现
求图论算法java实现
packagetest;
importjava.io.BufferedReader;
importjava.io.FileReader;
importjava.io.IOException;
importjava.util.ArrayList;
importjava.util.Comparator;
importjava.util.HashMap;
importjava.util.Map;
importjava.util.PriorityQueue;
importjava.util.Queue;
publicclassMinSpanningTree{
classEdge{//内部类定义边的数据结果
intu,v,weight;
}
ArrayList<edge>Edges=newArrayList<edge>();
Map<integer,integer="">nodeFather=newHashMap<integer,integer="">();
intcnt=0,nodeCnt=0;
publicMinSpanningTree(Stringpath){
try{
BufferedReaderbr=newBufferedReader(newFileReader(path));
Stringstr;
String[]strArray;
while((str=br.readLine())!=null){
strArray=str.split("\s");
Edges.add(cnt,newEdge());
Edges.get(cnt).u=Integer.parseInt(strArray[0]);
Edges.get(cnt).v=Integer.parseInt(strArray[1]);
Edges.get(cnt).weight=Integer.parseInt(strArray[2]);
if(!nodeFather.containsKey(Edges.get(cnt).u)){
nodeFather.put(Edges.get(cnt).u,Edges.get(cnt).u);//初始化,father[i]=i;
++nodeCnt;
}
if(!nodeFather.containsKey(Edges.get(cnt).v)){
nodeFather.put(Edges.get(cnt).v,Edges.get(cnt).v);
++nodeCnt;
}
++cnt;
}
br.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
publicbooleanunion(intu,intv){//并操作
inta=find(u);
intb=find(v);
if(a!=b){
nodeFather.put(a,b);
returntrue;
}
returnfalse;
}
publicintfind(intx){//查操作
if(x!=nodeFather.get(x)){
nodeFather.put(x,find(nodeFather.get(x)));
}
returnnodeFather.get(x);
}
publicArrayList<edge>getMinSpanningTree(){
ArrayList<edge>result=newArrayList<edge>();
Queue<edge>FsQueue=newPriorityQueue<edge>(1000,//设置优先队列,使按边权值从小到大排序
newComparator<edge>(){
publicintcompare(EdgeEdgeOne,EdgeEdgeTwo){
if(EdgeOne.weight>EdgeTwo.weight)
return1;
elseif(EdgeOne.weight<EdgeTwo.weight)
return-1;
else
return0;
}
});
for(inti=0;i<cnt;++i){
FsQueue.add(Edges.get(i));
}
while(!FsQueue.isEmpty()){//遍历每一条边
EdgeEdge=FsQueue.poll();
if(union(Edge.u,Edge.v)){
result.add(Edge);
}else{
continue;
}
}
returnresult;
}
publicstaticvoidmain(String[]args){
MinSpanningTreemstree=newMinSpanningTree("c:/treedata.txt");
ArrayList<edge>result=mstree.getMinSpanningTree();
for(inti=0;i<result.size();++i){
System.out.println(result.get(i).u+""+result.get(i).v+""+result.get(i).weight);
}
}
}
C. java程序开发中的逻辑思维怎样学习的呢
逻辑思维的培养对软件工程非常重要,思维快的能快速编写逻辑代码。可以从一下几个方面进行慢慢培养。
第一:明确学习目的
逻辑思维学习编程对多数IT业人员来说都是非常有用的。学编程,做一名编程人员,从个人角度讲,可以解决在软件使用中所遇到的问题,改进现有软件,可以为自己找到一份理想的工作添加重要得砝码,有利于在求职道路上谋得一个好的职位;从国家的角度,可以为中国的软件产业做出应有的贡献,一名优秀的程序员永远是被争夺的对象。学习编程还能锻炼思维,使我们的逻辑思维更加严密;能够不断享受到创新的乐趣,将一直有机会走在高科技的前沿,因为程序设计本身是一种创造性的工作。知识经济时代给我们带来了无限的机会,要想真正掌握计算机技术,并在IT行业里干出一番事业来,有所作为,具有一定的编程能力是一个基本条件和要求。
第二打好基础,学好基础知识对我们开发也很重要学编程要具备一定的基础,总结之有以下几方面:
首先是数学基础 从计算机发展和应用的历史来看计算机的数学模型和体系结构等都是有数学家提出的,最早的计算机也是为数值计算而设计的。因此,要学好计算机就要有一定的数学基础,出学者有高中水平就差不多了。
其次是逻辑思维能力的培养 学程序设计要有一定的逻辑思维能力,“逻思力”的培养要长时间的实践锻炼。要想成为一名优秀的程序员,最重要的是掌握编程思想。要做到这一点必须在反复的实践、观察、分析、比较、总结中逐渐地积累。因此在学习编程过程中,我们不必等到什么都完全明白了才去动手实践,只要明白了大概,就要敢于自己动手去体验。谁都有第一次。有些问题只有通过实践后才能明白,也只有实践才能把老师和书上的知识变成自己的,高手都是这样成材的。最后是选择一种合适的入门语言 面对各种各样的语言,应按什么样的顺序学呢?程序设计工具不外乎如下几类: 1)本地开发 应用软件开发的工具有:Visual Basic 、Delphi 、VC++ ( C++ Builder ) 等;数据库开发工具有:Visual Foxpro 、Oracle Developer 、Power Builder 等。 2)跨平台开发 开发工具如 Java 等。 3)网络开发 对客户端开发工具如:Java Script 等;对服务器开发工具如:PHP 、ASP 、JSP 、ISAPI 、NSAPI 、CGI 等。 以上不同的环境下几种开发工具中 VB 法简单并容易理解,界面设计是可设化的,易学、易用。选 VB 作为入门的方向对出学者是较为适合的。
第三:注意理解一些重要概念
一本程序设计的书看到的无非就是变量、函数、条件语句、循环语句等概念,但要真正能进行编程应用,需要深入理解这些概念,在理解的基础上应用,不要只简单地学习语法、结构,而要吃透针对这些语法、结构的应用例子,做到举一反三,触类旁通。
第四:掌握编程思想,编程思想使用较多的就是oop编程思想
学习一门语言或开发工具,语法结构、功能调用是次要的,最主要是学习它的思想。例如学习 VC 就要学习 Windows 的内在机理、什么是线程......;学习 COM 就要知道VTALBE 、类厂、接口、idl......,关键是学一种思想,有了思想,那么我们就可以触类旁通。
第六:多实践、多交流,一切思维来自项目开发的积累
掌握编程思想必须在编程实际工作中去实践和体会。编程起步阶段要经常自己动手设计程序,具体设计时不要拘泥于固定的思维方式,遇到问题要多想几种解决的方案。这就要多交流,各人的思维方式不同、角度各异,各有高招,通过交流可不断吸收别人的长处,丰富编程实践,帮助自己提高水平。亲自动手进行程序设计是创造性思维应用的体现,也是培养逻辑思维的好方法。
第七:养成良好的编程习惯
编程入门不难,但入门后不断学习是十分重要的,相对来说较为漫长。在此期间要注意养成一些良好的编程习惯。编程风格的好坏很大程度影响程序质量。良好的编程风格可以使
程序结构清晰合理,且使程序代码便于维护。如代码的缩进编排、变量命令规则的一致性、代码的注释等。
第八:上网学编程
在网上可以学到很多不同的编程思想、方法、经验和技巧,有大量的工具和作品及相关的辅导材料供下载
8.加强计算机理论知识的再学习
思维培养学编程是符合“理论→实践→再理论→再实践”的一个认识过程。一开始要具有一定的计算机理论基础知识,包括编程所需的数学基础知识,具备了入门的条件,就可以
开始编程的实践,从实践中可以发现问题需要加强计算机理论知识的再学习。程序人人皆可编,但当你发现编到一定程度很难再提高的时候,就要回头来学习一些计算机科学和数
学基础理论。学过之后,很多以前遇到的问题都会迎刃而解,使人有豁然开朗之感。因此在学习编程的过程中要不断地针对应用中的困惑和问题深入学习数据结构、算法、计算机
原理、编译原理、操作系统原理、软件工程等计算机科学的理论基础和数理逻辑、代数系统、图论、离散数学等数学理论基础知识。这样经过不断的学习,再努力地实践,编程水平一定会不断提高到一个新高度。
D. 判断有向图是否连通+dfs+java
方法1:
如果存在回路,则必存在一个子图,是一个环路。环路中所有顶点的度>=2。
n算法:
第一步:删除所有度<=1的顶点及相关的边,并将另外与这些边相关的其它顶点的度减一。
第二步:将度数变为1的顶点排入队列,并从该队列中取出一个顶点重复步骤一。
如果最后还有未删除顶点,则存在环,否则没有环。
n算法分析:
由于有m条边,n个顶点。
i)如果m>=n,则根据图论知识可直接判断存在环路。(证明:如果没有环路,则该图必然是k棵树 k>=1。根据树的性质,边的数目m = n-k。k>=1,所以:m<n)
ii)如果m<n 则按照上面的算法每删除一个度为0的顶点操作一次(最多n次),或每删除一个度为1的顶点(同时删一条边)操作一次(最多m次漏敏晌)。这两种操作的总数不会超拿瞎过m+n。由于m<n,所以返锋算法复杂度为O(n)。
E. Java虚拟机怎么判断对象没被引用从而回收,什么时候会回收,什么时候会销毁
1. 引用计数器算法
解释
系统给每个对象添加一个引用计数器,每当有一个地方引用这个对象的时候,计数器就加1,当引用失效的时候,计数器就减1,在任何一个时刻计数器为0的对象就是不可能被使用的对象,因为没有任何地方持有这个引用,这时这个对象就被视为内存垃圾,等待被虚拟机回收
优点
客观的说,引用计数器算法,他的实现很简单,判定的效率很高,在大部分情况下这都是相当不错的算法
其实,很多案例中都使用了这种算法,比如 IOS 的Object-C , 微软的COM技术(用于给window开发驱动,.net里面的技术几乎都是建立在COM上的),Python语言等.
缺陷
无法解决循环引用的问题.
这就好像是悬崖边的人采集草药的人, 想要活下去就必须要有一根绳子绑在悬崖上. 如果有两个人, 甲的手拉着悬崖, 乙的手拉着甲, 那么这两个人都能活, 但是, 如果甲的手拉着乙, 乙的手也拉着甲, 虽然这两个人都认为自己被别人拉着, 但是一样会掉下悬崖.
比如说 A对象的一个属性引用B,B对象的一个属性同时引用A A.b = B() B.a = A(); 这个A,B对象的计数器都是1,可是,如果没有其他任何地方引用A,B对象的时候,A,B对象其实在系统中是无法发挥任何作用的,既然无法发挥作用,那就应该被视作内存垃圾予以清理掉,可是因为此时A,B的计数器的值都是1,虚拟机就无法回收A,B对象,这样就会造成内存浪费,这在计算机系统中是不可容忍的.
解决办法
在语言层面处理, 例如Object-C 就使用强弱引用类型来桥肢解决问题.强引用计数器加1 ,弱引用不增加
Java中也有强弱引用
2. 可达性分析算法
解释
这种算法通过一系列成为 "GC Roots " 的对象作为起始点,从这些节点开始向下搜索所有走过的路径成为引用链(Reference Chain) , 当一个对象GC Roots没有任何引用链相连(用图论的话来说就是从GC Roots到这个对象不可达),则证明此对象是不可用的
优点
这个算法可以轻松的解决循环引用的问题
大部分的主流java虚拟机棚迹使用的都是这种算法
3. Java语言中的GC Roots
在虚拟机栈(其实是栈帧中的本地变量表)中引用的对象
在方法区中链消并的类静态属性引用对象
在方法区中的常量引用的对象
在本地方法栈中JNI(即一般说的Native方法)的引用对象
F. Java 的垃圾回收如何判断哪个对象可以被回收
一般情况下java中对象可被回收的前提是:该对象不再被引用。
例如:
object
o
=
new
object();
o
=
null;
此时第一步
new
出来的对象不再被引用,垃圾回收器在回收的时候便会把这个对象清理掉。
特殊情况下
,java中存在弱引用(weakreference<>
很少用,不确定拼写的是否准确哈),对象即使被弱引用,垃圾回收机制也是可以回收的,我们正常直接赋值的引用属于强引用,除了系统内存不足等因素外,垃圾回收机制是不会清理的。
G. 北大青鸟java培训:编程需要多少数学知识
1、编程中的数学于是我马上回顾了下编程中用到的数学知识,好像少的可怜。
计数的能力:for循环中经常用,小学生都会。
数字的加减乘除:每种编程语言都会内置支持,都不需要你自己算余数和模:偶尔会用得到集合运算:交集、并集、差集,编程中用的不多。
布尔运算:AND,OR,非各种进制:二进制、十进制、十六进制还有哪些?我想不起来了。
当然这和我从事的编程领域有极大关系,辽宁北大青鸟http://www.kmbdqn.cn/认为如果我做的不是Web开发,而是搜索,游戏,安全,算法,人工智能等,那对数学的要求估计就开始飙升了。
其实计算机的基础是数让搜裂学,只是我们一直在应用层编程,体会不到罢了。
比如说我们日常使用的计算机,绝大部分都是所谓冯诺依曼结构,这个结构可以说是图灵机这个概念机器的具体实现,而图灵机就是一个纯数学的东西啊,没有图灵机这么伟大的抽象作为数学基础,现代的计算机是制造不出来的。
再比如说密码领域需要很多数论的知识,RSA算法就涉及到大素数的分解;我们常用的Mysql,Oracle等关系数据库的底层基础是离散数学的笛卡尔乘积;通信系统中很重要的一个原理就是傅里叶变换。
编译器会用到有限状态机;数据的压缩会用到各种数学的算法;项目管理中的进度管理,甘特图数学基础就是图论。
.....总之,数学在计算机科学扮演着非常重要的角色,是整个学科的基础。
2、不拼数学拼什么?具体到应用层编程,尤其Web开发、企业信息化开发,整天折腾的是框架和类库,用不到这么多高大上的数学知识,那到底拼的是什么?想想编程中常用的数组,如果是一维数组,做个循环和遍历,每个人都能轻松应对。
如果要用数组来表示二叉树坦闭,就需要把一个树形结构对应到线性结构,那难度立刻上升。
如果在编程中需要自己实现链表,就会发现把各个节点的链接关系维护好,需要把指针调来调去,挪来挪去,实在不是一件容易的事情。
这样的能力就是逻辑思维的一种体现。
我们在做系统设计的时候,经常需要总结、分析现实需求,找到容易变化的部分和相对稳定的部分,把他们封装起来,形成核心的概念,支撑起整个系统,这是一个抽象的过程,虽然用不到多少数学知识,但是思维的过程也极不容易。
逻辑思维能力和抽象能力的差别,能够区分出程序员的优秀和平庸。
一个优秀程序员写出的代码,接口清晰,容易扩展,易于维护;一个差程序员写出的代码,思路混乱,完全是一些计算机语句的堆砌,漏卜别人看不明白,过一段时间自己都看不明白了。
数学系的同学在这两方面恰恰是长项,想想看,数学系同学们整天折腾这么多“枯燥的”抽象概念,再去看编程这样大部分都是具体化的实现,简直是分分钟搞定!这可能是数学系的转到编程领域很厉害的原因吧。
逻辑思维能力通过学习数据结构和算法,做数据结构的习题可以得到有效的提高,抽象能力需要在实践中不断的练习、积累经验。
对于初学编程的同学,从现在就开始努力提升吧!
H. java中的算法,一共有多少种,哪几种,怎么分类。
就好比问,汉语中常用写作方法有多少种,怎么分类。
算法按用途分,体现设计目的、有什么特点
算法按实现方式分,有递归、迭代、平行、序列、过程、确定、不确定等等
算法按设计范型分,有分治、动态、贪心、线性、图论、简化等等
作为图灵完备的语言,理论上”Java语言“可以实现所有算法。
“Java的标准库'中用了一些常用数据结构和相关算法.
像apache common这样的java库中又提供了一些通用的算法
I. Java 的垃圾回收如何判断哪个对象可以被回收
java对象符合以下条件便会被垃圾回收:
1.所有实例都没有活动线程访问。
2.没有被其他任何实例访问的循环引用实例。
3.Java 中有不同的引用类型。判断实例是否符合垃圾收集的条件都依赖于它的引用类型。
在编译过程中作为一种优化技术,Java编译器能选择给实例赋null值,从而标记实例为可回收。
classAnimal{
publicstaticvoidmain(String[]args){
Animallion=newAnimal();
System.out.println("Mainiscompleted.");
}
protectedvoidfinalize(){
System.out.println("RestinPeace!");
}
}