要求:

TSP 算法(Traveling Salesman Problem)是指给定 n 个城市和各个城市之间的距离,要

求确定一条经过各个城市当且仅当一次的最短路径,它是一种典型的优化组合问题,其最优

解得求解代价是指数级的。TSP 问题代表一类优化组合问题,在实际工程中有很多应用,如

计算机联网、电子地图、交通诱导等,具有重要的研究价值。遗传算法和禁忌搜所算法都是

是一种智能优化算法,具有全局的优化性能、通用性强。这种算法一般具有严密的理论依据,

理论上可以在一定的时间内找到最优解或近似最优解,广泛应用于计算机科学优化调度问题、

组合优化问题。通过阅读书籍以及科技文献,研究遗传算法或 禁忌搜索算法的基本原理,

研究TSP 问题并提出常见解决方案。要求在此基础上,编程实现以智能优化算法来解决 TSP

问题,并给出相应实验结果和算法分析。

遗传算法:

package org.wucl.ga;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.wucl.City;

/**
* 遗传算法解决TSP问题
*
* 1.个体编码方案 整数编码:对城市进行编号,每个城市分别用0到n-1之间不同的整数表示,n个整数的一个排列就代表了旅行商问题的一个可能解
*
* 2.交配方法 常规交配法,交配概率为100%
*
* 3.变异方法 打乱变异,使用逆序方式,变异概率为10%
*
* 4.新种群构成的方法 用轮盘赌求出子代种群
*
* 5.算法结束的条件 当代数打到200时,结束算法
*
* @author wucl(lailaiwcl@163.com)
*
*/
public class Genetic {

List<City> vec = new ArrayList<City>();
int n = 0;
int num;
double optimal; // 记录最优解
int best[] = new int[n]; // 记录最终路径

public void getStrategy() {

try {
Reader reader = new InputStreamReader(Genetic.class
.getClassLoader().getResourceAsStream("data.txt"));
BufferedReader br = new BufferedReader(reader);
String line = br.readLine();
while (line != null) {
String[] sa = line.split(" ");
vec.add(new City(sa[0], Double.parseDouble(sa[1]), Double
.parseDouble(sa[2])));
line = br.readLine();
}
n = vec.size();
} catch (IOException e) {
e.printStackTrace();
}
num = 4 * n * n; // 初始个体数为4*n*n;
int a[][] = new int[num][n];

for (int i = 0; i < num; i++) // 随机生成num个个体
{
a[i] = random(n, n);
}
optimal = getValue(a[0])[1];
for (int i = 0; i < 200; i++) {
a = nextGen(a);
}
System.out.print("最佳路径:");
for (int i = 0; i < n - 1; i++)
System.out.print(vec.get(best[i]).name + "->");
System.out.println(vec.get(best[n - 1]).name);
System.out.println("最佳长度:" + optimal);
}

public int[] random(int m, int t) // 生成互不相同的随机数序列的函数
{
Random r = new Random();
int k = 0;
int tmp[] = new int[m];
for (int i = 0; i < m; i++) {
while (true) {
boolean flag = true;
tmp[i] = r.nextInt(t);
k++;
for (int j = 0; j < k - 1; j++) {
if (tmp[i] == tmp[j]) {
k--;
flag = false;
break;
}
}
if (flag == true)
break;
}
}
return tmp;
}

public int[][] Crossove(int a[][]) // 交配函数
{
int A[][] = new int[num][n];
int k = 0;
for (int i = 0; i < num; i = i + 2) {
Random r = new Random();
int loc = r.nextInt(n - 1);
for (int j = 0; j <= loc; j++) {
A[k][j] = a[i][j];
A[k + 1][j] = a[i + 1][j];
}
int m1 = loc + 1, m2 = m1;
for (int t = 0; t < n; t++) {
if (!is_exist(loc, a[i + 1][t], a[i])) {
A[k][m1] = a[i + 1][t];
m1++;
}
if (!is_exist(loc, a[i][t], a[i + 1])) {
A[k + 1][m2] = a[i][t];
m2++;
}

}
if (r.nextInt(100) < 10) {
A[k] = variation(A[k]);
}
if (r.nextInt(100) < 10) {
A[k + 1] = variation(A[k + 1]);
}
k += 2;
}
return A;
}

public int[][] nextGen(int a[][]) // 生成新种群的函数
{
int A[][] = new int[num][n];
double p[] = new double[num];
double value[] = new double[num];
double sum = 0;
for (int i = 0; i < num; i++) {
double tmp[] = new double[2];
tmp = getValue(a[i]);
value[i] = tmp[0];
if (optimal > tmp[1]) {
optimal = tmp[1];
best = a[i];
}
sum += value[i];
}
for (int i = 0; i < num; i++) {
p[i] = value[i] / sum;
}
int k = 0;
for (int i = 0; i < num; i++) {
double s = 0;
int j = 0;
double r = Math.random();
while (true) {
if (s >= r)
break;
s += p[j];
j++;
}
A[k] = a[j - 1];
k++;
}
return Crossove(A);
}

public boolean is_exist(int loc, int x, int b[]) {
for (int i = 0; i <= loc; i++) {
if (x == b[i])
return true;
}
return false;
}

public int[] variation(int a[]) // 变异函数
{
int b[] = new int[n];
Random r = new Random();
int x = r.nextInt(n);
int y = r.nextInt(n);
while (y == x)
y = r.nextInt(n);
if (x < y) {
int k = 0;
for (int i = 0; i < n; i++) {
if (i < x)
b[i] = a[i];
else if (i > y)
b[i] = a[i];
else {
b[i] = a[y - k];
k++;
}
}
} else {
int yy = y, k = 1;
for (int i = 0; i < n; i++) {
if (i <= yy) {
b[i] = a[y];
y--;
} else if (i >= x) {
b[i] = a[n - k];
k++;
} else
b[i] = a[i];

}
}
return b;
}

public double[] getValue(int a[]) // 获取路径值的函数
{
double length = 0;
int k = a.length - 1;
for (int i = 0; i < k; i++) {
double tmp1 = Math.pow(vec.get(a[i]).x - vec.get(a[i + 1]).x, 2);
double tmp2 = Math.pow(vec.get(a[i]).y - vec.get(a[i + 1]).y, 2);
length += Math.sqrt(tmp1 + tmp2);
}
double tmp1 = Math.pow(vec.get(a[0]).x - vec.get(a[k]).x, 2);
double tmp2 = Math.pow(vec.get(a[0]).y - vec.get(a[k]).y, 2);
length += Math.sqrt(tmp1 + tmp2);
double f[] = new double[2];
f[0] = 1 / Math.pow(length, 8);
f[1] = length;
return f;
}

public static void main(String argv[]) {
new Genetic().getStrategy();
}
}

