रणनीतिक वोटिंग, खेल


37

एकल-विजेता चुनावों के लिए सबसे आम मतदान प्रणालियों में से एक बहुतायत मतदान पद्धति है। सीधे शब्दों में कहें तो सबसे ज्यादा वोटों वाला उम्मीदवार जीतता है। बहुलता मतदान, हालांकि, गणितीय रूप से निराधार है और उन स्थितियों को बनाने के लिए उत्तरदायी है जिसमें मतदाताओं को "दो बुराइयों के कम" के लिए वोट करने के लिए प्रेरित किया जाता है, जैसा कि उम्मीदवार वास्तव में पसंद करते हैं।

इस गेम में, आप प्रोग्राम लिखेंगे जो बहुलता मतदान प्रणाली का लाभ उठाता है। यह एक चुनाव में तीन उम्मीदवारों में से एक के लिए वोट डालेगा। प्रत्येक उम्मीदवार अपने लिए एक निश्चित भुगतान के साथ जुड़ा हुआ है, और आपका लक्ष्य आपके अपेक्षित भुगतान को अधिकतम करना है।

भुगतान "समान रूप से" बेतरतीब ढंग से, वितरित कर रहे हैं प्रत्येक चुनाव के साथ परिवर्तन, और 100 के उम्मीदवार के लिए जोड़ एक 40 अदायगी हो सकता था, उम्मीदवार बी अदायगी 27 हो सकता था, और उम्मीदवार सी 33. अदायगी प्रत्येक खिलाड़ी को भुगतान का एक अलग सेट है हो सकता था।

जब वोट देने की आपकी बारी है, तो आपके पास अधूरी जानकारी होगी। नीचे सूचीबद्ध जानकारी है जो आपके पास उपलब्ध होगी। चूंकि आपको नहीं पता कि अन्य खिलाड़ी के व्यक्तिगत भुगतान क्या हैं, इसलिए यह भविष्यवाणी करना आपकी चुनौती होगी कि वे वर्तमान मतदान परिणामों को कैसे वोट देंगे।

  • चुनाव के अब तक के आंशिक परिणाम
  • प्रवेशकों की संख्या (खुद को छोड़कर), जिन्होंने अभी तक मतदान नहीं किया है
  • प्रत्येक उम्मीदवारों के लिए आपका व्यक्तिगत भुगतान
  • प्रत्येक उम्मीदवारों के लिए कुल समूह भुगतान

प्रत्येक खिलाड़ी को वोट देने का मौका दिए जाने के बाद, सबसे अधिक वोटों के साथ उम्मीदवार बहुलता वोटिंग के अनुसार जीतता है। प्रत्येक खिलाड़ी को उसके बाद उस उम्मीदवार से उसके भुगतान से मेल खाने वाले अंकों की संख्या प्राप्त होती है। यदि वोटों में एक टाई है, तो निर्दिष्ट अंकों की संख्या बंधे उम्मीदवारों का औसत होगी।

टूर्नामेंट संरचना

जब पहली बार त्वरित किया जाता है, तो प्रवेशकर्ता को टूर्नामेंट में आयोजित चुनावों की संख्या बताई जाएगी। मैं बहुत बड़ी संख्या में चुनाव चलाने का प्रयास करूंगा। फिर, प्रत्येक चुनाव एक-एक करके किया जाएगा।

प्रवेशकों के फेरबदल के बाद, प्रत्येक को मतदान करने की बारी दी जाती है। उन्हें ऊपर दी गई सीमित जानकारी दी जाती है और एक संख्या को उनके वोट को दर्शाता है। प्रत्येक चुनाव समाप्त होने के बाद, प्रत्येक बॉट को अंतिम चुनाव परिणाम दिया जाता है और उस चुनाव से उनका स्कोर बढ़ता है।

कुछ बड़ी संख्या में चुनाव होने के बाद विजयी प्रवेश कुल उच्चतम स्कोर वाला होगा। नियंत्रक भी एक यादृच्छिक रूप से मतदान बॉट के लिए अनुमानित स्कोर वितरण के लिए अपने स्कोर की तुलना करके प्रत्येक प्रतियोगी के लिए "सामान्यीकृत" स्कोर की गणना करता है।

प्रस्तुत विवरण

प्रस्तुतियाँ जावा 8 कक्षाओं का रूप लेंगी। प्रत्येक प्रवेशकर्ता को निम्नलिखित इंटरफ़ेस लागू करना होगा:

public interface Player
{
    public String getName();
    public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs);
    public void receiveResults(int[] voteCounts, double result);
}
  • आपके निर्माता intको एक पैरामीटर के रूप में एकल लेना चाहिए , जो कि होने वाले चुनावों की संख्या का प्रतिनिधित्व करेगा।
  • getName()विधि नाम लीडरबोर्ड पर प्रयोग की जाने वाली देता है। यह आपको अच्छी तरह से स्वरूपित नाम रखने की अनुमति देता है, बस पागल मत बनो।
  • getVote(...)विधि रिटर्न 0, 1या 2सूचित करने के लिए जो उम्मीदवार वोट प्राप्त होगा।
  • यह receiveResults(...)विधि मुख्य रूप से ऐतिहासिक डेटा का उपयोग करने वाली अधिक जटिल रणनीतियों के अस्तित्व को सक्षम करने के लिए है।
  • आपको अपने द्वारा दी गई जानकारी को रिकॉर्ड करने और संसाधित करने की इच्छा रखने वाले किसी भी अन्य तरीके / उदाहरण चर बनाने की अनुमति है।

टूर्नामेंट साइकिल, विस्तारित

  1. प्रवेशकों के साथ प्रत्येक तात्कालिक हैं new entrantName(int numElections)
  2. प्रत्येक चुनाव के लिए:
    1. नियंत्रक इस चुनाव के लिए प्रत्येक खिलाड़ी के लिए भुगतान को यादृच्छिक रूप से निर्धारित करता है। इसके लिए कोड नीचे दिया गया है। फिर, यह खिलाड़ियों को हिला देता है और उन्हें वोट देना शुरू कर देता है।
    2. प्रवेशी की विधि public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs)शुरू हो जाती है, और प्रवेशी अपने वोट देता है की 0, 1या 2अपनी पसंद के उम्मीदवार के लिए।
    3. प्रवेशकर्ता जिनकी getVote(...)विधि एक वैध वोट नहीं लौटाती है उन्हें एक यादृच्छिक वोट सौंपा जाएगा।
    4. सभी ने मतदान करने के बाद, नियंत्रक बहुलता विधि द्वारा चुनाव परिणामों को निर्धारित करता है।
    5. प्रवेशकों को अंतिम वोट काउंट्स और उनके भुगतान को उनके तरीके से कॉल करके सूचित किया जाता है public void receiveResults(int[] voteCounts, double result)
  3. सभी चुनाव होने के बाद, विजेता उच्चतम स्कोर वाला होता है।

भुगतान का यादृच्छिक वितरण

सटीक वितरण गेमप्ले पर एक महत्वपूर्ण प्रभाव पड़ेगा। मैंने एक बड़े मानक विचलन (लगभग 23.9235) के साथ एक वितरण को चुना है और जो बहुत अधिक और बहुत कम अदायगी दोनों बनाने में सक्षम है। मैंने जाँच की है कि तीनों भुगतानों में से प्रत्येक का समान वितरण है।

public int[] createPlayerPayoffs()
{
    int cut1;
    int cut2;
    do{
        cut1 = rnd.nextInt(101);
        cut2 = rnd.nextInt(101);  
    } while (cut1 + cut2 > 100);
    int rem = 100 - cut1 - cut2;
    int[] set = new int[]{cut1,cut2,rem};
    totalPayoffs[0] += set[0];
    totalPayoffs[1] += set[1];
    totalPayoffs[2] += set[2];
    return set;
}

अधिक नियम

यहाँ कुछ और सामान्यीकृत नियम हैं।

  • आपके कार्यक्रम को नियंत्रक या अन्य प्रवेशकों या उनकी यादों के किसी भी हिस्से को चलाना / संशोधित / त्वरित नहीं करना चाहिए।
  • चूंकि आपका कार्यक्रम पूरे टूर्नामेंट के लिए "लाइव" है, इसलिए कोई भी फाइल न बनाएं।
  • किसी भी अन्य प्रवेशी कार्यक्रमों के साथ बातचीत, सहायता या लक्ष्यीकरण न करें।
  • आप कई प्रवेशकों को जमा कर सकते हैं , जब तक वे यथोचित रूप से भिन्न होते हैं, और जब तक आप उपरोक्त नियमों का पालन करते हैं।
  • मैंने एक सटीक समय सीमा निर्दिष्ट नहीं की है, लेकिन मैं उन रनटाइम की बहुत सराहना करता हूं जो प्रति सेकंड एक कॉल से काफी कम हैं । मैं संभव के रूप में कई चुनाव चलाने में सक्षम होना चाहता हूं।

