优化FireCenter部分代码

main
PeterAlbus 2 years ago
parent 4c6d1a2aba
commit 410754e6a7

@ -4,6 +4,7 @@ import com.peteralbus.entity.*;
import com.peteralbus.service.EarthquakeInfoService; import com.peteralbus.service.EarthquakeInfoService;
import com.peteralbus.service.EstimateService; import com.peteralbus.service.EstimateService;
import com.peteralbus.service.FireCenterService; import com.peteralbus.service.FireCenterService;
import com.peteralbus.util.EstimateUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.CrossOrigin;
@ -12,159 +13,186 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.*; import java.util.*;
/**
* The type Fire center controller.
*/
@CrossOrigin @CrossOrigin
@RestController @RestController
public class FireCenterController { public class FireCenterController {
private FireCenterService fireCenterService;
private EstimateController estimateController;
private EstimateService estimateService;
private EarthquakeInfoService earthquakeInfoService;
private EstimateUtil estimateUtil;
/**
* The Max fire center count.
*/
static Integer MAX_FIRE_CENTER_COUNT = 20;
/**
* Sets fire center service.
*
* @param fireCenterService the fire center service
*/
@Autowired @Autowired
FireCenterService fireCenterService; public void setFireCenterService(FireCenterService fireCenterService) {
this.fireCenterService = fireCenterService;
}
/**
* Sets estimate controller.
*
* @param estimateController the estimate controller
*/
@Autowired @Autowired
EstimateController estimateController; public void setEstimateController(EstimateController estimateController) {
this.estimateController = estimateController;
}
/**
* Sets estimate service.
*
* @param estimateService the estimate service
*/
@Autowired @Autowired
EstimateService estimateService; public void setEstimateService(EstimateService estimateService) {
this.estimateService = estimateService;
}
/**
* Sets earthquake info service.
*
* @param earthquakeInfoService the earthquake info service
*/
@Autowired
public void setEarthquakeInfoService(EarthquakeInfoService earthquakeInfoService) {
this.earthquakeInfoService = earthquakeInfoService;
}
/**
* Sets estimate util.
*
* @param estimateUtil the estimate util
*/
@Autowired @Autowired
EarthquakeInfoService earthquakeInfoService; public void setEstimateUtil(EstimateUtil estimateUtil) {
this.estimateUtil = estimateUtil;
}
/**
* Gets all fire center.
*
* @return the all fire center
*/
@RequestMapping("/getAllFireCenter") @RequestMapping("/getAllFireCenter")
public List<FireCenter> getAllFireCenter(){ public List<FireCenter> getAllFireCenter() {
return fireCenterService.getAllFireCenter(); return fireCenterService.getAllFireCenter();
} }
//获取一个地震区域的消防站位置 /**
public List<FireCenter> getOnePlaceAllFireCenter(Long earthquakeId){ *
List<FireCenter> fireCenters=getAllFireCenter(); *
List<FireCenter> fireCenterList=new ArrayList<>(); * @param earthquakeId the earthquake id
Map<String,Object>mapParameter=new HashMap<>(); * @return the one place all fire center
mapParameter.put("earthquakeId",earthquakeId); */
EarthquakeInfo earthquakeInfo=earthquakeInfoService.queryInfoWithLine(mapParameter).get(0); public List<FireCenter> getOnePlaceAllFireCenter(Long earthquakeId) {
for(FireCenter fireCenter:fireCenters){ List<FireCenter> fireCenters = fireCenterService.getAllFireCenter();
double distanceTwoPlaces=getDistance(fireCenter.getFireLon(),fireCenter.getFireLat(),earthquakeInfo.getLongitude(),earthquakeInfo.getLatitude()); List<FireCenter> fireCenterList = new ArrayList<>();
List<IntensityLine> intensityLineList=earthquakeInfo.getIntensityLineList(); Map<String, Object> mapParameter = new HashMap<>();
if(distanceTwoPlaces<intensityLineList.get(intensityLineList.size()-1).getLongRadius()) mapParameter.put("earthquakeId", earthquakeId);
{ EarthquakeInfo earthquakeInfo = earthquakeInfoService.queryInfoWithLine(mapParameter).get(0);
for (FireCenter fireCenter : fireCenters) {
double distanceTwoPlaces = getDistance(fireCenter.getFireLon(), fireCenter.getFireLat(), earthquakeInfo.getLongitude(), earthquakeInfo.getLatitude());
List<IntensityLine> intensityLineList = earthquakeInfo.getIntensityLineList();
if (distanceTwoPlaces < intensityLineList.get(intensityLineList.size() - 1).getLongRadius()) {
fireCenterList.add(fireCenter); fireCenterList.add(fireCenter);
} }
} }
return fireCenterList; return fireCenterList;
} }
/**
* Gets one fire center.
*
* @param id the id
* @return the one fire center
*/
@RequestMapping("/getOneFireCenter") @RequestMapping("/getOneFireCenter")
public FireCenter getOneFireCenter(int id){ public FireCenter getOneFireCenter(int id) {
return fireCenterService.getAllFireCenter().get(id); return fireCenterService.getAllFireCenter().get(id);
} }
/**
* IDfireCenterCount.
*
* @param earthquakeId ID
* @param fireCenterCount
* @return FireWeight
*/
@RequestMapping("/findFireCenterNearby") @RequestMapping("/findFireCenterNearby")
public List<FireWeight> getFireCenterWeight(Long earthquakeId){ public List<FireWeight> getFireCenterWeight(Long earthquakeId, Integer fireCenterCount) {
List<FireCenter> OnePlaceAllFireCenter=getOnePlaceAllFireCenter(earthquakeId); if (fireCenterCount > MAX_FIRE_CENTER_COUNT) {
List<Double> FireCenterIntensityArr=new ArrayList<>(); // 自行修改封装后的返回值,错误:资助点数量不能过多
for(FireCenter fireCenter:OnePlaceAllFireCenter){
FireCenterIntensityArr.add(estimateController.getPointIntensity(earthquakeId, fireCenter.getFireLon(), fireCenter.getFireLat()));
}
int FireCenterIntensityArSize=FireCenterIntensityArr.size();
System.out.print("FireCenterIntensityArSize长度为"+FireCenterIntensityArSize);
if(FireCenterIntensityArSize==0){
return null; return null;
} }
Map<Integer,Integer>map = new HashMap<Integer,Integer>(); List<FireCenter> fireCenterList = getOnePlaceAllFireCenter(earthquakeId);
for(int i=0;i<FireCenterIntensityArSize;i++){ List<FireCenter> randomFireCenterList = new ArrayList<>();
map.put(i,OnePlaceAllFireCenter.get(i).getFireId()); Random random = new Random();
} // 随机选取 fireCenterCount 个消防站
double [][] arr=new double [10][FireCenterIntensityArSize]; for (int i = 0; i < fireCenterCount; i++) {
//通过earthquakeId获得想要的地区的估计结果 if(fireCenterList.size()==0){
Estimate estimate=estimateService.queryAnalyzeById(earthquakeId); break;
int temp=0;
for(double f:FireCenterIntensityArr){
arr[0][temp]=f*100;//属性1对于资助点1、2、3的值,因为基本上属性是固定的,可能资助点的数量会增加,假定属性最大值为10个
arr[1][temp]=estimate.getPopulation()*f+100*Math.random();
arr[2][temp]=Math.log(estimate.getPredictDeath()*estimate.getPredictEconomy())+100*Math.random();
temp++;
}
// arr[1]=new double[] {0.847,0.63,0.921};
// arr[2]=new double[] {524,439,842};
double [][]arrNew=new double[10][FireCenterIntensityArSize];
double [][]arrNew1=new double[10][FireCenterIntensityArSize];
double sumProvide=0;
double max;
double min;
int strictNum=arr[0].length;//代表有多少个救助点
double k=1/(Math.log((double)strictNum));
double[] e=new double[10];//第 j 项指标的熵值 ej
double[] g=new double[10];//差异性系数 gi越大指标越重要
for(int j=0;j<3;j++) {
min=max=arr[j][0];
sumProvide=0;
for(int i=0;i<arr[j].length;i++) {
if(arr[j][i]<min) {
min=arr[j][i];
}
if(arr[j][i]>max) {
max=arr[j][i];
}
}
for(int i=0;i<arr[j].length;i++) {
arrNew[j][i]=(arr[j][i]-min)/(max-min);//假设都是正向指标,正向指标的值越大,就说明该地方越需要救助
arrNew1[j][i]=arrNew[j][i];
sumProvide+=arrNew[j][i];
}
for(int i=0;i<arr[j].length;i++) {
arrNew[j][i]=(arrNew[j][i]/sumProvide)+0.0000001;
}
double sumArrNewHang=0.0;
for(int i=0;i<arr[j].length;i++) {
//System.out.println("sum"+Math.log(arrNew[j][i]));
sumArrNewHang+=(arrNew[j][i]*Math.log(arrNew[j][i]));
} }
e[j]=(-k)*sumArrNewHang; int index = random.nextInt(fireCenterList.size());
g[j]=1-e[j]; randomFireCenterList.add(fireCenterList.get(index));
fireCenterList.remove(index);
} }
double[] a=new double[10];//每个属性所占的权数 int randomFireCenterListSize = randomFireCenterList.size();
double SumG=0.0; if(randomFireCenterList.size()==0) {
for(int i=0;i<g.length;i++) { // 自行修改封装后的返回值,错误:该地区没有找到消防站
SumG+=g[i]; return null;
}
for(int i=0;i<g.length;i++) {
a[i]=g[i]/SumG;
}
double[]w=new double[strictNum];
for(int j=0;j<strictNum;j++) {
w[j]=0;
for(int i=0;i<3;i++) {
w[j]+=a[i]*arrNew1[i][j];
}
// w[j]=1-w[j];
} }
Map arrayStrict=new HashMap(); double[][] arr = new double[randomFireCenterListSize][10];
List<Double> arrayW1=new ArrayList<>(); int temp = 0;
Map topTen=new LinkedHashMap(); //通过earthquakeId获得想要的地区的估计结果
List <FireWeight> resultFireWeightLists=new ArrayList<>(); Estimate estimate = estimateService.queryAnalyzeById(earthquakeId);
for(int i=0;i<strictNum;i++){ // 依次设定每个救援点的指标最多可以设置10个指标
arrayW1.add(w[i]); for (FireCenter fireCenter : randomFireCenterList) {
// System.out.println("第+"+(i+1)+"个地区的权重值为"+w[i]); Double intensity = estimateController.getPointIntensity(earthquakeId, fireCenter.getFireLon(), fireCenter.getFireLat());
// arrayStrict.put(i+1,w[i]); arr[temp][0] = intensity * 100;
arrayStrict.put(i,w[i]); arr[temp][1] = estimate.getPopulation() * intensity + 100 * Math.random();
arr[temp][2] = Math.log(estimate.getPredictDeath() * estimate.getPredictEconomy()) + 100 * Math.random();
temp++;
} }
List<Map.Entry<Integer,Double>> entrys=new ArrayList<>(arrayStrict.entrySet()); Double[] weights = estimateUtil.entropyMethod(arr,randomFireCenterListSize,3,new ArrayList<Integer>(Arrays.asList(0,1,2)));
Collections.sort(entrys, new MyComparator()); List<FireWeight> resultFireWeightLists = new ArrayList<>();
//输出排序后的键值对 for (int i=0;i<randomFireCenterListSize;i++) {
int count=0; FireWeight fireWeight = new FireWeight();
for(Map.Entry<Integer,Double> entry:entrys){ fireWeight.setFireId(randomFireCenterList.get(i).getFireId());
topTen.put(entry.getKey(),entry.getValue()); fireWeight.setFireLat(randomFireCenterList.get(i).getFireLat());
FireCenter resultFireCenter=getOneFireCenter(map.get(entry.getKey())); fireWeight.setFireLon(randomFireCenterList.get(i).getFireLon());
FireWeight fireWeight=new FireWeight(); fireWeight.setFireName(randomFireCenterList.get(i).getFireName());
fireWeight.setFireId(resultFireCenter.getFireId()); fireWeight.setFireAddress(randomFireCenterList.get(i).getFireAddress());
fireWeight.setFireLat(resultFireCenter.getFireLat()); fireWeight.setFireCenterWeight(weights[i]);
fireWeight.setFireLon(resultFireCenter.getFireLon());
fireWeight.setFireName(resultFireCenter.getFireName());
fireWeight.setFireAddress(resultFireCenter.getFireAddress());
fireWeight.setFireCenterWeight(entry.getValue());
resultFireWeightLists.add(fireWeight); resultFireWeightLists.add(fireWeight);
count++;
if(count==30){
break;
}
} }
// 返回值自行封装
// return arrayW1;
// return topTen;
return resultFireWeightLists; return resultFireWeightLists;
} }
private static final double EARTH_RADIUS = 6378.137; private static final double EARTH_RADIUS = 6378.137;
/**
* Gets distance.
*
* @param longitude1 the longitude 1
* @param latitude1 the latitude 1
* @param longitude2 the longitude 2
* @param latitude2 the latitude 2
* @return the distance
*/
public static double getDistance(double longitude1, double latitude1, double longitude2, double latitude2) { public static double getDistance(double longitude1, double latitude1, double longitude2, double latitude2) {
// 纬度 // 纬度
double lat1 = Math.toRadians(latitude1); double lat1 = Math.toRadians(latitude1);
@ -179,7 +207,7 @@ public class FireCenterController {
// 计算两点距离的公式 // 计算两点距离的公式
double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2))); double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2)));
// 弧长乘地球半径, 返回单位: 千米 // 弧长乘地球半径, 返回单位: 千米
s = s * EARTH_RADIUS; s = s * EARTH_RADIUS;
return s; return s;
} }
} }

