Помощь в определении времени выполнения алгоритма n

#java #algorithm #performance #pairwise

#java #алгоритм #Производительность #попарно

Вопрос:

Следующая программа создана для выполнения парных выборов по упорядоченному по рангу набору бюллетеней.

конечным результатом является то, что парный выбор завершает все тестовые примеры менее чем за 0,01 секунды прошедшего времени выполнения.

В настоящее время производительность конечного результата программы составляет около 0,02 секунды. Нужна помощь, чтобы помочь сократить время до 0,01 секунды и меньше.

Ниже приведен программный код:

 import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;

/**
 * 
 * 
 *         Utility class to compute the pairwise winner of elections
 */
public class PairwiseVote {
    /**
     * Get the placement order of a candidate in a rank order list of candidates
     *
     * @param votersVotes
     *            an array of rank order candidates. First has the highest rank.
     */
    public static int getPlacement(int candidate, int[] votersVotes) {
        for (int placement = 0; placement < votersVotes.length; placement  ) {
            if (candidate == votersVotes[placement]) {
                return placement;
            }
        }
        return votersVotes.length   1;
    }

    /**
     * Get the candidate winner from a set of rank ordered ballots
     *
     * @param votes
     *            - a two dimensional array, first dimension is the voter, second
     *            dimension is the rank ordered ballot of candidates for the given
     *            voter
     */
    public static int getPairwiseWinner(int[][] votes) {
        int noVoters = votes.length;

        if (noVoters == 0) {
            return -1;
        }

        int noCandidates = votes[0].length;

        if (noCandidates == 0) {
            return -1;
        }

        // Compare every pair of candidates
        for (int candidate1 = 0; candidate1 < noCandidates; candidate1  ) {
            int noTimesCandidate1Wins = 0;
            for (int candidate2 = 0; candidate2 < noCandidates; candidate2  ) {
                // Consider a candidate compared with themselves to be a winner
                if (candidate1 == candidate2) {
                    noTimesCandidate1Wins  ;
                    continue;
                }

                // Determine count the ballots for each candidate
                int candidate1votes = 0;
                int candidate2votes = 0;
                for (int voter = 0; voter < noVoters; voter  ) {
                    int placement1 = getPlacement(candidate1, votes[voter]);
                    int placement2 = getPlacement(candidate2, votes[voter]);
                    if (placement1 < placement2) {
                        candidate1votes  ;
                        ;
                    } else {
                        candidate2votes  ;
                        ;
                    }
                }

                // determine if candidate1 is the winner if so increment the number of wins
                if (candidate1votes > candidate2votes) {
                    noTimesCandidate1Wins  ;
                }
            }

            // Determine if candidate 1 wins all
            if (noTimesCandidate1Wins == noCandidates) {
                return candidate1;
            }
        }

        // No winner
        return -1;
    }

    static int electionNo = 0;

    /**
     * Main - reads several test elections using the text file votes.txt. Each
     * election begins with two number, the number of voters and the number of
     * candidates, all followed by the ballots of each voter.
     */
    public static void main(String[] args) throws FileNotFoundException {
        int noVoters;
        int noCandidates;

        Scanner in = new Scanner(new FileInputStream("votes.txt"));

        // read ballots for each election
        for (;;) {
            noVoters = in.nextInt();
            noCandidates = in.nextInt();

            if (noVoters == 0 amp;amp; noCandidates == 0) {
                break;
            }

            final int[][] votes = new int[noVoters][noCandidates];

            // Read the ballots
            for (int i = 0; i < noVoters; i  ) {
                for (int j = 0; j < noCandidates; j  ) {
                    votes[i][j] = in.nextInt();
                }
            }

            new TimeExec(new Runnable() {
                public void run() {
                    int winner = getPairwiseWinner(votes);
                    if (winner >= 0) {
                        System.out.printf("Winner of election %d is candidate %dn", electionNo, winner);
                    } else {
                        System.out.printf("No winner for election %dn", electionNo);
                    }
                }
            }, "Election "     electionNo, System.out).start();
        }
    }
}
  

Спасибо за помощь!!

Комментарии:

1. Вы можете сначала определить, какой код стоит больше времени, а затем выполнить некоторую работу, чтобы сократить время.

2. @TongChen я не понимаю, что ты говоришь.

Ответ №1:

Текущий код вызывает getPlacement noCandidates*noCandidates*noVoters*2 раз, но этого было бы достаточно, чтобы вызвать его noCandidates*noVoters раз.

Вы можете управлять этим, предварительно вычисляя значения и сохраняя их следующим образом (не уверен, компилируется ли это, поскольку я не программирую на Java, но я думаю, вы можете понять идею):

 public static int getPairwiseWinner(int[][] votes) {
    int noVoters = votes.length;

    if (noVoters == 0) {
        return -1;
    }

    int noCandidates = votes[0].length;

    if (noCandidates == 0) {

        return -1;
    }

    int[][] placements = new int[noVoters][noCandidates]; // to store precalculated placements

    // go through each of the voters and precalculate the placements of each candidate
    for (int voter = 0; voter<noVoters; voter  ) {

        for (int candidate = 0; candidate < noCandidates; candidate  ) {

            placements[voter][candidate] = getPlacement(candidate, votes[voter]);
        }
    }

    // Compare every pair of candidates
    for (int candidate1 = 0; candidate1 < noCandidates; candidate1  ) {

        int noTimesCandidate1Wins = 0;
        for (int candidate2 = 0; candidate2 < noCandidates; candidate2  ) {

            // Consider a candidate compared with themselves to be a winner
            if (candidate1 == candidate2) {

                noTimesCandidate1Wins  ;
                continue;
            }

            // Determine count the ballots for each candidate
            int candidate1votes = 0;
            int candidate2votes = 0;
            for (int voter = 0; voter < noVoters; voter  ) {

                // use precalculated placements
                if (placements[voter][candidate1] < placements[voter][candidate2]) {

                    candidate1votes  ;
                    ;
                } else {


                    candidate2votes  ;
                    ;
                }
            }

            // determine if candidate1 is the winner if so increment the number of wins
            if (candidate1votes > candidate2votes) {

                noTimesCandidate1Wins  ;
            }
        }

        // Determine if candidate 1 wins all
        if (noTimesCandidate1Wins == noCandidates) {

            return candidate1;
        }
    }

    // No winner
    return -1;
}