नियंत्रक

नियंत्रक यहाँ पाया जा सकता है मुख्य कार्यक्रम है Tournament.java। दो सरल बॉट भी हैं, जो प्रतिस्पर्धा, शीर्षक RandomBotऔर PersonalFavoriteBot। मैं इन दोनों बॉट को एक उत्तर में पोस्ट करूंगा।

लीडरबोर्ड

ऐसा लगता है कि ExpectantBot मौजूदा नेता है, उसके बाद मोंटे कार्लो और उसके बाद StaBot हैं।

Leaderboard - 20000000 elections:
   767007688.17 (  937.86) - ExpectantBot                            
   766602158.17 (  934.07) - Monte Carlo 47                          
   766230646.17 (  930.60) - StatBot                                
   766054547.17 (  928.95) - ExpectorBot                             
   764671254.17 (  916.02) - CircumspectBot                          
   763618945.67 (  906.19) - LockBot                                 
   763410502.67 (  904.24) - PersonalFavoriteBot343                  
   762929675.17 (  899.75) - BasicBot                                
   761986681.67 (  890.93) - StrategicBot50                          
   760322001.17 (  875.37) - Priam                                   
   760057860.67 (  872.90) - BestViableCandidate (2842200 from ratio, with 1422897 tie-breakers of 20000000 total runs)
   759631608.17 (  868.92) - Kelly's Favorite                        
   759336650.67 (  866.16) - Optimist                                
   758564904.67 (  858.95) - SometimesSecondBestBot                  
   754421221.17 (  820.22) - ABotDoNotForget                         
   753610971.17 (  812.65) - NoThirdPartyBot                         
   753019290.17 (  807.12) - NoClueBot                               
   736394317.17 (  651.73) - HateBot670                              
   711344874.67 (  417.60) - Follower                                
   705393669.17 (  361.97) - HipBot                                  
   691422086.17 (  231.38) - CommunismBot0                           
   691382708.17 (  231.01) - SmashAttemptByEquality (on 20000000 elections)
   691301072.67 (  230.25) - RandomBot870                            
   636705213.67 ( -280.04) - ExtremistBot                            
The tournament took 34573.365419071 seconds, or 576.2227569845166 minutes.

यहां कुछ पुराने टूर्नामेंट हैं, लेकिन इनमें से कोई भी बॉट कार्यक्षमता में नहीं बदला है।

Leaderboard - 10000000 elections:
   383350646.83 (  661.14) - ExpectantBot                            
   383263734.33 (  659.99) - LearnBot                                
   383261776.83 (  659.97) - Monte Carlo 48                          
   382984800.83 (  656.31) - ExpectorBot                             
   382530758.33 (  650.31) - CircumspectBot                          
   381950600.33 (  642.64) - PersonalFavoriteBot663                  
   381742600.33 (  639.89) - LockBot                                 
   381336552.33 (  634.52) - BasicBot                                
   381078991.83 (  631.12) - StrategicBot232                         
   380048521.83 (  617.50) - Priam                                   
   380022892.33 (  617.16) - BestViableCandidate (1418072 from ratio, with 708882 tie-breakers of 10000000 total runs)
   379788384.83 (  614.06) - Kelly's Favorite                        
   379656387.33 (  612.31) - Optimist                                
   379090198.33 (  604.83) - SometimesSecondBestBot                  
   377210328.33 (  579.98) - ABotDoNotForget                         
   376821747.83 (  574.84) - NoThirdPartyBot                         
   376496872.33 (  570.55) - NoClueBot                               
   368154977.33 (  460.28) - HateBot155                              
   355550516.33 (  293.67) - Follower                                
   352727498.83 (  256.36) - HipBot                                  
   345702626.33 (  163.50) - RandomBot561                            
   345639854.33 (  162.67) - SmashAttemptByEquality (on 10000000 elections)
   345567936.33 (  161.72) - CommunismBot404                         
   318364543.33 ( -197.86) - ExtremistBot                            
The tournament took 15170.484259763 seconds, or 252.84140432938332 minutes.

मैंने ExpectantBot की अगुवाई की पुष्टि करते हुए एक दूसरा 10 मीटर टूर्नामेंट भी चलाया।

Leaderboard - 10000000 elections:
   383388921.83 (  661.65) - ExpectantBot                            
   383175701.83 (  658.83) - Monte Carlo 46                          
   383164037.33 (  658.68) - LearnBot                                
   383162018.33 (  658.65) - ExpectorBot                             
   382292706.83 (  647.16) - CircumspectBot                          
   381960530.83 (  642.77) - LockBot                                 
   381786899.33 (  640.47) - PersonalFavoriteBot644                  
   381278314.83 (  633.75) - BasicBot                                
   381030871.83 (  630.48) - StrategicBot372                         
   380220471.33 (  619.77) - BestViableCandidate (1419177 from ratio, with 711341 tie-breakers of 10000000 total runs)
   380089578.33 (  618.04) - Priam                                   
   379714345.33 (  613.08) - Kelly's Favorite                        
   379548799.83 (  610.89) - Optimist                                
   379289709.83 (  607.46) - SometimesSecondBestBot                  
   377082526.83 (  578.29) - ABotDoNotForget                         
   376886555.33 (  575.70) - NoThirdPartyBot                         
   376473476.33 (  570.24) - NoClueBot                               
   368124262.83 (  459.88) - HateBot469                              
   355642629.83 (  294.89) - Follower                                
   352691241.83 (  255.88) - HipBot                                  
   345806934.83 (  164.88) - CommunismBot152                         
   345717541.33 (  163.70) - SmashAttemptByEquality (on 10000000 elections)
   345687786.83 (  163.30) - RandomBot484                            
   318549040.83 ( -195.42) - ExtremistBot                            
The tournament took 17115.327209018 seconds, or 285.25545348363335 minutes.

ऊ वाह, मेरा क्या हुआ बेचारा!
इस्माइल मिगुएल

कोड में मैंने जो देखा है, उसके अनुसार, दूसरा पैरामीटर शेष वोटों की संख्या है। और पहले एक Arrayमें सभी वोटों की गिनती होती है। क्या मैं सही हूँ?
इस्माइल मिगुएल

1
@IsmaelMiguel हाँ।
PhiNotPi

1
दूसरा। वे चुनाव के आंशिक परिणाम हैं, जो आप से आगे के लोगों द्वारा दिए गए मतों के फेरबदल के क्रम में किए गए वोट हैं।
PhiNotPi

2
आप यह भी देखना चाहते हैं कि जब आप मतदाताओं को क्लोन का समूह देते हैं तो क्या होता है। एक संक्षिप्त नज़र, sometimesSecondBestBot, NoThirdPartyBot पर और सभी आशावादी बड़ा मतदान पूल से लाभ करने लगते हैं (जैसा कि अपने तरीके से, communismBot में extremistBot करते हैं और, लेकिन यह कम महत्वपूर्ण है)।
Saidoro

जवाबों:


10

NoThirdPartyBot

यह बॉट यह अनुमान लगाने की कोशिश करता है कि कौन सा उम्मीदवार तीसरा होगा, और उस उम्मीदवार को वोट देगा जिसे वह दो फ्रंट रनर में से सबसे अच्छा पसंद करता है।

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class NoThirdPartyBot implements Player {

    public NoThirdPartyBot(int e) {
    }


    @Override
    public String getName() {
        return "NoThirdPartyBot";
    }

    @Override
    public int getVote(int[] voteCounts, int votersRemaining, int[] payoffs,
            int[] totalPayoffs) {
        List<Integer> order = order(totalPayoffs);

        if (payoffs[order.get(0)] > payoffs[order.get(1)]) {
            return order.get(0);
        } else {
            return order.get(1);
        }
    }

    static List<Integer> order(int[] array) {
        List<Integer> indexes = Arrays.asList(0, 1, 2);
        Collections.sort(indexes, (i1, i2) -> array[i2] - array[i1]);
        return indexes;
    }

    @Override
    public void receiveResults(int[] voteCounts, double result) {
    }
}

CircumspectBot

यह बॉट अपने पसंदीदा के लिए वोट करता है जिसे गणितीय रूप से समाप्त नहीं किया गया है।

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;


public class CircumspectBot implements Player {

    public CircumspectBot(int elections) {
    }

    @Override
    public String getName() {
        return "CircumspectBot";
    }

