Description of my code:I am trying to maximize the number of nodes that could be reachable in a graph. Please do not consider my main algorithm, I want it to be like that. The only parts that I need to be boosted are the way of using data structures and reachability. I don't want to change my main algorithm.I am looking for boosting the performance of my program. Here is the source code of that. Is there any part that could perform faster? Any little speed up would be great because of this algorithm should be run on a graph with more than 1m nodes.public LinkedHashSet<Customer> retentionSeedFinder(int budget,        HashSet<Customer> churnerNodes, int delay,        DirectedSparseGraph<Customer, Transaction> network) {    LinkedHashSet<Customer> seedSet = new LinkedHashSet<Customer>();    numberofNodes = network.getVertexCount();    churnNet = new HashSet<Customer>();    HashSet<Customer> tmpchurnNet = new HashSet<Customer>();    HashSet<Customer> availableNodes;    // at timestep 0    churnNet.addAll(churnerNodes);    churnNet.addAll(getNeighbors(churnerNodes, network));    availableNodes = getReachableNodes(churnNet, network);    // at timestep 1    int timestep = 1;    tmpchurnNet = churnNet;    while (timestep <= delay) {        Collection<Customer> neighbors;        System.out.println(***********************At timestep: + timestep                + *************************);        for (Customer churner : churnNet) {            neighbors = network.getNeighbors(churner);            for (Customer specificNeighbor : neighbors) {                tmpchurnNet.add(specificNeighbor);            }        }        churnNet = tmpchurnNet;        timestep++;    }    PriorityQueue<Customer> marginalGainHeap = new PriorityQueue<Customer>(            1, new Comparator<Customer>() {                public int compare(Customer c1, Customer c2) {                    if (c1.getMarginalGain() < c2.getMarginalGain())                        return 1;                    if (c1.getMarginalGain() > c2.getMarginalGain())                        return -1;                    if (c1.getMarginalGain() == c2.getMarginalGain()) {                        if (c1.getRevenue() < c2.getRevenue())                            return 1;                        if (c1.getRevenue() > c2.getRevenue())                            return -1;                    }                    return 0;                }            });    // set of all remains available nodes    availableNodes.removeAll(churnNet);    for (Customer avail : availableNodes) {        avail.setMarginalGain(0);        marginalGainHeap.add(avail);    }    int seedNum = 1;    while (seedSet.size() < budget) {        Collection<Customer> tmpAvailNodes = new HashSet<Customer>();        tmpAvailNodes.addAll(availableNodes);        for (Customer remainingNode : tmpAvailNodes) {            remainingNode.setMarginalGain(calculateMarginalGain(                    remainingNode, seedSet, network, availableNodes,                    churnNet));            // heapify bar asase mg            marginalGainHeap.remove(remainingNode);            marginalGainHeap.add(remainingNode);        }        availableNodes.remove(marginalGainHeap.peek());        System.out.println(marginalGainHeap.peek().getName());        seedSet.add(marginalGainHeap.poll());        System.out                .println(Target seed subscriber for short-term campaign has been found:                        + seedNum++);    }    return seedSet;}private double calculateMarginalGain(Customer remainingNode,        HashSet<Customer> seedSet,        DirectedSparseGraph<Customer, Transaction> net,        HashSet<Customer> availableNodes, HashSet<Customer> churnNetwork) {    // Marginal gain for short-term campaign    HashSet<Customer> tmp = new HashSet<Customer>(); // seedset U                                                        // {remainingNode}    tmp.addAll(seedSet);    tmp.add(remainingNode);    HashSet<Customer> tmpAvailableNodes = new HashSet<Customer>();    tmpAvailableNodes.addAll(availableNodes);    // sigma function for calculating the expected number of influenced    // customers- seedSettmp=seedset U {u}    tmpAvailableNodes.removeAll(churnNetwork);    HashSet<Customer> influencedNet = getNeighbors(tmp, net);    tmpAvailableNodes.retainAll(influencedNet);    return tmpAvailableNodes.size();}private HashSet<Customer> getNeighbors(HashSet<Customer> churnNetwork,        DirectedSparseGraph<Customer, Transaction> net) {    HashSet<Customer> churnNeighbors = new HashSet<Customer>();    churnNeighbors.addAll(churnNetwork);    Collection<Customer> neighbors = new HashSet<Customer>();    for (Customer node : churnNetwork) {        neighbors = net.getNeighbors(node);        for (Customer neighbor : neighbors) {            churnNeighbors.add(neighbor);        }    }    return churnNeighbors;}public HashSet<Customer> getReachableNodes(Collection<Customer> startNodes,        DirectedSparseGraph<Customer, Transaction> graph) {    Queue<Customer> queue = new LinkedList<Customer>();    HashSet<Customer> visited = new HashSet<Customer>();    queue.addAll(startNodes);    visited.addAll(startNodes);    while (!queue.isEmpty()) {        Customer v = queue.poll();        Collection<Customer> neighbors = graph.getNeighbors(v);        for (Customer n : neighbors) {            if (!visited.contains(n)) {                queue.offer(n);                visited.add(n);            }        }    }    return visited;}
Maximize the number of nodes that could be reachable in a graph
java;performance;graph