禁忌搜索算法(1):单线程实现

package org.wucl.ts;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Random;

import org.wucl.ga.Genetic;
/**
* 单线程实现禁忌搜索算法解决TSP问题
*
*
* @author wucl(lailaiwcl@163.com)
*
*/
public class Tabu {

private int MAX_GEN;// 迭代次数

private int N;// 每次搜索邻居个数

private int ll;// 禁忌长度

private int cityNum; // 城市数量,编码长度

private double[][] distance; // 距离矩阵

private int bestT;// 最佳出现代数

private int[] Ghh;// 初始路径编码

private int[] bestGh;// 最好的路径编码

private double bestEvaluation;

private int[] LocalGhh;// 当代最好编码

private double localEvaluation;

private int[] tempGhh;// 存放临时编码

private double tempEvaluation;

private int[][] jinji;// 禁忌表

private int t;// 当前代数

private Random random;

public Tabu() {

}

/**
*
* constructor of Tabu
*
* @param n
*
* 城市数量
* @param g
*
* 运行代数
* @param c
*
* 每次搜索邻居个数
*
* @param m
*
* 禁忌长度
*
**/

public Tabu(int n, int g, int c, int m) {
cityNum = n;
MAX_GEN = g;
N = c;
ll = m;
}

/**

* 初始化Tabu算法类

* @param filename 数据文件名,该文件存储所有城市节点坐标数据

* @throws IOException

*/
private void init() throws IOException {

// 读取数据
int[] x;
int[] y;
String strbuff;
Reader reader = new InputStreamReader(Genetic.class.getClassLoader().getResourceAsStream("data.txt"));
BufferedReader data = new BufferedReader(reader);
distance = new double[cityNum][cityNum];
x = new int[cityNum];
y = new int[cityNum];
for (int i = 0; i < cityNum; i++) {
strbuff = data.readLine();
String[] strcol = strbuff.split(" ");
x[i] = Integer.valueOf(strcol[1]);// x坐标
y[i] = Integer.valueOf(strcol[2]);// y坐标

}
// 计算距离矩阵
//System.out.println("距离矩阵为:");
for (int i = 0; i < cityNum - 1; i++) {
distance[i][i] = 0; // 对角线为0
for (int j = 0; j < cityNum; j++) {
distance[i][j] = Math
.sqrt(((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j])
* (y[i] - y[j])));
//System.out.print(Math.ceil(distance[i][j]) + " ");
}
//System.out.println();

}

distance[cityNum - 1][cityNum - 1] = 0;
Ghh = new int[cityNum];
bestGh = new int[cityNum];
bestEvaluation = Integer.MAX_VALUE;
LocalGhh = new int[cityNum];
localEvaluation = Integer.MAX_VALUE;
tempGhh = new int[cityNum];
tempEvaluation = Integer.MAX_VALUE;
jinji = new int[ll][cityNum];
bestT = 0;
t = 0;
random = new Random(System.currentTimeMillis());
}