    @Override
    public int getVote(int[] voteCounts, int votersRemaining, int[] payoffs,
            int[] totalPayoffs) {
        List<Integer> indexes = new ArrayList<>();
        int topVote = Arrays.stream(voteCounts).max().getAsInt();
        for (int index = 0; index < 3; index++) {
            if (voteCounts[index] + votersRemaining + 1 >= topVote) {
                indexes.add(index);
            }
        }
        Collections.sort(indexes, (i1, i2) -> payoffs[i2] - payoffs[i1]);

        return indexes.get(0);
    }

    @Override
    public void receiveResults(int[] voteCounts, double result) {

    }

}

4
मैं दांव लगाऊंगा सर्कसपैक्ट बॉट व्यक्तिगत पसंदीदा बॉट की तुलना में कड़ाई से बेहतर है। अच्छा लगा।
इसहाक

10

ExpectantBot

यह बॉट प्रत्येक मतदान विकल्प के अनुमानित मूल्य की गणना करता है, यह मानते हुए कि सभी मतदाता बाद में यादृच्छिक रूप से मतदान करेंगे।

import java.util.Arrays;

public class ExpectantBot implements Player {

    public ExpectantBot(int elections) {
    }

    @Override
    public String getName() {
        return "ExpectantBot";
    }

    static double choose(int x, int y) {
        if (y < 0 || y > x) return 0;
        if (y > x/2) {
            // choose(n,k) == choose(n,n-k), 
            // so this could save a little effort
            y = x - y;
        }

        double denominator = 1.0, numerator = 1.0;
        for (int i = 1; i <= y; i++) {
            denominator *= i;
            numerator *= (x + 1 - i);
        }
        return numerator / denominator;
    }

    double expectedPayout(int[] voteCounts, int[] payoffs, int votersRemaining) {
        double total = 0.0;
        for (int firstPartyVoters = 0; firstPartyVoters <= votersRemaining; firstPartyVoters++) {
            for (int secondPartyVoters = 0; secondPartyVoters <= votersRemaining - firstPartyVoters; secondPartyVoters++) {
                int thirdPartyVoters = votersRemaining - firstPartyVoters - secondPartyVoters;

                int [] newVoteCounts = voteCounts.clone();
                newVoteCounts[0] += firstPartyVoters;
                newVoteCounts[1] += secondPartyVoters;
                newVoteCounts[2] += thirdPartyVoters;
                int highest = Arrays.stream(newVoteCounts).max().getAsInt();
                int payoff = 0;
                int winCount = 0;
                for (int index = 0; index < 3; index++) {
                    if (newVoteCounts[index] == highest) {
                        payoff += payoffs[index];
                        winCount++;
                    }
                }
                double v = (double)payoff / (double) winCount;
                double value = choose(votersRemaining, firstPartyVoters)*choose(votersRemaining - firstPartyVoters, secondPartyVoters)*v*Math.pow(1/3.0, votersRemaining);
                total += value;
            }
        }
        return total;
    }

    @Override
    public int getVote(int[] voteCounts, int votersRemaining, int[] payoffs,
            int[] totalPayoffs) {

        int bestVote = 0;
        double bestScore = 0.0;
        for (int vote = 0; vote < 3; vote++) {      
            voteCounts[vote]++;
            double score = expectedPayout(voteCounts, payoffs, votersRemaining);
            if (score > bestScore) {
                bestVote = vote;
                bestScore = score;
            }
            voteCounts[vote]--;
        }
        return bestVote;

    }

    @Override
    public void receiveResults(int[] voteCounts, double result) {   
    }

}

अन्य विरोधियों से भारी पैठ के बिना, मुझे आश्चर्य होगा अगर कुछ भी इस आदमी को धड़कता है।
डॉक्टरहेकले

@ डॉक्टरहेकल, मुझे स्टेटबोट की उम्मीद थी, लेकिन मुझे लगता है कि आप सही हैं।
विंस्टन इवर्ट

9

HipBot

हिपबॉट पेआउट के बारे में परवाह नहीं करता है। पैसा सिर्फ एक शामक है जो सच्ची कला से विचलित करता है।

HipBot किसी के लिए वोट करने के लिए चाहता है असली ही नहीं, कुछ कॉर्पोरेट shill। वह हार (अपमानजनक) हार के बाद भी अपने अभियान की शर्ट पहनना चाहता है, इसलिए जब भी विजेता कुछ गलत करता है तो वह श्रेष्ठ महसूस करता है।

इसलिए, हिपबोट सबसे कम वोट वाले व्यक्ति के लिए वोट देता है या, यदि कोई टाई है, तो जिसे बेहतर भुगतान मिला है। केवल जैविक भोजन ही मुफ्त नहीं है।

public class HipBot implements Player{

    public HipBot(int rounds){ /*Rounds are a social construct*/ }

    public String getName(){ return "HipBot"; }

    public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs){

        int coolest = 0;
        int lowest = 100000000;
        int gains = 0;

        for( int count = 0; count < voteCounts.length; count++ ){

            if( voteCounts[count] < lowest || (voteCounts[count] == lowest && payoffs[count] > gains) ){

                lowest = voteCounts[count];
                coolest = count;
                gains = payoffs[count];

            }

        }

        return coolest;

    }

    public void receiveResults(int[] voteCounts, double result){ /*The past is dead*/ }

}

हिपबॉट भी अप्रयुक्त है, इसलिए मुझे बताएं कि क्या कुछ चल रहा है।

संपादित करें: अधिक प्रतिस्पर्धी टाईब्रेकिंग, पिट्टी टिप्पणियों में जोड़ा गया।


मेरे लिए काम करता है, हालांकि शिथिल के लिए उनकी दया उनके स्कोर के लिए बहुत कुछ नहीं करती है :)
euanjt

5
वह अपने दिमाग में जीता है, और उसके लिए, यह सब मायने रखता है: D
DoctorHeckle

8

PersonalFavoriteBot

इस बॉट ने सबसे अधिक व्यक्तिगत भुगतान के साथ उम्मीदवार के लिए वोट दिया, बाकी सब कुछ अनदेखा कर दिया। इस चुनौती के मुख्य बिंदुओं में से एक यह प्रदर्शित करना है कि यह इष्टतम रणनीति कैसे नहीं है।

import java.lang.Math;
import java.util.Random;
/**
 * This bot picks the candidate with the highest personal payoff, ignoring everyone else's actions.
 * 
 * @author PhiNotPi 
 * @version 5/27/15
 */
public class PersonalFavoriteBot implements Player
{
    Random rnd;
    String name;
    /**
     * Constructor for objects of class PersonalFavoriteBot
     */
    public PersonalFavoriteBot(int e)
    {
       rnd = new Random(); 
       name = "PersonalFavoriteBot" + rnd.nextInt(1000);
    }

    public String getName()
    {
        return name;
    }

    public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs)
    {
        //return rnd.nextInt(3);
        int maxloc = 0;
        for(int i = 1; i< 3; i++)
        {
            if(payoffs[i] > payoffs[maxloc])
            {
                maxloc = i;
            }
        }
        return maxloc;
    }

    public void receiveResults(int[] voteCounts, double result)
    {

    }
}

RandomBot

यह बॉट बेतरतीब ढंग से वोट करता है। चुनावों की संख्या के बावजूद (जब तक यह काफी हद तक उच्च है, 100 से अधिक की तरह), इस प्रतियोगी के सामान्यीकृत स्कोर में -2 और 2 के बीच उतार-चढ़ाव होता है।

import java.lang.Math;
import java.util.Random;
/**
 * This bot votes for a random candidate.
 * 
 * @author PhiNotPi 
 * @version 5/27/15
 */
public class RandomBot implements Player
{
    Random rnd;
    String name;
    /**
     * Constructor for objects of class RandomBot
     */
    public RandomBot(int e)
    {
       rnd = new Random(); 
       name = "RandomBot" + rnd.nextInt(1000);
    }

    public String getName()
    {
        return name;
    }

    public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs)
    {
        return rnd.nextInt(3);
    }

    public void receiveResults(int[] voteCounts, double result)
    {

    }
}

7

अनुगामी

अनुयायी इसमें फिट होना चाहता है। यह पूरा करने का सबसे अच्छा तरीका है कि वह वोटिंग उसी तरह से करे जैसे कि बाकी सभी, या कम से कम अब तक की बहुलता के साथ। यह थोड़ी सी स्वतंत्रता दिखाने के लिए, अपनी स्वयं की वरीयता के संबंध तोड़ देगा। लेकिन बहुत ज्यादा नहीं।

public class Follower implements Player
{
    public Follower(int e) { }

    public String getName()
    {
        return "Follower";
    }

    public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs)
    {
        int mostPopular = 0;
        int mostVotes = voteCounts[0];
        for (int i = 1; i < voteCounts.length; i++) {
            int votes = voteCounts[i];
            if (votes > mostVotes || (votes == mostVotes && payoffs[i] > payoffs[mostPopular])) {
                mostPopular = i;
                mostVotes = votes;
            }
        }
        return mostPopular;

    }

    public void receiveResults(int[] voteCounts, double result) { }
}

