⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 minimizerclassic.java

📁 用能量函数布局网络图
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		} else {
			repuFactor = 1.0;
		}
    }


	/**
	 * Returns the Euclidean distance between the positions pos1 and pos2.
	 * @return Euclidean distance between the positions pos1 and pos2
	 */
    private final double getDist(final double[] pos1, final double[] pos2) {
        double dist = 0.0;
        for (int d = 0; d < nrDims; d++) {
            double diff = pos1[d] - pos2[d];
            dist += diff * diff;
        }
        return Math.sqrt(dist);
    }


	/** 
	 * Returns the repulsion energy of a node.
	 * @param node  repulsing node
	 * @return repulsion energy of the specified node
	 */
	private double getRepulsionEnergy(final Node node) {
        if (node.weight == 0.0) return 0.0; 
        final double[] position = positions.get(node);
		double energy = 0.0;
		for (Node node2 : nodes) {
			if (node2 == node || node2.weight == 0.0) continue;
			final double dist = getDist(position, positions.get(node2));
			if (repuExponent == 0.0) {
				energy -= repuFactor * node.weight * node2.weight 
				        * Math.log(dist);
			} else {
				energy -= repuFactor * node.weight * node2.weight 
				        * Math.pow(dist, repuExponent) / repuExponent;
			}
		}
		return energy;
	}

	/** 
	 * Returns the attraction energy of a node.
	 * @param node  attracting node
	 * @return attraction energy of the specified node
	 */
	private double getAttractionEnergy(final Node node) {
		double energy = 0.0;
        final double[] position = positions.get(node);
		for (Edge edge : attrEdges.get(node)) {
			final double dist = getDist(position, positions.get(edge.endNode));
			if (attrExponent == 0.0) {
				energy += edge.weight * Math.log(dist);
			} else {
				energy += edge.weight * Math.pow(dist, attrExponent) / attrExponent;
			}
		}
		return energy;
	}
	
	/** 
	 * Returns the gravitation energy of a node.
	 * @param node  gravitating node
	 * @return gravitation energy of the specified node
	 */
	private double getGravitationEnergy(final Node node) {
        final double dist = getDist(positions.get(node), baryCenter);
		if (attrExponent == 0.0) {
			return gravFactor * node.weight * Math.log(dist);
		} else {
			return gravFactor * node.weight * Math.pow(dist, attrExponent) / attrExponent;
		}
	}

	/**
	 * Returns the total energy of a node.
	 * @param node  node
	 * @return total energy of the specified node
 	 */
    private double getEnergy(final Node node) {
		return getRepulsionEnergy(node)
			+ getAttractionEnergy(node) + getGravitationEnergy(node);
    }


	/**
	 * Computes the direction of the repulsion force on a node.
	 * @param  node  repulsing node
	 * @param  dir   direction of the repulsion force acting on the node
	 * 				 is added to this variable (output parameter)
	 * @return approximate second derivation of the repulsion energy
	 */
	private double addRepulsionDir(final Node node, final double[] dir) {
        if (node.weight == 0.0) return 0.0;
        final double[] position = positions.get(node);
		double dir2 = 0.0;
		for (Node node2 : nodes) {
			if (node2 == node || node2.weight == 0.0) continue;
            final double[] position2 = positions.get(node2);
			final double dist = getDist(position, position2);
			if (dist == 0.0) continue;
			double tmp = repuFactor * node.weight * node2.weight 
			          * Math.pow(dist, repuExponent-2);
			dir2 += tmp * Math.abs(repuExponent-1);
			for (int d = 0; d < nrDims; d++) {
				dir[d] -= (position2[d] - position[d]) * tmp;
			}
		}
		return dir2;
	}

	/**
	 * Computes the direction of the attraction force on the a node.
	 * @param  node  attracting node
	 * @param  dir   direction of the attraction force acting on the node
	 * 				 is added to this variable (output parameter)
	 * @return approximate second derivation of the attraction energy
	 */
	private double addAttractionDir(final Node node, final double[] dir) {
		double dir2 = 0.0;
        final double[] position = positions.get(node);
		for (Edge edge : attrEdges.get(node)) {
            final double[] position2 = positions.get(edge.endNode);
			final double dist = getDist(position, position2);
			if (dist == 0.0) continue;
			double tmp = edge.weight * Math.pow(dist, attrExponent-2);
			dir2 += tmp * Math.abs(attrExponent-1);
			for (int d = 0; d < nrDims; d++) {
				dir[d] += (position2[d] - position[d]) * tmp;
			}
		}
		return dir2;
	}

	/**
	 * Computes the direction of the gravitation force on the a node.
	 * @param  node  gravitating node
	 * @param  dir   direction of the gravitation force acting on the node
	 * 				 is added to this variable (output parameter)
	 * @return approximate second derivation of the gravitation energy
	 */
	private double addGravitationDir(final Node node, final double[] dir) {
        final double[] position = positions.get(node);
        final double dist = getDist(position, baryCenter);
		double tmp = gravFactor * repuFactor * node.weight * Math.pow(dist, attrExponent-2);
        for (int d = 0; d < nrDims; d++) {
            dir[d] += (baryCenter[d] - position[d]) * tmp;
        }
		return tmp * Math.abs(attrExponent-1);
	}
		
	/**
	 * Computes the direction of the total force acting on a node.
	 * @param  node  node
	 * @param  dir   direction of the total force acting on the node
	 *               (output parameter)
	 */
    private void getDirection(final Node node, final double[] dir) {
        for (int d=0; d<nrDims; d++) dir[d] = 0.0;

		double dir2 = addRepulsionDir(node, dir);
		dir2 += addAttractionDir(node, dir);
		dir2 += addGravitationDir(node, dir);

		// compute average Euclidean distance to other nodes
		double avgDist = 0.0;
		for (Node node2 : nodes) { 
            avgDist += getDist(positions.get(node), positions.get(node2));
        }
		avgDist /= nodes.size()-1;

		if (dir2 != 0.0) {
			// normalize force vector with second derivation of energy
            for (int d=0; d<nrDims; d++) dir[d] /= dir2;
         
			// ensure that the length of dir is not greater
			// than average Euclidean distance to other nodes
            double length = getDist(dir, new double[nrDims]);
			if (avgDist > 0.0 && length > avgDist) {
				length /= avgDist;
                for (int d=0; d<nrDims; d++) dir[d] /= length;
			}
		} else {
            for (int d=0; d<nrDims; d++) dir[d] = 0.0;
		}
    }    


    /** 
     * Computes the position of the barycenter of all nodes
     * and stores it in the attribute <code>baryCenter</code>.
     */
    private void computeBaryCenter() {
        for (int d=0; d<nrDims; d++) baryCenter[d] = 0.0;
		double weightSum = 0.0;
        for (Node node : nodes) {
			weightSum += node.weight;
			double[] position = positions.get(node);
            for (int d=0; d<nrDims; d++) baryCenter[d] += node.weight * position[d];
        }
		if (weightSum > 0.0) {
            for (int d=0; d<nrDims; d++) baryCenter[d] /= weightSum;
		}
    }

	/**
	 * Computes and outputs some statistics. 
	 */
	private void printStatistics() {
        System.out.println("Number of nodes: " + nodes.size());
		double attrSum = 0.0;
		for (Node node : nodes) {
			for (Edge edge : attrEdges.get(node)) {
				attrSum += edge.weight;
			}
		}
		System.out.println("Overall attraction: " + attrSum);
		double meanAttrEnergy = 0.0;
		for (Node node : nodes) meanAttrEnergy += getAttractionEnergy(node);
		meanAttrEnergy = (attrExponent == 0.0)
			? Math.exp(meanAttrEnergy / attrSum)
			: Math.pow(meanAttrEnergy * attrExponent / attrSum, 1.0 / attrExponent); 
		System.out.println("Weighted mean of attraction energy: " + meanAttrEnergy);
		
		double repuSum = 0.0, repuSquareSum = 0.0;
		for (Node node : nodes) {
			repuSum += node.weight;
			repuSquareSum += node.weight * node.weight;
		}
		repuSum = repuSum*repuSum - repuSquareSum;
		System.out.println("Overall repulsion: " + repuSum);
		double meanRepuEnergy = 0.0;
		for (Node node : nodes) meanRepuEnergy += getRepulsionEnergy(node);
		meanRepuEnergy /= repuFactor; 
		meanRepuEnergy = (repuExponent == 0.0) 
			? Math.exp(-meanRepuEnergy / repuSum)
			: Math.pow(-meanRepuEnergy * repuExponent / repuSum, 1.0 / repuExponent); 
		System.out.println("Weighted mean of repulsion energy: " + meanRepuEnergy);
		
		System.out.println("Mean attraction / mean repulsion: " + meanAttrEnergy / meanRepuEnergy);
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -