-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCalculateAccumulatedFlow.java
More file actions
90 lines (82 loc) · 3.67 KB
/
Copy pathCalculateAccumulatedFlow.java
File metadata and controls
90 lines (82 loc) · 3.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package heyingzhe;
import java.util.*;
public class CalculateAccumulatedFlow {
private int[][] data;
private static final int[][] DIRECTIONS = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
private int[] dx = {1, 1, 0, -1, -1, -1, 0, 1}; // 定义八个方向的x偏移
private int[] dy = {0, -1, -1, -1, 0, 1, 1, 1}; // 定义八个方向的y偏移
private int[] dir = {1, 2, 4, 8, 16, 32, 64, 128}; // 定义八个方向的值
// 构造函数
public CalculateAccumulatedFlow(int[][] data) {
this.data = data;
}
public double[][] calculateFlow(int[][] flowDirection, double[][] rainfall, int[][] dem) {
int m = flowDirection.length; // 获取行数
int n = flowDirection[0].length; // 获取列数
double[][] flow = new double[m][n]; // 初始化累积流量二维数组
boolean[][] visited = new boolean[m][n]; // 初始化标记数组
Integer[][] indexes = new Integer[m*n][2]; // 初始化索引数组
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
indexes[i*n+j] = new Integer[]{i, j}; // 保存索引
flow[i][j] = rainfall[i][j]; // 初始化累积流量数组
}
}
// 对索引数组进行排序,按照dem值的降序排序
Arrays.sort(indexes, (a, b) -> dem[b[0]][b[1]] - dem[a[0]][a[1]]);
for (Integer[] index : indexes) {
int x = index[0];
int y = index[1];
//System.out.println("支线:" + "x=" + x + ", y=" + y);
if (!visited[x][y]) { // 如果该点未被访问
dfs(flowDirection, flow, visited, x, y, m, n); // 从该点开始进行深度优先搜索
}else{
continue;
}
}
return flow; // 返回累积流量二维数组
}
private void dfs(int[][] flowDirection, double[][] flow, boolean[][] visited, int x, int y, int m, int n) {
visited[x][y] = true; // 标记该点已被访问
// 判断当前点是否是最下游
if (flowDirection[x][y]==0) {
return;
}else{
int num = (int)(Math.log(flowDirection[x][y]) / Math.log(2));
int nx = x + dx[num]; // 计算新的x坐标
int ny = y + dy[num]; // 计算新的y坐标
// 判断新的坐标是否在网格内
if (nx >= 0 && nx < m && ny >= 0 && ny < n) {
flow[nx][ny] += flow[x][y];
}else{
return;
}
if (visited[nx][ny]) {
double flow_add = flow[x][y];
//System.out.println("进入重复支流...");
accumulateFlow(flowDirection, flow, nx, ny, flow_add);
}else{
//System.out.println("进入递归...");
dfs(flowDirection, flow, visited, nx, ny, m, n);
}
}
}
public void accumulateFlow(int[][] flowDirection, double[][] flow, int x, int y, double value) {
int m = flowDirection.length; // 获取行数
int n = flowDirection[0].length; // 获取列数
// 判断当前点是否是最下游
if (flowDirection[x][y]==0) {
return;
}else{
int num = (int)(Math.log(flowDirection[x][y]) / Math.log(2));
int nx = x + dx[num]; // 计算新的x坐标
int ny = y + dy[num]; // 计算新的y坐标
// 判断新的坐标是否在网格内
if (nx >= 0 && nx < m && ny >= 0 && ny < n) {
flow[nx][ny] += value;
}else{
return;
}
}
}
}