नोट: मैंने इसका परीक्षण नहीं किया है, इसलिए मुझे बताएं कि क्या कोई त्रुटि है।


यह काम करने लगता है।
PhiNotPi

4

मौंटे कारलो

यह यादृच्छिक चुनावों की एक बड़ी मात्रा का अनुकरण करता है। यह तब विकल्प चुनता है जो इसे अधिकतम लाभ देता है।

import java.util.ArrayList;
import java.util.List;

public class MonteCarlo implements Player{

    private static long runs = 0;
    private static long elections = 0;

    public MonteCarlo(int e) {
        elections = e;
    }

    @Override
    public String getName() {
        return "Monte Carlo (difficulty " + (runs / elections) + ")";
    }

    @Override
    public int getVote(int[] voteCounts, int votersRemaining, int[] payoffs, int[] totalPayoffs) {
        elections++;
        double[] predictedPayoffs = new double[3];
        long startTime = System.nanoTime();
        while (System.nanoTime() - startTime <= 200_000){ //Let's give us 200 micro-seconds.
            runs++;
            int[] simulatedVoteCounts = voteCounts.clone();
            for (int j = 0; j < votersRemaining; j++){
                simulatedVoteCounts[((int) Math.floor(Math.random() * 3))]++;
            }
            for (int j = 0; j < 3; j++) {
                simulatedVoteCounts[j]++;
                List<Integer> winners = new ArrayList<>();
                winners.add(0);
                for (int k = 1; k < 3; k++) {
                    if (simulatedVoteCounts[k] > simulatedVoteCounts[winners.get(0)]) {
                        winners.clear();
                        winners.add(k);
                    } else if (simulatedVoteCounts[k] == simulatedVoteCounts[winners.get(0)]) {
                        winners.add(k);
                    }
                }
                for (int winner : winners) {
                    predictedPayoffs[j] += payoffs[winner] / winners.size();
                }
                simulatedVoteCounts[j]--;
            }
        }
        int best = 0;
        for (int i = 1; i < 3; i++){
            if (predictedPayoffs[i] > predictedPayoffs[best]){
                best = i;
            }
        }
        return best;
    }

    @Override
    public void receiveResults(int[] voteCounts, double result) {

    }
}

4

StatBot

स्टेटबोट ExpectantBot पर आधारित है; हालांकि, यह मानने के बजाय कि प्रत्येक वोट समान रूप से संभावित है, यह इस बात पर आँकड़े एकत्र करता है कि लोग कैसे वोट देते हैं और संभावना का अनुमान लगाने के लिए इसका उपयोग करते हैं।

import java.util.Arrays;


public class StatBot implements Player {

    static private int[][][] data = new int[3][3][3];
    private int[] voteCounts;

    StatBot(int unused) {

    }

    @Override
    public String getName() {
        return "StatBot";

    }

     static double choose(int x, int y) {
            if (y < 0 || y > x) return 0;
            if (y > x/2) {
                // choose(n,k) == choose(n,n-k), 
                // so this could save a little effort
                y = x - y;
            }

            double denominator = 1.0, numerator = 1.0;
            for (int i = 1; i <= y; i++) {
                denominator *= i;
                numerator *= (x + 1 - i);
            }
            return numerator / denominator;
        }

    double expectedPayout(int[] voteCounts, int[] payoffs, int votersRemaining) {
        Integer[] indexes = {0, 1, 2};
        Arrays.sort(indexes, (i0, i1) -> voteCounts[i1] - voteCounts[i0]);
        int [] stats = data[indexes[0]][indexes[1]];
        int total_stats = Arrays.stream(stats).sum();
        double total = 0.0;
        for (int firstPartyVoters = 0; firstPartyVoters <= votersRemaining; firstPartyVoters++) {
            for (int secondPartyVoters = 0; secondPartyVoters <= votersRemaining - firstPartyVoters; secondPartyVoters++) {
                int thirdPartyVoters = votersRemaining - firstPartyVoters - secondPartyVoters;

                int [] newVoteCounts = voteCounts.clone();
                newVoteCounts[0] += firstPartyVoters;
                newVoteCounts[1] += secondPartyVoters;
                newVoteCounts[2] += thirdPartyVoters;
                int highest = 0;
                for (int h : newVoteCounts) {
                    if (h > highest) highest = h;
                }
                int payoff = 0;
                int winCount = 0;
                for (int index = 0; index < 3; index++) {
                    if (newVoteCounts[index] == highest) {
                        payoff += payoffs[index];
                        winCount++;
                    }
                }
                double v = (double)payoff / (double) winCount;
                double value = choose(votersRemaining, firstPartyVoters)*choose(votersRemaining - firstPartyVoters, secondPartyVoters)*v;
                value *= Math.pow((double)stats[0]/(double)total_stats, firstPartyVoters);
                value *= Math.pow((double)stats[1]/(double)total_stats, secondPartyVoters);
                value *= Math.pow((double)stats[2]/(double)total_stats, thirdPartyVoters);

                total += value;
            }
        }
        return total;
    }

    @Override
    public int getVote(int[] voteCounts, int votersRemaining, int[] payoffs,
            int[] totalPayoffs) {

        int bestVote = 0;
        double bestScore = 0.0;
        for (int vote = 0; vote < 3; vote++) {      
            voteCounts[vote]++;
            double score = expectedPayout(voteCounts, payoffs, votersRemaining);
            if (score > bestScore) {
                bestVote = vote;
                bestScore = score;
            }
            voteCounts[vote]--;
        }
        voteCounts[bestVote]++;
        this.voteCounts = voteCounts;

        return bestVote;

    }

    @Override
    public void receiveResults(int[] endVoteCounts, double result) {
        Integer[] indexes = {0, 1, 2};
        Arrays.sort(indexes, (i0, i1) -> voteCounts[i1] - voteCounts[i0]);
        for(int i = 0; i < 3; i++){
            data[indexes[0]][indexes[1]][i] += endVoteCounts[i] - voteCounts[i];
        }
    }
}

4

सर्वश्रेष्ठ व्यवहार्य उम्मीदवार

मेरे मूल प्रस्तुत करने का बहुत भारी संशोधित संस्करण। यह अभी भी किसी भी उम्मीदवार को समाप्त कर देता है जो कि डाले जाने के लिए शेष वोटों को नहीं जीत सकता है, लेकिन फिर एक रणनीति का उपयोग करता है जो कि पूर्ण के बजाय सापेक्ष भुगतान को अनुकूलित करने की कोशिश करता है । पहला परीक्षण प्रत्येक उम्मीदवार के लिए मेरे व्यक्तिगत भुगतान का अनुपात लेने के लिए है, वहां सर्वोत्तम मूल्य की तलाश है। मैं तब अन्य अनुपातों की तलाश करता हूं जो सबसे अच्छे के बहुत करीब हैं और अगर कोई ऐसा है जिसमें बहुत कम सर्वश्रेष्ठ भुगतान है, तो मैं इसके बजाय इसे चुनता हूं। उम्मीद है कि यह अन्य खिलाड़ियों के भुगतान को कम करने के लिए होगा, जबकि मेरा उद्देश्य काफी ऊंचा होगा।

यह बॉट लगभग मेरे स्वयं के परीक्षण पर मूल के रूप में अच्छी तरह से करता है, लेकिन काफी नहीं। हमें यह देखना होगा कि यह पूरे क्षेत्र के खिलाफ कैसा है।

 /**
  * This bot picks the candidate with the highest relative payoff out of those
  * candidates who are not already mathematically eliminated.
  *
  * @author Ralph Marshall
  * @version 5/28/2015
  */

import java.util.List;
import java.util.ArrayList;


public class BestViableCandidate implements Player
{
    private static int NUM_CANDIDATES = 3;
    private int relativeCount = 0;
    private int relativeCountLowerTotal = 0;
    private int totalRuns;

    public BestViableCandidate(int r) {
        totalRuns = r;
    }

    public String getName() {
        return "BestViableCandidate (" + relativeCount + " from ratio, with " + relativeCountLowerTotal + " tie-breakers of " + totalRuns + " total runs)";
    }