@ -4,6 +4,9 @@ import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
/**
* @author lakefish
*/
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor

@ -5,5 +5,5 @@ import com.peteralbus.entity.FireCenter;
import java.util.List; import java.util.List;
public interface FireCenterService { public interface FireCenterService {
List<FireCenter>getAllFireCenter(); List<FireCenter> getAllFireCenter();
} }

@ -8,11 +8,23 @@ import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
/**
* The type Fire center service.
* @author wuhon
*/
@Service @Service
public class FireCenterServiceImpl implements FireCenterService { public class FireCenterServiceImpl implements FireCenterService {
/**
* The Fire center mapper.
*/
FireCenterMapper fireCenterMapper; FireCenterMapper fireCenterMapper;
/**
* Sets fire center mapper.
*
* @param fireCenterMapper the fire center mapper
*/
@Autowired @Autowired
public void setFireCenterMapper(FireCenterMapper fireCenterMapper) { public void setFireCenterMapper(FireCenterMapper fireCenterMapper) {
this.fireCenterMapper = fireCenterMapper; this.fireCenterMapper = fireCenterMapper;

@ -1,12 +1,17 @@
package com.peteralbus.util; package com.peteralbus.util;
import com.peteralbus.entity.FireWeight;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Map;
/** /**
* The type Estimate util. * The type Estimate util.
*
* @author PeterAlbus * @author PeterAlbus
*/ */
@Component @Component
@ -15,14 +20,16 @@ public class EstimateUtil
/** /**
* death predict int. * death predict int.
* *
* @param population the population * @param earthquakeId the earthquake id
* @param magnitude the magnitude * @param population the population
* @param magnitude the magnitude
* @param intensity the intensity
* @param earthquakeTime the time of earthquake * @param earthquakeTime the time of earthquake
* @param longitude the longitude * @param longitude the longitude
* @param latitude the latitude * @param latitude the latitude
* @return the double * @return the double
*/ */
public double deathPredict(Long earthquake_id,int population, double magnitude, double intensity, LocalDateTime earthquakeTime,Double longitude,Double latitude) public double deathPredict(Long earthquakeId,int population, double magnitude, double intensity, LocalDateTime earthquakeTime,Double longitude,Double latitude)
{ {
double deathPredict = 0; double deathPredict = 0;
/*M为震级 I为震中强度*/ /*M为震级 I为震中强度*/
@ -67,7 +74,82 @@ public class EstimateUtil
* @return the double * @return the double
*/ */
public double economyPredict(double highIntensity) public double economyPredict(double highIntensity)
{return Math.pow(10,0.84444*highIntensity-1.831)/10000; {
return Math.pow(10,0.84444*highIntensity-1.831)/10000;
}
/**
* 使
*
* @param data pointCountparameterCount
* @param pointCount
* @param parameterCount
* @param positiveIndicatorsIndex
* @return Double[pointCount], data
*/
public Double[] entropyMethod(double[][] data, int pointCount, int parameterCount, List<Integer> positiveIndicatorsIndex) {
Double[] max = new Double[parameterCount];
Double[] min = new Double[parameterCount];
Double[] sum = new Double[parameterCount];
// 求出每个属性的最大值、最小值
for(int i = 0; i < parameterCount; i++) {
max[i] = Double.MIN_VALUE;
min[i] = Double.MAX_VALUE;
sum[i] = 0.0;
for(int j=0;j<pointCount;j++) {
if(data[j][i] > max[i]) {
max[i] = data[j][i];
}
if(data[j][i] < min[i]) {
min[i] = data[j][i];
}
}
}
// 归一化
Double[][] normalizedData = new Double[pointCount][parameterCount];
for(int i = 0; i < parameterCount; i++) {
for(int j=0;j < pointCount;j++) {
if(positiveIndicatorsIndex.contains(i)) {
normalizedData[j][i] = (data[j][i] - min[i]) / (max[i] - min[i]);
} else {
normalizedData[j][i] = (max[i] - data[j][i]) / (max[i] - min[i]);
}
sum[i] += normalizedData[j][i];
}
}
// 每个属性指标值在该属性所有数值中的比例
Double[][] percentage = new Double[pointCount][parameterCount];
for(int i = 0; i < parameterCount; i++) {
for(int j=0;j<pointCount;j++) {
percentage[j][i] = normalizedData[j][i] / sum[i] + 0.000000000001;
}
}
// 熵值
Double[] entropy = new Double[parameterCount];
// 变异系数的总和
double sumG = 0.0;
for(int i = 0; i < parameterCount; i++) {
double sumJ = 0.0;
for(int j=0;j< pointCount;j++) {
sumJ += percentage[j][i] * Math.log(percentage[j][i]);
}
entropy[i] = (-1/Math.log(10))*sumJ;
sumG += 1 - entropy[i];
}
// 每个系数的权重
Double[] parameterWeight = new Double[parameterCount];
for(int i = 0; i < parameterCount; i++) {
parameterWeight[i] = (1 - entropy[i]) / sumG;
}
// 计算每个点的权重
Double[] weight = new Double[pointCount];
for(int i = 0; i < pointCount; i++) {
weight[i] = 0.0;
for(int j = 0; j < parameterCount; j++) {
weight[i] += percentage[i][j] * parameterWeight[j];
}
}
return weight;
} }
} }

@ -1,5 +1,6 @@
package com.peteralbus; package com.peteralbus;
import com.peteralbus.controller.FireCenterController;
import com.peteralbus.entity.EarthquakeInfo; import com.peteralbus.entity.EarthquakeInfo;
import com.peteralbus.entity.Estimate; import com.peteralbus.entity.Estimate;
import com.peteralbus.service.EarthquakeInfoService; import com.peteralbus.service.EarthquakeInfoService;
@ -16,9 +17,7 @@ import org.springframework.boot.test.context.SpringBootTest;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Date; import java.util.*;
import java.util.HashMap;
import java.util.Map;
@SpringBootTest @SpringBootTest
class EarthquickApplicationTests class EarthquickApplicationTests
@ -29,41 +28,28 @@ class EarthquickApplicationTests
EstimateUtil estimateUtil; EstimateUtil estimateUtil;
@Autowired @Autowired
EarthquakeInfoService earthquakeInfoService; EarthquakeInfoService earthquakeInfoService;
@Autowired
FireCenterController fireCenterController;
@Test @Test
void contextLoads() void contextLoads()
{ {
// long startTime = System.currentTimeMillis(); System.out.println(fireCenterController.getFireCenterWeight(16L, 12));
// Map<String, Object> mapParameter = new HashMap<String, Object>(); // double[][] data = {{6.962645,67101.0,730.3979,1.3},
// mapParameter.put("earthquakeId",16); // {5.643831,50732.0,170.8517,1.7},
// EarthquakeInfo earthquakeInfo=earthquakeInfoService.queryInfoWithLine(mapParameter).get(0); // {7.775079,39755.0,89.2054,1.0},
// double magnitude = earthquakeInfo.getMagnitude(), // {6.568763,67101.0,294.3379,1.0},
// highIntensity = earthquakeInfo.getHighIntensity(), // {6.552100,67101.0,281.1741,1.9},
// longitude = earthquakeInfo.getLongitude(), // {6.669364,43274.0,41.5144,1.2},
// latitude = earthquakeInfo.getLatitude(), // {7.774892,39755.0,89.2054,1.4},
// longRadius = earthquakeInfo.getIntensityLineList().get(2).getLongRadius(), // {6.511145,67101.0,518.4596,1.4},
// shortRadius = earthquakeInfo.getIntensityLineList().get(2).getShortRadius(); // {6.966898,67101.0,382.3772,1.7},
// System.out.println(longRadius); // {5.894564,35641.0,374.3219,1.2}};
// LocalDateTime earthquakeTime = earthquakeInfo.getEarthquakeTime(); // List<Integer> list = new ArrayList<>();
// //将角度转换为弧度。 // list.add(0);
// double radians = Math.toRadians(latitude); // list.add(2);
// double minLongitude = longitude-shortRadius/(111-Math.cos(radians)), // list.add(3);
// maxLongitude = longitude+shortRadius/(111-Math.cos(radians)), // System.out.println(Arrays.toString(estimateUtil.entropyMethod(data, 10, 4, list)));
// minLatitude = latitude-longRadius/111,
// maxLatitude = latitude+longRadius/111;
// int population=(int)estimateService.getPopulation(minLongitude,maxLongitude,minLatitude,maxLatitude);
// double death=estimateUtil.deathPredict(earthquakeInfo.getEarthquakeId(),population,magnitude,highIntensity,earthquakeTime,longitude,latitude);
// long endTime = System.currentTimeMillis();
// long usedTime = (endTime-startTime)/1000;
// System.out.println(death + " " + usedTime);
// getPopulation(100.7342,25.5736);
// getPopulation(99.9586,25.6753);
// getPopulation(100.1926,25.9121);
// getPopulation(100.1885,25.9252);
// getPopulation(99.7768,25.3342);
// getPopulation(99.9586,25.6752);
// getPopulation(100.3105,25.6775);
// getPopulation(100.1209,25.7921);
// getPopulation(100.4937,25.3366);
} }
void getPopulation(double longitude,double latitude) void getPopulation(double longitude,double latitude)

Loading…
Cancel
Save