// 初始化编码Ghh

void initGroup() {
int i, j;
Ghh[0] = random.nextInt(65535) % cityNum;
for (i = 1; i < cityNum;)// 编码长度
{
Ghh[i] = random.nextInt(65535) % cityNum;
for (j = 0; j < i; j++) {
if (Ghh[i] == Ghh[j]) {
break;
}
}
if (j == i) {
i++;
}
}
}

// 复制编码体,复制编码Gha到Ghb

public void copyGh(int[] Gha, int[] Ghb) {
for (int i = 0; i < cityNum; i++) {
Ghb[i] = Gha[i];
}
}

public double evaluate(int[] chr) {
double len = 0;
// 编码,起始城市,城市1,城市2...城市n
for (int i = 1; i < cityNum; i++) {
len += distance[chr[i - 1]][chr[i]];
}
// // 城市n,起始城市
len += distance[chr[cityNum - 1]][chr[0]];
// for (int i = 1; i < cityNum; i++) {
// System.out.print(chr[i] + ",");
// }
// System.out.println("-------------" + len);
return len;
}

// 邻域交换,得到邻居
public void Linju(int[] Gh, int[] tempGh) {
int i, temp;
int ran1, ran2;
for (i = 0; i < cityNum; i++) {
tempGh[i] = Gh[i];
}
ran1 = random.nextInt(65535) % cityNum;
ran2 = random.nextInt(65535) % cityNum;
while (ran1 == ran2) {
ran2 = random.nextInt(65535) % cityNum;
}
temp = tempGh[ran1];
tempGh[ran1] = tempGh[ran2];
tempGh[ran2] = temp;

}

// 判断编码是否在禁忌表中