    public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs) {

        int i, maxVoteSoFar = 0;

        // First we figure out the maximum possible number of votes each candidate would get
        // if every remaining bot voted for it
        int [] maxPossibleVotes = new int[NUM_CANDIDATES];
        for (i = 0; i < NUM_CANDIDATES; i++) {

            // The voters remaining does not include me, so we need to add one to it
            maxPossibleVotes[i] = voteCounts[i] + votersRemaining + 1;

            if (voteCounts[i] > maxVoteSoFar) {
                maxVoteSoFar = voteCounts[i];
            }
        }

        // Then we throw out anybody who cannot win even if they did get all remaining votes
        List<Integer> viableCandidates = new ArrayList<Integer>();
        for (i = 0; i < NUM_CANDIDATES; i++) {
            if (maxPossibleVotes[i] >= maxVoteSoFar) {
                viableCandidates.add(Integer.valueOf(i));
            }
        }

        // And of the remaining candidates we pick the one that has the personal highest payoff
        // relative to the payoff to the rest of the voters
        int maxCandidate = -1;
        double maxRelativePayoff = -1;
        int maxPayoff = -1;
        int minTotalPayoff = Integer.MAX_VALUE;

        int originalMaxCandidate = -1;
        double originalMaxPayoff = -1;

        double DELTA = 0.01;

        double tiebreakerCandidate = -1;

        for (Integer candidateIndex : viableCandidates) {
            double relativePayoff = (double) payoffs[candidateIndex] / (double) totalPayoffs[candidateIndex];
            if (maxRelativePayoff < 0 || relativePayoff - DELTA > maxRelativePayoff) {
                maxRelativePayoff = relativePayoff;
                maxCandidate = candidateIndex;

                maxPayoff = payoffs[candidateIndex];
                minTotalPayoff = totalPayoffs[candidateIndex];

            } else if (Math.abs(relativePayoff - maxRelativePayoff) < DELTA) {
                if (totalPayoffs[candidateIndex] < minTotalPayoff) {
                    tiebreakerCandidate = candidateIndex;

                    maxRelativePayoff = relativePayoff;
                    maxCandidate = candidateIndex;

                    maxPayoff = payoffs[candidateIndex];
                    minTotalPayoff = totalPayoffs[candidateIndex];

                }
            }

            if (payoffs[candidateIndex] > originalMaxPayoff) {
                originalMaxPayoff = payoffs[candidateIndex];
                originalMaxCandidate = candidateIndex;
            }
        }

        if (tiebreakerCandidate == maxCandidate) {
            relativeCountLowerTotal++;
        }

        if (originalMaxCandidate != maxCandidate) {
            /*                System.out.printf("%nSelecting candidate %d with relative payoff %f (%d/%d) instead of %d with relative payoff %f (%d/%d)%n",
                              maxCandidate, (double) payoffs[maxCandidate]/(double)totalPayoffs[maxCandidate], payoffs[maxCandidate], totalPayoffs[maxCandidate],
                              originalMaxCandidate, (double) payoffs[originalMaxCandidate]/(double)totalPayoffs[originalMaxCandidate], payoffs[originalMaxCandidate], totalPayoffs[originalMaxCandidate]);
            */
            relativeCount++;
        }

        return maxCandidate;
    }
}

1
क्या यह वैसा ही नहीं है CircumspectBot?
TheNumberOne

हाँ, यह पता चला है कि यह है; मैंने मुख्य प्रश्न में इस आशय की टिप्पणी की। जब मैंने इसे कोड करना शुरू किया तो मुझे बिल्कुल एहसास नहीं हुआ कि यह कैसे काम करता है। चूंकि CircumspectBot को पहले लिखा गया था, इसलिए इसे विचार के लिए स्पष्ट रूप से श्रेय मिलना चाहिए।
राल्फ मार्शल

मुझे लगता है कि आप अपनी कक्षा के अंत को याद कर रहे हैं।
विंस्टन इर्वेट

धन्यवाद। मैंने आखिरी ब्रेस खो दिया; वहाँ क्या था के बाद कोई अन्य कोड नहीं था।
राल्फ मार्शल

3

आशावादी

आशावादी बहुत आशावादी है और यह मानता है कि शेष मतदाताओं में से आधे उम्मीदवार उस उम्मीदवार को वोट देंगे जो उसे सबसे अच्छा भुगतान करता है।

import java.lang.Integer;
import java.lang.String;
import java.util.Arrays;
import java.util.Comparator;

public class Optimist implements Player
{
    public Optimist(int _) { }
    public String getName() { return "Optimist"; }
    public int getVote(int[] curVotes, int rem, final int[] payoffs, int[] _)
    {
        Integer[] opt = new Integer[] { 0, 1, 2 };
        Arrays.sort(opt, new Comparator<Integer>() { public int compare(Integer i1, Integer i2) { return payoffs[i1] > payoffs[i2] ? -1 : payoffs[i1] == payoffs[i2] ? 0 : 1; } });
        int a = curVotes[opt[0]], b = curVotes[opt[1]], c = curVotes[opt[2]];
        double rest = (double)rem / 4;
        if (b <= a + rest && c <= a + rest)
            return opt[0];
        else if (c <= b)
            return opt[1];
        else
            return opt[0];
    }
    public void receiveResults(int[] _, double __) { }
}

3

ABotDoNotForget

उनका लक्ष्य सरल है: कुल अदायगी का उपयोग करते हुए समग्र प्रवृत्तियों का निर्धारण करना और निचले / मध्यम / उच्चतर लोगों की संख्या की गणना करना। वह तब उसी के लिए मतदान करेगा, जिसके जीतने की संभावना सबसे अधिक है।

import java.util.ArrayList;

public class ABotDoNotForget implements Player
{
    private int nbElec;
    private int countElec=0;
    private int[] currPayoffs=new int[3];
    private int[] lmh=new int[3];
    private int[] wins=new int[3];

    public ABotDoNotForget(int nbElec)
    {
        this.nbElec=nbElec;
    }

    public String getName() {return "ABotDoNotForget";}

    public int getVote(int[] voteCounts, 
                        int votersRemaining, 
                        int[] payoffs,
                        int[] totalPayoffs) 
    {
        countElec++;
        System.arraycopy(totalPayoffs, 0, currPayoffs, 0, totalPayoffs.length);

        if(countElec<=nbElec/20&&countElec<=20)
        {
            int best=0;
            for(int i=1;i<payoffs.length;i++)
                if(payoffs[i]>=payoffs[best])
                    best=i;
            return best;
        }

        for(int i =1;i<totalPayoffs.length;i++)
        {
            if(totalPayoffs[i]<totalPayoffs[i-1])
            {
                int tmp= totalPayoffs[i];
                totalPayoffs[i]=totalPayoffs[i-1];
                totalPayoffs[i-1]=tmp;
                if(i==2&&totalPayoffs[i-1]<totalPayoffs[i-2]){
                    tmp= totalPayoffs[i-1];
                    totalPayoffs[i-1]=totalPayoffs[i-2];
                    totalPayoffs[i-2]=tmp;
                }
            }
        }
        lmhDist(currPayoffs,totalPayoffs);
        int best=0;
        for(int i=1;i<wins.length;i++)
            if(wins[i]>=wins[best]){
                best=i;
            }
        int ownH=0;
        for(int i=1;i<payoffs.length;i++)
            if(payoffs[i]>=payoffs[ownH])
                ownH=i;
        int ownM=0;
        for(int i=1;i<payoffs.length;i++)
            if(payoffs[i]>=payoffs[ownM]&&i!=ownH)
                ownM=i;

        int persBest=(voteCounts[ownH]-voteCounts[ownM]+(votersRemaining/3)>=0
                &&voteCounts[ownH]-voteCounts[best]<(votersRemaining/3))?ownH:ownM;

        return persBest;

    }

    public void receiveResults(int[] voteCounts, double result) 
    {
        int best=0,bestV=voteCounts[best];
        for(int i=1;i<voteCounts.length;i++)
            if(voteCounts[i]>=bestV){
                best=i;
                bestV=voteCounts[i];
            }
        wins[lmh[best]]++;

    }

    private void lmhDist(int[] a,int[] s)
    {
        ArrayList<Integer> al = new ArrayList<Integer>();
        al.add(a[0]);al.add(a[1]);al.add(a[2]);
        lmh[0]=al.indexOf(s[0]);
        lmh[1]=al.indexOf(s[1]);
        lmh[2]=al.indexOf(s[2]);

    }
}

संपादित करें:

निर्णय में किए गए कुछ बदलाव, अब अपने सर्वश्रेष्ठ भुगतान को ध्यान में रखते हैं। अब बेहतर मतदान करने में सक्षम होना चाहिए जब वर्तमान वितरण उसे अपने लोअर के लिए वोट दे रहा था जब अन्य जहां अपने उच्च भुगतान के लिए मतदान कर रहे थे।


3

प्रियम

प्रियम को रिक्रिएशन से नफरत है। वह कुल भुगतान के आधार पर प्रत्येक बचे हुए बॉट की संभावना का अनुमान लगाता है और फिर अपने अदायगी को अधिकतम करने के सर्वोत्तम तरीके की गणना करता है।

