Stack类测试:
在测试Stck类型的变量内容是否正确时,经常会通过把所有值pop出来输出的方法,这样容易造成一个问题就是,栈已经被弄空了,以后再用的时候就会是一个空栈。所以,栈类型的变量测试完了以后及的把测试部分注释掉。或者查一下有没有好的方法用来测试栈
2017.11.15
//逻辑错误:版本v2,更改NodeRank类的rank方法,但是节点排名值得计算结果跟v1版本不一致,
//修改:map.put(i, t+0.4*nov(i,j)*map.get(i));===〉map.put(i, t+0.4*nov(i,j)*map.get(j));
开始考虑的是用queue存储最终的节点排名,把队列变量以参数的方式传输到finalRank()函数,这样先进先出后来用到映射过程中就可以
现在又想,就用ArrayList存储,按照value排名,然后下标从1开始遍历,得到跟queue一样的效果。
2017.11.18
今天需要处理两个图了,由于NodeRank类里面之前把g定义成了static,发现在main里面对g分别用两个图赋值,只按照最后一次赋值的来,而且啊,程序都需运行第一次赋值之后的rank方法。
code:
System.out.println("这是第一个start");
NodeRank.g=g2;
rank=NodeRank.rank();
System.out.println("这是第一个rank");
NodeRank.g=g;
rank2=NodeRank.rank();
System.out.println("这是第二个rank");
result:
这是第一个start
这是第一个rank
这是第二个rank
排名结果:2--0.3479683489497371
排名结果:0--0.28652638523658425
排名结果:1--0.20537981498161176
处理:只能是把g定义成普通的,然后再用构造函数初始化g,这样对于不同的图就有了相应的rank类。
注意-----后来发现,我的测试输出可能是有问题的,所以上面说的g是static时候只按照第二次赋值的说法可能有误,记住退回到v2版本去看看到底是不是只按照最后一次赋值的处理,在v2中,g还是static。由于发现把g定义成非静态处理以后似乎更好所以没有退回去检测。再后来,我发现好像只需要给一个图排序,也就是VNR的图,现在想想弄成静态的也可以,再再后来,又想,是要有多个VNR的,哎哟,问题好像更多了呢。
问题:测试的时候发现,会映射到重复的节点上。
解决:对于物理网络节点,添加一个标志位,已经被映射过的就干脆因为不符合要求而直接不被加入备选项中。这个标志位对于一个网络请求的所有节点映射过程中起作用的,所以要声明在遍历VNR节点之前。
主动排查发现:sim这个数组,对于一个VNR中的每一个节点都要进行一次更新,所以一定一定要声明在里面,(代码中有一个声明被注释掉了,可以注意下),这样上次节点的结果才不会影响这次的。
结果不理想,排查发现:一个超级大的逻辑错误,我的方法里面,只传入了物理网络而没有虚拟网络,关于虚拟网络只是传入了节点下标和排名值,但是我在方法内部,同时需要获得物理网络cpu和虚拟网络cpu,在我想要虚拟网络cpu的时候,我是用物理网络拓扑的g,还有虚拟网络拓扑的节点下标去查的,这个根本没有任何含义!!傻子傻子傻子!!!
解决:给方法添加一个参数,传递进去虚拟网络拓扑咯。总感觉还有别的办法,但是哪个更好却不知道了。
2017.11.19(main和embedding方法)
语法问题:方法需要Map类型的变量,传入LinkedHashMap型的提出语法错误。声明和创建的时候都用的LinkedHashMap不行,但是声明用map,初始化用linkedhashmap就行。
上面说错了,其实是,方法返回一个map型的,我要赋值给一个linkedhashmap的变量l,l被声明成map,初始化成linkedhashmap的时候没毛病,但是声明并初始化成linkedhashmap的时候不行。
2017.11.21(Floyd方法)
问题:在floyd算法里面,把路径入栈再出栈的时候,用的for循环,终止条件是(i<stack.size()),然后在循环里面出栈。一直出问题,忽略了出栈后size是会变得,所以每次测试i的时候,size都不一样
改正:如果还是用for循环的话,就需要把初始时候的size存储,然后再用做循环终止条件。后来没有用for,而是改用while,在栈非空的时候执行循环。所以对栈来说,似乎while循环更合适一点儿。
大改embedding类,EmbedOrder类,
其中embedorder类,更改了返回类型为link<Map>//
2017.11.22
Floyd.java
在后面的编程中发现,我需要知道floyd计算后整条路径的权重以及这条路径(先计算路径权值,如果权值较小,再去记录路径),所以这一个算法对我来说需要返回两类值:路径list,还有路径权重,临时为了更改方便,决定加入
int[][]用来存储路径权重//这里一定一定要好好改改,待改进
embedding方法,需要返回两类值,节点间的对应关系以及链路间的对应关系。现在打算用返回类型返回节点间的对应关系,用参数引用的方式返回链路间的对应关系。后期的改进中,要把这两类数值存储到txt里面,如果是一个txt的话,一行内容,表示 虚拟起始、虚拟终止、物理起始、物理终止、物理路径
2017.11.23
启发:
如果想要在一个方法里面返回多种数据,可以考虑把结果写成一个数据类型啊,里面的成员变量就是你要的多个结果
感受:初期留下的“小将就”,在后面都是“大麻烦”,教训教训啊!!!
2017.11.24
经验:什么样的变量没有被初始化才会被报错?
An:如果,你的变量定义了,没有初始值,后面首次用它是为了给他赋值,也就是在等号的左边,那么就没关系
但是如果你没有给他初值,而且还没有让他被赋值,就开始让他作为方法参数或者放在等号右边,那么就会报错。一种情况,即使你赋值了,如果没有跟后面用到的地方在一个代码块里,有可能也报错,比如,在if==0的时候赋值,在if==1的时候使用变量,就会报错。变量一旦被放入if里面再赋值的话,除非所有的if都有赋值语句,不然在if外面用的话就会被报错。
局部变量要先给赋初值才能进行使用,成员变量可以不赋初值,它有默认值,但是局部变量在声明的时候最好给赋初值。要不会出现编译错误
,JAVA局部变量都必须给初始值的
下面例子
for(Map.Entry<Integer, Double>e:embOrder.entrySet()) {
int firstSel;//用于存储第一个VNR节点对应的物理节点
int lastSel;//用于存储上一个VNR节点对应的物理节点
List<Integer> pathSel;//某对被选中的节点最终被选中的路径
int pathLength=5000;//用于存储对应的物理路径的长度,待改进,这里的;路径长度选的是长度上线,直接用5000不好
boolean[] fTemp=new boolean[pn.getNumOfNode()];//用于标志这个节点在回退过程中,有么有被映射过
if(t==0) {
entryFirst=e;
}
if(t==1) {
entry=e;
int firsTemp;//用于临时存储第一个虚拟节点某次被选中的物理节点
int lasTemp;//用于临时存储某个虚拟节点被临时选中的物理节点
List<Integer> pathTemp=new LinkedList<Integer>();//用于存储被临时选中的路径;
for(int j=0;j<3;j++){
{
double[] sim=new double[pn.getNumOfNode()];//待改进:这里不好。这个数组肯定用不到这么大,++但是,每个i都有可能被记录,所以用这么大的数组是可以的。
for(int i=0;i<pn.getNumOfNode();i++){
if(!f[i] && pn.getCpu(i)>=vn.getCpu(entryFirst.getKey())){//物理网络节点cpu大于VNR节点cpu
System.out.println("embedding__new__待映射点1与物理节点中满足要求的节点"+i+"的相似度:"+Similarity.cos(vn.getNode(entryFirst.getKey()),pn.getNode(i)));
sim[i]=Similarity.cos(vn.getNode(entryFirst.getKey()),pn.getNode(i));
//
g.getCpu(i)>g.getCpu(entryFirst.getKey()))
}
}
firsTemp=ProbabilitySelected.proSelected(sim);
fTemp[firsTemp]=true;
System.out.println("此次选中节点"+firsTemp);
}
/*启发:这里用了两个程序块,因为一个待映射节点对应一个sim数组,这个数组在存储的时候我是用节点下标作为数组下标的,为了不让上一次被允许的几点的sim值影响下一个节点的值,
* 所以sim这个数组,对于每一个待映射节点 都需要从空的数组开始,可以每次用之前更新赋值为0,但是我选择了使用俩程序块,在每个块里定义数组,这样更新,*/
{
double[] sim=new double[pn.getNumOfNode()];//待改进:这里不好。这个数组肯定用不到这么大,++但是,每个i都有可能被记录,所以用这么大的数组是可以的。
for(int i=0;i<pn.getNumOfNode();i++){
if(!fTemp[i] && !f[i] && pn.getCpu(i)>=vn.getCpu(entry.getKey())){//物理网络节点cpu大于VNR节点cpu
System.out.println("embedding__new__待映射点2与物理节点中满足要求的节点"+i+"的相似度:"+Similarity.cos(vn.getNode(entry.getKey()),pn.getNode(i)));
sim[i]=Similarity.cos(vn.getNode(entry.getKey()),pn.getNode(i));
//
g.getCpu(i)>g.getCpu(entry.getKey()))
}
}
lasTemp=ProbabilitySelected.proSelected(sim);
System.out.println("此次选中节点:"+lasTemp);
}
if(pathLength>Floyd.floyd(pn, firsTemp, lasTemp, pathTemp)) {//如果新得到的路径长度小,那么就存储这个新的路径对应的起始终止节点,以及路径
pathLength=Floyd.floyd(pn, firsTemp, lasTemp, pathTemp);
firstSel=firsTemp;
lastSel=lasTemp;
pathSel=pathTemp;
}
/*在这里就可以把映射结果加入到map里面啦*/
emb.put(entryFirst.getKey(), firstSel);
emb.put(entry.getKey(), lastSel);
}
}
}
经验:关于变量定义的位置,
他会影响循环的次数,在循环中还会影响是不是能把前面得到的值传递给后面,如果想传递,一定要定义到循环的外面。
又是一个变量定义位置影响运行结果的错误案例
41、42行和74、75行
package vnr.main;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import vnr.bandit.Embedding;
import vnr.graph.CreateGraph;
import vnr.graph.Edge;
import vnr.graph.Graph;
import vnr.graph.Node;
import vnr.rank.EmbedOrder;
import vnr.rank.NodeRank;
public class embedThread implements Runnable {
String folder;
Graph gPhy;
/**
* @param folderName 存储VNR的文件夹
* @param g 待映射的物理网络拓扑
* */
public embedThread(String folderName,Graph g) {
// TODO Auto-generated constructor stub
folder=folderName;
gPhy=g;
}
@Override
public void run() {
// TODO Auto-generated method stub
int nodeNumPhy=-1,edgeNumPhy=-1;
int nodeNumVir=-1,edgeNumVir=-1;//改进:这里好像用不到两个变量,物理网络和虚拟网络可以用同一对变量。
// LinkedHashMap<Integer,Double> embOrder =new LinkedHashMap<Integer,Double>();//最终映射顺序
// LinkedHashMap<Integer,Integer> result=new LinkedHashMap<Integer,Integer>();
int sucCount=0;
int failCount=0;
try {
// BufferedReader phyReader=new BufferedReader(new FileReader("sub.txt"));
Embedding embeder = new Embedding(".\\Result");
String line;
String regex=" ";
String[] lineContent;
List<String> lines=new LinkedList<String>();
/*虚拟网络相关变量*/
Edge[] edgeVir=null;
Node[] nodeVir=null;
Graph gVir=null;
//网络映射相关变量:noderank
List<Map.Entry<Integer,Double>> rank=new ArrayList<Map.Entry<Integer,Double>>();//VNR
/*虚拟网络topo处理,把表示虚拟网络拓扑的文件存为Graph*/
File demo = new File(folder);
File[] vnrs=demo.listFiles();
for(int j=0;j<vnrs.length;j++) {
BufferedReader virReader = new BufferedReader(new InputStreamReader(new FileInputStream(vnrs[j])));
LinkedHashMap<Integer,Double> embOrder =new LinkedHashMap<Integer,Double>();//最终映射顺序
LinkedHashMap<Integer,Integer> result=new LinkedHashMap<Integer,Integer>();
//启发:本来这两个变量的定义是在上面,但是运行的时候出现数组越界异常,debug发现result的似乎不太对,所以怀疑是前面对变量的赋值影响了后面
//试图调整变量定义的位置,使得每个虚拟网络请求都有自己的排序变量,所以放到for里面创建,果然不再出现异常
lines.clear();
while((line=virReader.readLine())!=null) {
lines.add(line);
}
for(int i=0;i<lines.size();i++) {
lineContent=lines.get(i).split(regex);
if(lineContent.length==2) {
nodeNumVir=Integer.parseInt(lineContent[0]);
edgeNumVir=Integer.parseInt(lineContent[1]);
edgeVir=new Edge[edgeNumVir];
nodeVir=new Node[nodeNumVir];
gVir=new Graph(nodeNumVir);
}else if(lineContent.length==1) {
nodeVir[i-1]=new Node(Double.parseDouble(lineContent[0]));
}else {
edgeVir[i-1-nodeNumVir]=new Edge(Integer.parseInt(lineContent[0]),Integer.parseInt(lineContent[1]),
Double.parseDouble(lineContent[2]));
}
}
CreateGraph.create(gVir, nodeVir, nodeNumVir, edgeVir, edgeNumVir);
/*计算节点排名以及映射顺序*/
NodeRank nr=new NodeRank(gVir);
rank=nr.rank();
for(int u=0;u<rank.size();u++) {
System.out.println(rank.get(u).getKey()+"-"+rank.get(u).getValue());
}
embOrder=EmbedOrder.embOrder(rank,gVir);
/*节点映射+链路映射*/
switch (embeder.embedding(embOrder, result, gVir, gPhy,j)) {
case 1://节点映射成功则进行链路映射
switch (embeder.embLink(gVir, gPhy, result,j)) {
case 1://链路映射成功
sucCount++;
break;
case -1://等待补充:映射失败后除了统计失败数量,还需要把被这个失败映射占用的资源恢复回来
failCount++;
break;
default:
break;
}
break;
case -1://等待补充:映射失败后除了统计失败数量,还需要把被这个失败映射占用的资源恢复回来
failCount++;
default:
break;
}
System.out.println("成功映射数目:"+sucCount);
System.out.println("失败映射数目:"+failCount);
}
} catch (Exception e) {
// TODO: handle exception
System.out.println("FROM embedThread.java-"+e);
}
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)