public int panduan(int[] tempGh) {
int i, j;
int flag = 0;
for (i = 0; i < ll; i++) {
flag = 0;
for (j = 0; j < cityNum; j++) {
if (tempGh[j] != jinji[i][j]) {
flag = 1;// 不相同
break;
}
}
if (flag == 0)// 相同,返回存在相同
{
// return 1;
break;

}
}

if (i == ll)// 不等
{
return 0;// 不存在

} else {
return 1;// 存在
}
}

// 解禁忌与加入禁忌

public void jiejinji(int[] tempGh) {
int i, j, k;
// 删除禁忌表第一个编码,后面编码往前挪动
for (i = 0; i < ll - 1; i++) {
for (j = 0; j < cityNum; j++) {
jinji[i][j] = jinji[i + 1][j];
}
}

// 新的编码加入禁忌表

for (k = 0; k < cityNum; k++) {
jinji[ll - 1][k] = tempGh[k];
}
}

public void solve() {
int nn;
// 初始化编码Ghh
initGroup();
copyGh(Ghh, bestGh);// 复制当前编码Ghh到最好编码bestGh
bestEvaluation = evaluate(Ghh);
while (t < MAX_GEN) {
nn = 0;
localEvaluation = Integer.MAX_VALUE;
while (nn < N) {
Linju(Ghh, tempGhh);// 得到当前编码Ghh的邻域编码tempGhh
if (panduan(tempGhh) == 0)// 判断编码是否在禁忌表中
{
// 不在
tempEvaluation = evaluate(tempGhh);
if (tempEvaluation < localEvaluation) {
copyGh(tempGhh, LocalGhh);
localEvaluation = tempEvaluation;
}
nn++;
}
}
if (localEvaluation < bestEvaluation) {
bestT = t;
copyGh(LocalGhh, bestGh);
bestEvaluation = localEvaluation;
}
copyGh(LocalGhh, Ghh);
// 解禁忌表,LocalGhh加入禁忌表
jiejinji(LocalGhh);
t++;
}
System.out.print("最佳长度出现代数:");
System.out.println(bestT);
System.out.print("最佳长度:");
System.out.println(bestEvaluation);
System.out.print("最佳路径:");
for (int i = 0; i < cityNum; i++) {
System.out.print(bestGh[i] + "->");
}
}

public static void main(String[] args) throws IOException {
System.out.println("Start....");
Tabu tabu = new Tabu(30,200000, 200, 20);
tabu.init();
long t1 = System.currentTimeMillis();
tabu.solve();
System.out.println();
System.out.println("计算用时:" + (System.currentTimeMillis() - t1));
}

}

禁忌搜索算法(2):多线程是实现

package org.wucl.ts;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Random;

import org.wucl.ga.Genetic;

/**
* 多线程调度实现禁忌搜索算法解决TSP问题
*
*
* @author wucl(lailaiwcl@163.com)
*
*/
public class Tabu2 {

public static int MAX_GEN;// 迭代次数

private int N;// 每次搜索邻居个数

private int ll;// 禁忌长度

private int cityNum; // 城市数量,编码长度

private double[][] distance; // 距离矩阵

public int bestT;// 最佳出现代数

private int[] Ghh;// 初始路径编码

public int[] bestGh;// 最好的路径编码

public double bestEvaluation;

private int[] LocalGhh;// 当代最好编码

public double localEvaluation;

private int[] tempGhh;// 存放临时编码

private double tempEvaluation;

private static int[][] jinji;// 禁忌表

private static int t;// 当前代数

private Random random;

private Object obj1 = new Object();

private Object obj2 = new Object();

public Tabu2() {

}

/**
*
* constructor of Tabu
*
* @param n
*
* 城市数量
* @param g
*
* 运行代数
* @param c
*
* 每次搜索邻居个数
*
* @param m
*
* 禁忌长度
*
**/

public Tabu2(int n, int c, int m) {
cityNum = n;
N = c;
ll = m;
}

/**

* 初始化Tabu算法类

* @param filename 数据文件名,该文件存储所有城市节点坐标数据

* @throws IOException

*/
private void init() throws IOException {

// 读取数据
int[] x;
int[] y;
String strbuff;
Reader reader = new InputStreamReader(Genetic.class.getClassLoader()
.getResourceAsStream("data.txt"));
BufferedReader data = new BufferedReader(reader);
distance = new double[cityNum][cityNum];
x = new int[cityNum];
y = new int[cityNum];
for (int i = 0; i < cityNum; i++) {
strbuff = data.readLine();
String[] strcol = strbuff.split(" ");
x[i] = Integer.valueOf(strcol[1]);// x坐标
y[i] = Integer.valueOf(strcol[2]);// y坐标

}
// 计算距离矩阵
// System.out.println("距离矩阵为:");
for (int i = 0; i < cityNum - 1; i++) {
distance[i][i] = 0; // 对角线为0
for (int j = 0; j < cityNum; j++) {
distance[i][j] = Math
.sqrt(((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j])
* (y[i] - y[j])));
}

}

distance[cityNum - 1][cityNum - 1] = 0;
Ghh = new int[cityNum];
bestGh = new int[cityNum];
bestEvaluation = Integer.MAX_VALUE;
LocalGhh = new int[cityNum];
localEvaluation = Integer.MAX_VALUE;
tempGhh = new int[cityNum];
tempEvaluation = Integer.MAX_VALUE;
jinji = new int[ll][cityNum];
bestT = 0;
t = 0;
random = new Random(System.currentTimeMillis());
}

// 初始化编码Ghh

void initGroup() {
int i, j;
Ghh[0] = random.nextInt(65535) % cityNum;
for (i = 1; i < cityNum;)// 编码长度
{
Ghh[i] = random.nextInt(65535) % cityNum;
for (j = 0; j < i; j++) {
if (Ghh[i] == Ghh[j]) {
break;
}
}
if (j == i) {
i++;
}
}
}

// 复制编码体,复制编码Gha到Ghb

public void copyGh(int[] Gha, int[] Ghb) {
for (int i = 0; i < cityNum; i++) {
Ghb[i] = Gha[i];
}
}

public double evaluate(int[] chr) {
double len = 0;
// 编码,起始城市,城市1,城市2...城市n
for (int i = 1; i < cityNum; i++) {
len += distance[chr[i - 1]][chr[i]];
}
// // 城市n,起始城市
len += distance[chr[cityNum - 1]][chr[0]];
return len;
}

// 邻域交换,得到邻居
public void Linju(int[] Gh, int[] tempGh) {
int i, temp;
int ran1, ran2;
for (i = 0; i < cityNum; i++) {
tempGh[i] = Gh[i];
}
ran1 = random.nextInt(65535) % cityNum;
ran2 = random.nextInt(65535) % cityNum;
while (ran1 == ran2) {
ran2 = random.nextInt(65535) % cityNum;
}
temp = tempGh[ran1];
tempGh[ran1] = tempGh[ran2];
tempGh[ran2] = temp;

}

// 判断编码是否在禁忌表中
public int panduan(int[] tempGh) {
int i, j;
int flag = 0;
for (i = 0; i < ll; i++) {
flag = 0;
for (j = 0; j < cityNum; j++) {
if (tempGh[j] != jinji[i][j]) {
flag = 1;// 不相同
break;
}
}
if (flag == 0)// 相同,返回存在相同
{
// return 1;
break;

}
}

if (i == ll)// 不等
{
return 0;// 不存在
} else {
return 1;// 存在
}
}

// 解禁忌与加入禁忌
public void jiejinji(int[] tempGh) {
synchronized (obj2) {
int i, j, k;
// 删除禁忌表第一个编码,后面编码往前挪动
for (i = 0; i < ll - 1; i++) {
for (j = 0; j < cityNum; j++) {
jinji[i][j] = jinji[i + 1][j];
}
}

// 新的编码加入禁忌表
for (k = 0; k < cityNum; k++) {
jinji[ll - 1][k] = tempGh[k];
}
}
}

