protected float calcDNode(LASTNode node) {
        int prevNumeratorSum = 0;
        int prevDenominatorSum = 0;
        int nextNumeratorSum = 0;
        int nextDenominatorSum = 0;

        int communicationTime = 0;

        for (List<LASTNode> group : groups) {
            for (LASTNode prevNode : group) {
                if (taskGraph.containsEdge(prevNode.getTaskGraphNode(), node.getTaskGraphNode())) {
                    try {
                        communicationTime = taskGraph.findEdge(prevNode.getTaskGraphNode(),
                                node.getTaskGraphNode()).getCommunicationTime();
                        prevNumeratorSum += communicationTime * calcDEdge(prevNode, node);
                    } catch (ContainsNoEdgeException e) {
                        e.printStackTrace();
                    }
                }
            }

            for (LASTNode nextNode : group) {
                if (taskGraph.containsEdge(node.getTaskGraphNode(), nextNode.getTaskGraphNode())) {
                    try {
                        communicationTime = taskGraph.findEdge(node.getTaskGraphNode(),
                                nextNode.getTaskGraphNode()).getCommunicationTime();

                        nextNumeratorSum += communicationTime * calcDEdge(node, nextNode);
                    } catch (ContainsNoEdgeException e) {
                        e.printStackTrace();
                    }
                }
            }
        } // for (group : groups)

        // Calculate denomiator sums
        for (TaskGraphEdge edge : node.getTaskGraphNode().getPrevEdges())
            prevDenominatorSum += edge.getCommunicationTime();
        for (TaskGraphEdge edge : node.getTaskGraphNode().getNextEdges())
            nextDenominatorSum += edge.getCommunicationTime();

        double result = ((double) (prevNumeratorSum + nextNumeratorSum))
                / ((prevDenominatorSum + nextDenominatorSum));

        return (float) result - node.getTaskGraphNode().getDeadLine();
    }