主要用于计算代理ip池设计,实现概率选择优质代理ip,所以简单写了个权重随机算法。
如果量大注意int 超限,默认20次 支持107374182个ip。
权重对象类
public class IpWeight {
private String address;//地址
private int weight=20;//可用次数
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public IpWeight(String address) {
super();
this.address = address;
}
public IpWeight(String address, int weight) {
super();
this.address = address;
this.weight = weight>=0?weight:0;
}
public void reduce(){
this.weight = weight>=1?(weight-1):0;
}
public void reduce(int n){
this.weight = weight>=n?(weight-n):0;
}
@Override
public String toString() {
return "IpWeight [address=" + address + ", weight=" + weight + "]";
}
/**
* set<User></>去重,重新如下两个方法hashCode、equals
*/
@Override
public int hashCode(){
return address.hashCode();
}
@Override
public boolean equals(Object obj){
if(obj instanceof IpWeight){
IpWeight ipWeight=(IpWeight)obj;
return address.equals(ipWeight.address);
}
return super.equals(obj);
}
算法实现类
/**
* 权重随机算法
* set [a,10] [b,10] [a,11]
* ↓ ↓
* [a,10] [b,10]
* ↓ ↓
* [a,10] [b,20]
* a[0,10) b[10,20)
* shoot[0,20)
* ↓ ↓
* get a or b
*/
public class IPtest {
public static void WeightedRandomAlgorithm(Set set) {
long s = System.currentTimeMillis();
// 加权算法开始
// set 转list 为了有序统计有效次数
List<IpWeight> result = new ArrayList<>(set);
// System.out.println(result.toString());
// list 转换 对象占用对应区域
if (result.size() > 1) {
List<IpWeight> result2 = new ArrayList<>();
// 边界
int limitsize = 0;
for (int i = 0; i < result.size(); i++) {
IpWeight ip = new IpWeight();
ip.setAddress(result.get(i).getAddress());
ip.setWeight(result.get(i).getWeight());
ip.setWeight(limitsize + result.get(i).getWeight());
limitsize = ip.getWeight();
result2.add(ip);
}
// System.out.println(result2.toString());
// 随机数
Random r = new Random();
int shoot = r.nextInt(result2.get(result2.size() - 1).getWeight());
// shoot=87;
// shoot=shoot2;
System.out.println(shoot);
// 遍历 计算随机数所在的区域
for (int j = 0; j < result2.size(); j++) {
if (j >= 0 && j < result2.size() - 1) {
if (result2.get(j).getWeight() <= shoot && result2.get(j + 1).getWeight() > shoot) {
System.out.println(result2.get(j + 1).toString());
} else if (result2.get(j).getWeight() > shoot && j == 0) {
System.out.println(result2.get(j).toString());
}
}
}
} else {
System.out.println(result.get(0).toString());
}
long e = System.currentTimeMillis();
System.out.println("time:" + (e - s));
}
public static void main(String[] args) {
//stringRedisTemplate.keys("*" + pattern + "*");
//测试生成
IpWeight i1=new IpWeight("a");
IpWeight i2=new IpWeight("b");
IpWeight i3=new IpWeight("a",21);
IpWeight i4=new IpWeight("b",20);
IpWeight i5=new IpWeight("c",15);
IpWeight i6=new IpWeight("d",10);
IpWeight i7=new IpWeight("e",14);
IpWeight i8=new IpWeight("f",12);
IpWeight i9=new IpWeight("g",10);
IpWeight i10=new IpWeight("h",11);
System.out.println(i1);
System.out.println(i2);
i1.reduce(15);
System.out.println(i1);
Set set=new HashSet<>();
set.add(i1);
set.add(i1);
set.add(i2);
set.add(i2);
set.add(i3);
set.add(i4);
set.add(i5);
set.add(i6);
set.add(i7);
set.add(i8);
set.add(i9);
set.add(i10);
for (int i = 0; i < 1000; i++) {
set.add(new IpWeight("a"+i,i+1));
}
/* //验证是否去重
Iterator<IpWeight> it=set.iterator();
while (it.hasNext()) {
IpWeight str = it.next();
System.out.println("----");
System.out.println(str);
}*/
WeightedRandomAlgorithm(set);
}
}
经测试千个以内耗时0.002s