public void solve() {
try {
init();
} catch (IOException e) {
e.printStackTrace();
}
int nn;
// 初始化编码Ghh
initGroup();
copyGh(Ghh, bestGh);// 复制当前编码Ghh到最好编码bestGh
bestEvaluation = evaluate(Ghh);
while (t < MAX_GEN) {
nn = 0;
localEvaluation = Integer.MAX_VALUE;
while (nn < N) {
Linju(Ghh, tempGhh);// 得到当前编码Ghh的邻域编码tempGhh
if (panduan(tempGhh) == 0)// 判断编码是否在禁忌表中
{
// 不在
tempEvaluation = evaluate(tempGhh);
if (tempEvaluation < localEvaluation) {
copyGh(tempGhh, LocalGhh);
localEvaluation = tempEvaluation;
}
nn++;
}
}
if (localEvaluation < bestEvaluation) {
bestT = t;
copyGh(LocalGhh, bestGh);
bestEvaluation = localEvaluation;
}
copyGh(LocalGhh, Ghh);
// 解禁忌表,LocalGhh加入禁忌表
jiejinji(LocalGhh);
synchronized (obj1) {
t++;
}
}
}

public static void main(String[] args) {
Tabu2.MAX_GEN = 200000;
final Tabu2 tabu1 = new Tabu2(30, 200, 20);
final Tabu2 tabu2 = new Tabu2(30, 200, 20);
final Thread thread1 = new Thread("thread-1") {
@Override
public void run() {
System.out.println("thread-1 start...");
tabu1.solve();
}
};
final Thread thread2 = new Thread("thread-2") {
@Override
public void run() {
System.out.println("thread-2 start...");
tabu2.solve();
}
};
final long t1 = System.currentTimeMillis();
Thread thread3 = new Thread("thread-2") {
@Override
public void run() {
System.out.println("thread-3 start...");
while (true) {
if (!thread1.isAlive() && !thread2.isAlive()) {
Tabu2 bestTabu = tabu1;
if (tabu1.localEvaluation <= tabu2.localEvaluation) {
bestTabu = tabu2;
}
System.out.print("最佳长度出现代数:");
System.out.println(bestTabu.bestT);
System.out.print("最佳长度:");
System.out.println(bestTabu.bestEvaluation);
System.out.print("最佳路径:");
for (int i = 0; i < 30; i++) {
System.out.print(bestTabu.bestGh[i] + "->");
}
System.out.println();
break;
}
}
System.out.println("计算用时:" + (System.currentTimeMillis() - t1));
}
};
thread1.start();
thread2.start();
thread3.start();
}

}