public class Priam implements Player {
    private static double[] smallFactorials = {1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800,479001600,6227020800.,87178291200.,1307674368000.,20922789888000.,355687428096000.,6402373705728000.,121645100408832000.,2432902008176640000.};
    @Override
    public String getName() {
        return "Priam";
    }

    @Override
    public int getVote(int[] voteCounts, int votersRemaining, int[] payoffs,
            int[] totalPayoffs) {
        int totalPayoff = totalPayoffs[0] + totalPayoffs[1] + totalPayoffs[2];
        double p0 = ((double)totalPayoffs[0])/totalPayoff;
        double p1= ((double) totalPayoffs[1])/totalPayoff;
        double p2 = ((double)totalPayoffs[2])/totalPayoff;
        double[] expectedPayoffs = {0,0,0};
        for(int myChoice=0;myChoice<3;myChoice++)
        {
            for(int x0 = 0; x0 <= votersRemaining; x0++)
            {
                for(int x1 = 0; x1 <= (votersRemaining-x0); x1++)
                {
                    int x2 = votersRemaining - (x1 + x0);
                    double probability =
                            Math.pow(p0, x0)
                            * Math.pow(p1, x1)
                            * Math.pow(p2, x2)
                            * Choose(votersRemaining, x0)
                            * Choose(votersRemaining-x0, x1);
                    int votes0 = voteCounts[0];
                    int votes1 = voteCounts[1];
                    int votes2 = voteCounts[2];
                    if(myChoice == 0)
                    {
                        votes0++;
                    }
                    else if(myChoice==1)
                    {
                        votes1++;
                    }
                    else
                    {
                        votes2++;
                    }

                    votes0+=x0;
                    votes1+=x1;
                    votes2+=x2;
                    if(votes0>votes1 && votes0>votes2)
                    {
                        expectedPayoffs[myChoice]+=probability*payoffs[0];
                    }
                    else if(votes1>votes2)
                    {
                        expectedPayoffs[myChoice]+=probability*payoffs[1];
                    }
                    else
                    {
                        expectedPayoffs[myChoice]+=probability*payoffs[2];
                    }
                }
            }
        }
        if(expectedPayoffs[0]>expectedPayoffs[1] && expectedPayoffs[0]>expectedPayoffs[2])
        {
            return 0;
        }
        else if(expectedPayoffs[1]>expectedPayoffs[2])
        {
            return 1;
        }
        else
        {
            return 2;
        }
    }

    private long Choose(int source, int team) {
        return Factorial(source)/(Factorial(team)*Factorial(source-team));
    }

    private long Factorial(int n) {
        if(n<=20)
        {
            return (long)smallFactorials[n];
        }
        double d=(double)n;
        double part1 = Math.sqrt(2*Math.PI*d);
        double part2 = Math.pow(d/Math.E, d);
        return (long)Math.ceil(part1 * part2);
    }

    @Override
    public void receiveResults(int[] voteCounts, double result) {


    }
    public Priam(int i)
    {

    }
}

ओडीसियस की तुलना में बहुत अधिक तेज है क्योंकि कोई पुनरावृत्ति नहीं है (समय ओ (एन ^ 2) में चलता है) और लगभग 15 सेकंड में एक मिलियन चुनाव कर सकते हैं।


"मुझे लगता है कि यह अपने लाभ के लिए कुल अदायगी पैरामीटर का उपयोग करने वाला पहला बॉट है :)" मेरे बॉट को देखें (ABotDoNotForget), वह पहले से ही इसका उपयोग कर रहा है, क्षमा करें: D
कैटेन्को

मेरे नवीनतम बॉट, एक्स्पेक्टेंटबॉट के बहुत करीब, सिवाय इसके कि आप संभावना का अनुमान लगाने के लिए कुलपयॉफ़ का उपयोग करते हैं और मुझे लगता है कि हर वोट समान रूप से संभावित है। मैं यह देखने के लिए उत्सुक हूं कि कौन सी रणनीति सबसे अच्छा काम करती है।
विंस्टन एवर्ट

@WinstonEwert मुझे लगता है कि आप करते हैं, आपने पिछले तीन टेस्ट जीते हैं।
euanjt

मैंने केवल समानता पर ध्यान दिया है- मैं ओडीसियस का एक संस्करण बनाने की कोशिश कर रहा था, जिसे 100 चुनावों को चलाने में 10 घंटे नहीं लगते थे, इसलिए मैंने छोरों के लिए इस्तेमाल किया
euanjt

ईमानदार होने के लिए, मुझे ओडीसियस द्वारा अपना दृष्टिकोण लेने के लिए प्रेरित किया गया था।
विंस्टन एवर्ट

2

NoClueBot

NoClue वास्तव में जावा या गणित को बहुत अच्छी तरह से नहीं जानता है, इसलिए उसे कोई पता नहीं है कि क्या यह भार-अनुपात-चीज़ उसे जीतने में मदद करेगा। लेकिन वह कोशिश कर रहा है।

import java.lang.Math;
import java.util.*;
/**
 * Created by Admin on 5/27/2015.
 */
public class NoClueBot implements Player {

    public NoClueBot(int e) { }

    public String getName() {
        return "NoClueBot";
    }

    public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs) {
        double x = 0;
        int y = 0;
        for (int i=0; i<3; i++) {
            double t = (double) voteCounts[i] * ((double) payoffs[i]/(double) totalPayoffs[i]);
            if (x<t) {
                x = t;
                y = i; 
            }
        }
        return y;
    }

    public void receiveResults(int[] voteCounts, double result) { }
}


SomeClueBot

SomeClueBot को डिमोशन किया गया है। वास्तव में तर्क का उपयोग करता है! तर्क का उपयोग करते थे, जो अक्षम हो गया था, इसलिए इसके बजाय वह अपने स्वयं के नहीं बल्कि कुल अदायगी के प्रति जागरूक हो गया। फिर से तर्क का उपयोग करता है! लेकिन वह इन सभी अनुयायियों और आशावादियों, और यहां तक ​​कि उन लोगों के साथ अच्छा नहीं करता है, जो परवाह नहीं करते हैं! :)


SometimesSecondBestBot

मूल रूप से PersonalFavouriteBot, बेहतर (सिद्धांत में)।

import java.lang.Math;
/**
 * Created by Admin on 5/27/2015.
 */
public class SometimesSecondBestBot implements Player {
    public SometimesSecondBestBot(int e) { }

    public String getName() {
        return "SometimesSecondBestBot";
    }

    public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs) {
        int m = 0;
        int n = 0;
        for(int i = 1; i< 3; i++) {
            if(payoffs[i] > payoffs[m]) { n = m; m = i; }
        }
        return (voteCounts[n]>voteCounts[m]&&totalPayoffs[n]>totalPayoffs[m])||(voteCounts[m]+votersRemaining<voteCounts[n])||voteCounts[m]+votersRemaining<voteCounts[Math.min(3-n-m, 2)] ? n : m;
    }

    public void receiveResults(int[] voteCounts, double result) { }
}

1
ऐसा लगता है कि आप एक संख्या की गणना करते हैं जो तीन वज़न में सबसे बड़ा है और सबसे अच्छा उम्मीदवार चुनने के लिए उस मान mod 3 से अधिक है। क्या यह सही है और यदि ऐसा नहीं है तो यह मूल रूप से एक यादृच्छिक संख्या है? मैं समझता हूं कि आप इसे "गणित कठिन बार्बी" कह रहे हैं, इसलिए मुझे यकीन नहीं है कि मेरे पास अवधारणा है।
राल्फ मार्शल

@RalphMarshall हां, यह मूल रूप से यादृच्छिक है। हालाँकि, मैंने पूरी तरह से ऐसा करने का इरादा नहीं किया था, ध्यान नहीं दे रहा था, हाहा। अब निश्चित कर दिया।
केड

@PhiNotPhi मुझे लगता है कि मैंने इसे अब सीमा से बाहर जाना तय किया है। और हाँ, मैं हैरान नहीं हूँ।
काडे

मेरे भगवान यह बुरा है .. मेरे बचाव के काम में आज मानसिक रूप से बहुत कम था।
केड

2

चरमपंथी

हमेशा सबसे कम अदायगी वाले उम्मीदवार को वोट करें

public class ExtremistBot implements Player
{
    public ExtremistBot(int e){}

    public void receiveResults(int[] voteCounts, double result){}

    public String getName(){
        return "ExtremistBot";
    }

    public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs)
    {
        int min = 0;
        for(int i = 1; i<payoffs.length; i++){
            if(payoffs[i] <payoffs[min]){
                min = i;
            }
        }
        return min;
    }
}

2

SmashAttemptByEquality

लक्ष्य सभी कैंडिडेट्स की बराबरी करना है, फिर SMASH! अंतिम राउंड पर अन्य सभी बॉट।
यह एक विनाशकारी एल्गोरिथ्म है जो जीत का दावा करने के लिए अन्य सभी को बाहर निकालने की कोशिश करता है।

public class SmashAttemptByEquality implements Player {
    static private int elections;

    public SmashAttemptByEquality(int e) { 
        this.elections = e;
    }

    public String getName() {
        return "SmashAttemptByEquality (on " + String.valueOf(this.elections) + " elections)";
    }

    public int getVote(int[] voteCounts, int votersRemaining, int[] payoffs, int[] totalPayoffs) {

        //if there are no votes or it is a tie
        if(voteCounts.length == 0 || (voteCounts[0] == voteCounts[1] && voteCounts[1] == voteCounts[2]))
        {
            //let the system handle the (distributed?) randomness
            return 3;
        }

        //we want to win, so, lets not mess when there are no voters left
        if( votersRemaining > 0 )
        {
            //lets bring some equality!
            if( voteCounts[0] >= voteCounts[1] )
            {
                if(voteCounts[0] > voteCounts[2])
                {
                    return 2;
                }
                else
                {
                    return 0;
                }
            }
            else if( voteCounts[1] >= voteCounts[2] )
            {
                if(voteCounts[1] > voteCounts[0])
                {
                    return 0;
                }
                else
                {
                    return 1;
                }
            }
            else
            {
                return 0;
            }
        }
        else
        {
            //just play for the winner!
            if( voteCounts[0] >= voteCounts[1] )
            {
                if(voteCounts[0] > voteCounts[2])
                {
                    return 0;
                }
                else
                {
                    return 2;
                }
            }
            else if( voteCounts[1] >= voteCounts[2] )
            {
                if(voteCounts[1] > voteCounts[0])
                {
                    return 1;
                }
                else
                {
                    return 0;
                }
            }
            else
            {
                return 0;
            }
        }
    }

    public void receiveResults(int[] voteCounts, double result) { }
}

ध्यान दें कि यह अप्राप्त है !


2

बेसिक बॉट

बेसिक बॉट सिर्फ उन उम्मीदवारों के लिए वोट करता है जो समाप्त नहीं होते हैं और उन उम्मीदवारों से सबसे अधिक अधिकतम भुगतान होता है।

public class BasicBot implements Player {
    public BasicBot(int e) { }
    public String getName()
    {
        return "BasicBot";
    }
    public static int getMax(int[] inputArray){ 
    int maxValue = inputArray[0]; 
    for(int i=1;i < inputArray.length;i++){ 
      if(inputArray[i] > maxValue){ 
         maxValue = inputArray[i]; 
      } 
    } 
    return maxValue; 
   }
    public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs)
    {
        // Check for Eliminated Candidates
        int eliminated0 = 0;
        int eliminated1 = 0;
        int eliminated2 = 0;
        if( ((voteCounts[0] + votersRemaining) < voteCounts[1]) || ((voteCounts[0] + votersRemaining) < voteCounts[2]))
        {
            eliminated0 = 1;
        }
        if( ((voteCounts[1] + votersRemaining) < voteCounts[0]) || ((voteCounts[1] + votersRemaining) < voteCounts[2]))
        {
            eliminated1 = 1;
        }
        if( ((voteCounts[2] + votersRemaining) < voteCounts[0]) || ((voteCounts[2] + votersRemaining) < voteCounts[1]))
        {
            eliminated2 = 1;
        }
        // Choose the Candidates that is not elimated with the largest payoff
        if ((payoffs[0] == getMax(payoffs)) && eliminated0 == 0)
            return 0
        else if ((payoffs[1] == getMax(payoffs)) && eliminated1 == 0)
            return 1
        else
            return 2

    }

    public void receiveResults(int[] voteCounts, double result)
    {
    }

}

2

केली की पसंदीदा

मैंने CircumspectBot से शुरुआत की, लेकिन बहुत कुछ बचा नहीं है। शेष मतों की संभाव्यता वितरण में एक प्रकार का उबाऊ अनुमान लगाता है, और फिर यह विकल्प बनाता है जो अपनी लॉग-यूटिलिटी (केली मानदंड) को अधिकतम करता है। सबसे तेजी से नहीं, लेकिन कुछ अन्य लोगों की गेंद पार्क के भीतर। इसके अलावा, यह क्षेत्र के साथ काफी प्रतिस्पर्धी है (जैसा कि यह तब खड़ा हुआ जब मैंने इस पर काम करना शुरू किया, और अन्य बॉट्स डाउनलोड किए)।

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

public class KellysFavorite implements Player {
    private ArrayList<Double> cache = new ArrayList<Double>();

    public KellysFavorite(int elections) {
        cache.add(0.0);
        double v = 0.0;
        for(int i=1; i<1000; i++) {
            v += Math.log(i);
            cache.add(v);
        }
    }

    @Override
    public String getName() {
        return "Kelly's Favorite";
    }

    private double factln(int n) {
        return cache.get(n);
    }

    private  double binll(int x, int n, double p)
    {
        double ll = 0.0;
        ll += ((double)x)*Math.log(p);
        ll += ((double)(n - x))*Math.log(1.0 - p);
        ll += factln(n) - factln(x) - factln(n-x);
        return ll;
    }

    public  double logAdd(double logX, double logY) {
        // 1. make X the max
        if (logY > logX) {
            double temp = logX;
            logX = logY;
            logY = temp;
        }
        // 2. now X is bigger
        if (logX == Double.NEGATIVE_INFINITY) {
            return logX;
        }
        // 3. how far "down" (think decibels) is logY from logX?
        //    if it's really small (20 orders of magnitude smaller), then ignore
        double negDiff = logY - logX;
        if (negDiff < -20) {
            return logX;
        }
        // 4. otherwise use some nice algebra to stay in the log domain
        //    (except for negDiff)
        return logX + java.lang.Math.log(1.0 + java.lang.Math.exp(negDiff));
    }

    @Override
    public int getVote(int[] voteCounts,
                       int votersRemaining,
                       int[] payoffs,
                       int[] totalPayoffs) {
        int totalviable = 0;
        boolean[] viable = { false, false, false };
        int topVote = Arrays.stream(voteCounts).max().getAsInt();
        for (int index = 0; index < 3; index++) {
            if (voteCounts[index] + votersRemaining + 1 >= topVote) {
                viable[index] = true;
                totalviable += 1;
            }
        }

        // if only one candidate remains viable, vote for them
        if(totalviable == 1) {
            for(int index = 0; index < 3; index++)
                if(viable[index])
                    return index;
        } else {
            double votelikelihoods[] = { 0.0, 0.0, 0.0 };
            double totalweight = 0.0;
            for(int index=0; index<3; index++) {
                if(!viable[index])
                    votelikelihoods[index] -= 10.0;
                else if(voteCounts[index] < topVote)
                    votelikelihoods[index] -= 0.1;

                totalweight += Math.exp(votelikelihoods[index]);
            }

            double probs[] = new double[3];
            for(int index=0; index<3; index++) {
                probs[index] = Math.exp(votelikelihoods[index]) / totalweight;
            }

            double[] utilities = {0,0,0};
            for(int mychoice=0; mychoice<3; mychoice++) {
                boolean seen[] = { false, false, false };
                double likelihoods[] = { Double.NEGATIVE_INFINITY,
                                         Double.NEGATIVE_INFINITY,
                                         Double.NEGATIVE_INFINITY };
                int[] localVoteCounts = { voteCounts[0] + (mychoice==0?1:0),
                                          voteCounts[1] + (mychoice==1?1:0),
                                          voteCounts[2] + (mychoice==2?1:0) };
                for(int iVotes=0; iVotes<=votersRemaining; iVotes++)
                    for(int jVotes=0; jVotes<=(votersRemaining-iVotes); jVotes++) {
                        int kVotes = votersRemaining - iVotes - jVotes;

                        int a = localVoteCounts[0] + iVotes;
                        int b = localVoteCounts[1] + jVotes;
                        int c = localVoteCounts[2] + kVotes;
                        int wincount = Math.max(a, Math.max(b, c));
                        int winners = 0;
                        if(a>=wincount) { winners += 1; }
                        if(b>=wincount) { winners += 1; }
                        if(c>=wincount) { winners += 1; }

                        double likelihood =
                            binll(iVotes, votersRemaining, probs[0])
                            + binll(jVotes, votersRemaining-iVotes, probs[1] / (probs[1] + probs[2]));

                        likelihood += Math.log(1.0/winners);

                        if(a>=wincount) {
                            if(seen[0])
                                likelihoods[0] = logAdd(likelihoods[0],
                                                        likelihood);
                            else
                                likelihoods[0] = likelihood;
                            seen[0] = true;
                        }
                        if(b>=wincount) {
                            if(seen[1])
                                likelihoods[1] = logAdd(likelihoods[1],
                                                        likelihood);
                            else
                                likelihoods[1] = likelihood;
                            seen[1] = true;
                        }
                        if(c>=wincount) {
                            if(seen[2])
                                likelihoods[2] = logAdd(likelihoods[2],
                                                        likelihood);
                            else
                                likelihoods[2] = likelihood;
                            seen[2] = true;
                        }

                    }

                for(int index=0; index<3; index++)
                    utilities[mychoice] += Math.exp(likelihoods[index]) * Math.log((double)payoffs[index]);
            }

            double maxutility = Math.max(utilities[0], Math.max(utilities[1], utilities[2]));
            int choice = 0;
            for(int index=0; index<3; index++)
                if(utilities[index]>=maxutility)
                    choice = index;
            return choice;
        }

        throw new InternalError();
    }

    @Override
    public void receiveResults(int[] voteCounts, double result) {

    }

}

इसके अलावा उपलब्ध https://gist.github.com/jkominek/dae0b3158dcd253e09e5 के मामले में यह सरल है।


2

CommunismBot

कम्युनिज्मबॉट सोचता है कि हम सभी को बस साथ लेना चाहिए और हर किसी के लिए सबसे अच्छा उम्मीदवार चुनना चाहिए।

public class CommunismBot implements Player
{
    Random rnd;
    String name;
    public CommunismBot(int e) {
        rnd = new Random(); 
        name = "CommunismBot" + rnd.nextInt(1000);
    }

    public String getName()
    {
        return name;
    }

    public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs)
    {
        int maxloc = 0;
        for(int i = 1; i< 3; i++)
        {
            if(totalPayoffs[i] > totalPayoffs[maxloc])
            {
                maxloc = i;
            }
        }
        return maxloc;
    }

    public void receiveResults(int[] voteCounts, double result) { }
}

Hatebot

हेटबोट हमेशा सबसे अच्छा उम्मीदवार चुनता है। जब तक वे एक गंदी-बदबूदार पार्टी न हो, 1. वे लोग भयानक हैं।

import java.util.Random;


public class HateBot implements Player
{
    Random rnd;
    String name;
    public HateBot(int e) {
        rnd = new Random(); 
        name = "HateBot" + rnd.nextInt(1000); }

    public String getName()
    {
        return name;
    }

    public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs)
    {
        if(payoffs[0]>payoffs[2])
            return 0;
        else
            return 2;
    }

    public void receiveResults(int[] voteCounts, double result) { }
}

StrategicBot

सर्वश्रेष्ठ उम्मीदवार के लिए स्ट्रैटेजिकबोट वोट प्रदान करते हैं कि वे अगले सर्वश्रेष्ठ उम्मीदवार के एक मानक विचलन के भीतर हैं, शेष मतदाताओं की संख्या को देखते हुए।

import java.util.Random;

public class StrategicBot implements Player
{
    Random rnd;
    String name;
    public StrategicBot(int e) {
        rnd = new Random(); 
        name = "StrategicBot" + rnd.nextInt(1000);

    }

    public String getName()
    {
        return name;
    }

    public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs)
    {
        double margin = 9.0*votersRemaining/9;
        int maxloc = 0;
        boolean noLead=false;
        for(int i = 1; i< 3; i++)
        {
            for(int j = 1; j < 3; j++)
            {
                if(payoffs[j] + margin > payoffs[i])
                    noLead=true;
            }
            if(payoffs[i] > payoffs[maxloc] && noLead)
            {
                maxloc = i;
            }
            noLead=false;
        }
        return maxloc;
    }

    public void receiveResults(int[] voteCounts, double result) { }
}

2

ExpectorBot

यह भविष्यवाणी करने की कोशिश करता है कि अन्य सभी बॉट दूसरों के लिए औसत भुगतान की गणना करके कैसे वोट करेंगे। सर्वश्रेष्ठ भुगतान के लिए डिफ़ॉल्ट वोट, लेकिन दूसरे सर्वश्रेष्ठ के लिए वोट करेंगे, अगर इसमें सर्वश्रेष्ठ से अधिक अपेक्षित वोट हैं, तो मेरे लिए औसत भुगतान की तुलना में बेहतर और सबसे खराब भुगतान के लिए इस चीज़ को जीतने का मौका है।

import java.util.Arrays;

public class ExpectorBot implements Player
{
    class Votee
    {
        int index;
        int payoff;
        float avgPayoff;
        float expectedVotes;
    }

    public ExpectorBot( final int e )
    {

    }

    @Override
    public String getName()
    {
        return "ExpectorBot";
    }

    @Override
    public int getVote( final int[] voteCounts, final int votersRemaining, final int[] payoffs, final int[] totalPayoffs )
    {
        final int otherVoters = Arrays.stream( voteCounts ).sum() + votersRemaining;
        final Votee[] v = createVotees( voteCounts, otherVoters, votersRemaining, payoffs, totalPayoffs );

        final Votee best = v[ 0 ]; // Most Payoff
        final Votee second = v[ 1 ];
        final Votee worst = v[ 2 ];

        int voteFor = best.index;

        if( ( second.expectedVotes >= best.expectedVotes + 1 ) // Second has more votes than Best even after I vote
                && ( second.payoff >= second.avgPayoff ) // Second payoff better than average for the others
                && ( worst.expectedVotes >= best.expectedVotes + 0.5f ) ) // Worst has a chance to win
        {
            voteFor = second.index;
        }

        return voteFor;
    }

    private Votee[] createVotees( final int[] voteCounts, final int otherVoters, final int votersRemaining, final int[] payoffs, final int[] totalPayoffs )
    {
        final Votee[] v = new Votee[ 3 ];

        for( int i = 0; i < 3; ++i )
        {
            v[ i ] = new Votee();
            v[ i ].index = i;
            v[ i ].payoff = payoffs[ i ];

            // This is the average payoff for other Players from this Votee
            v[ i ].avgPayoff = (float)( totalPayoffs[ i ] - payoffs[ i ] ) / otherVoters;

            // The expected number of Votes he will get if everyone votes for biggest payoff
            v[ i ].expectedVotes = voteCounts[ i ] + ( votersRemaining * v[ i ].avgPayoff / 100.0f );
        }

        Arrays.sort( v, ( o1, o2 ) -> o2.payoff - o1.payoff );

        return v;
    }

    @Override
    public void receiveResults( final int[] voteCounts, final double result )
    {

    }
}

1

LockBot

बस एक अकेला दार्शनिक, अपने "ई" की तलाश में ...

//He thinks he's the father of democracy, but something's missing....
public class LockBot implements Player {

public LockBot(int i) {
    //One election, 10000000, what's the difference?
}

@Override
public String getName() {
    return "LockBot";
}

@Override
public int getVote(int[] voteCounts, int votersRemaining, int[] payoffs,
        int[] totalPayoffs) {

    double totalPlayers = voteCounts.length + votersRemaining;
    double totalPayoff = totalPlayers * 100;

    //adjust total payoffs to ignore my own
    for( int i = 0; i < totalPayoffs.length; i++){
        totalPayoffs[i] -= payoffs[i];
    }

    //Votes are probably proportional to payoffs
    //So lets just find the highest weight
    double[] expectedOutcome = new double[3];
    for(int i = 0; i< expectedOutcome.length; i++){
        expectedOutcome[i] = (totalPayoffs[i] / totalPayoff) * payoffs[i];
    }

    //Find the highest
    int choice = 0;
    if(expectedOutcome[1] > expectedOutcome[choice]){
        choice = 1;
    }
    if(expectedOutcome[2] > expectedOutcome[choice]){
        choice = 2;
    }




    return choice;
}

@Override
public void receiveResults(int[] voteCounts, double result) {
    // TODO Auto-generated method stub

}

}

0

हार जीत

अगर तुम जीत गए, तो मैं हार गया! यह सरल है। तो यह बॉट उस वोट के लिए जिसे वह पसंद करता है और बाकी सभी को नापसंद है।

public class WinLose implements Player
{
    public WinLose(int e) { }

    public String getName()
    {
        return "WinLose";
    }
    public int getVote(int [] voteCounts, int votersRemaining, int [] payoffs, int[] totalPayoffs)
    {
        int max = 0;
        for(int i = 1; i< 3; i++)
        {
            if(10*payoffs[i]-totalPayoffs[i] > 10*payoffs[max]-totalPayoffs[max])
            {
                max = i;
            }
        }
        return max;
    }

    public void receiveResults(int[] voteCounts, double result)
    {

    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.