智能优化算法对TSP问题的求解研究的更多相关文章

  1. 模拟退火算法SA原理及python、java、php、c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径

    模拟退火算法SA原理及python.java.php.c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径 模拟退火算法(Simulated Annealing,SA)最早的思 ...

  2. 群智能优化算法-测试函数matlab源码

    群智能优化算法测试函数matlab源代码 global M; creatematrix(2); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %画ackley图. %%%% ...

  3. TSP问题 遗传算法 智能优化算法

    写了半天,效率还是有点低的,以后有空再优化下: //用次序表示法来表示个体编码 #include<iostream> #include<fstream> #include< ...

  4. 【优化算法】遗传算法GA求解混合流水车间调度问题(附C++代码)

    00 前言 各位读者大家好,好久没有介绍算法的推文了,感觉愧对了读者们热爱学习的心灵.于是,今天我们带来了一个神奇的优化算法--遗传算法! 它的优点包括但不限于: 遗传算法对所求解的优化问题没有太多的 ...

  5. 最优化算法——常见优化算法分类及总结

    之前做特征选择,实现过基于群智能算法进行最优化的搜索,看过一些群智能优化算法的论文,在此做一下总结. 在生活或者工作中存在各种各样的最优化问题,比如每个企业和个人都要考虑的一个问题"在一定成 ...

  6. 计算智能(CI)之粒子群优化算法(PSO)(一)

    欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识! 计算智能(Computational Intelligence , ...

  7. 粒子群优化算法及其java实现

    憋了两周终于把开题报告憋出来了,再一次证明自己不适合搞学术,哎--,花了点时间把报告中提到的粒子群算法看了看,看了些资料,用java跑起来. 算法简介 粒子群算法最先由Barnhart博士和Kenne ...

  8. 【优化算法】Greedy Randomized Adaptive Search算法 超详细解析,附代码实现TSP问题求解

    01 概述 Greedy Randomized Adaptive Search,贪婪随机自适应搜索(GRAS),是组合优化问题中的多起点元启发式算法,在算法的每次迭代中,主要由两个阶段组成:构造(co ...

  9. paper 8:支持向量机系列五:Numerical Optimization —— 简要介绍求解求解 SVM 的数值优化算法。

    作为支持向量机系列的基本篇的最后一篇文章,我在这里打算简单地介绍一下用于优化 dual 问题的 Sequential Minimal Optimization (SMO) 方法.确确实实只是简单介绍一 ...

随机推荐

  1. SpringMVC源码情操陶冶#task-executor解析器

    承接Spring源码情操陶冶-自定义节点的解析.线程池是jdk的一个很重要的概念,在很多的场景都会应用到,多用于处理多任务的并发处理,此处借由spring整合jdk的cocurrent包的方式来进行深 ...

  2. jquery基础总结 -- 转载

    jquery的each里面return的使用 在使用jquery的each方法时, return false相当于break,是跳出each循环,return true相当于continue,是继续循 ...

  3. django models的点查询/跨表查询/双下划线查询

    django models 在日常的编程中,我们需要建立数据库模型 而往往会用到表与表之间的关系,这就比单表取数据要复杂一些 在多表之间发生关系的情形下,我们如何利用models提供的API的特性获得 ...

  4. 电子称DIY(贴应变片+写代码)

    第一步.应变片介绍   ---------------------------------------------------------------------------------------- ...

  5. (转载) ASP.NET(C#) Web Api 通过文件流下载文件到本地实例

    下载文件到本地是很多项目开发中需要实现的一个很简单的功能.说简单,是从具体的代码实现上来说的,.NET的文件下载方式有很多种,本示例给大家介绍的是ASP.NET Web Api方式返回HttpResp ...

  6. SQL Server元数据损坏(metadata corruption)修复

    在升级一个SQL Server 2000的数据库时,遇到了一致性错误,其中有几个错误是元数据损坏(metadata corruption),特意研究了一下这个案例,因为以前也零零散散的遇到过一些一致性 ...

  7. solr云的简单搭建(了解)

    1.认识系统架构 1.1.集群概述 1.1.1.单点服务器的问题 我们之所以要学习集群,是因为单点服务器,存在一系列的问题. 我们以前学习的JavaEE项目,都是部署在一台Tomcat上,所有的请求, ...

  8. 使用 Angular CLI 和 Webpack 分析包尺寸

    使用 Angular CLI 和 Webpack 分析包尺寸 对于 Web app 来说,高性能总是最高优先级,对于 Angular 也不例外.但是随着应用复杂度的不断增长,我们如何才能知道哪些内容打 ...

  9. 日推20单词 Day01

    1.conflict n. 冲突 2.electronic adj. 电子的 3.mine n. 矿藏,地雷 4.mineral n. 矿物质 adj. 矿物的 5.undermine vt 破坏,渐 ...

  10. sys.exc_info()可以捕获到任意异常

    import sys try: a = 3 assert a > 4 except: exc = sys.exc_info()#返回异常的元祖 print (exc)