Java, $ 806.899
Ini dari uji coba 2501 putaran. Saya masih berusaha mengoptimalkannya. Saya menulis dua kelas, pembungkus dan pemain. Pembungkus instantiate pemain dengan jumlah amplop (selalu 10.000 untuk hal yang nyata), dan kemudian memanggil metode takeQ
dengan nilai amplop atas. Pemain kemudian kembali true
jika mereka mengambilnya, false
jika mereka melewatinya.
Pemain
import java.lang.Math;
public class Player {
public int[] V;
public Player(int s) {
V = new int[s];
for (int i = 0; i < V.length; i++) {
V[i] = i + 1;
}
// System.out.println();
}
public boolean takeQ(int x) {
// System.out.println("look " + x);
// http://www.programmingsimplified.com/java/source-code/java-program-for-binary-search
int first = 0;
int last = V.length - 1;
int middle = (first + last) / 2;
int search = x;
while (first <= last) {
if (V[middle] < search)
first = middle + 1;
else if (V[middle] == search)
break;
else
last = middle - 1;
middle = (first + last) / 2;
}
int i = middle;
if (first > last) {
// System.out.println(" PASS");
return false; // value not found, so the envelope must not be in the list
// of acceptable ones
}
int[] newVp = new int[V.length - 1];
for (int j = 0; j < i; j++) {
newVp[j] = V[j];
}
for (int j = i + 1; j < V.length; j++) {
newVp[j - 1] = V[j];
}
double pass = calcVal(newVp);
int[] newVt = new int[V.length - i - 1];
for (int j = i + 1; j < V.length; j++) {
newVt[j - i - 1] = V[j];
}
double take = V[i] + calcVal(newVt);
// System.out.println(" take " + take);
// System.out.println(" pass " + pass);
if (take > pass) {
V = newVt;
// System.out.println(" TAKE");
return true;
} else {
V = newVp;
// System.out.println(" PASS");
return false;
}
}
public double calcVal(int[] list) {
double total = 0;
for (int i : list) {
total += i;
}
double ent = 0;
for (int i : list) {
if (i > 0) {
ent -= i / total * Math.log(i / total);
}
}
// System.out.println(" total " + total);
// System.out.println(" entro " + Math.exp(ent));
// System.out.println(" count " + list.length);
return total * (Math.pow(Math.exp(ent), -0.5) * 4.0 / 3);
}
}
Pembungkus
import java.lang.Math;
import java.util.Random;
import java.util.ArrayList;
import java.util.Collections;
public class Controller {
public static void main(String[] args) {
int size = 10000;
int rounds = 2501;
ArrayList<Integer> results = new ArrayList<Integer>();
int[] envelopes = new int[size];
for (int i = 0; i < envelopes.length; i++) {
envelopes[i] = i + 1;
}
for (int round = 0; round < rounds; round++) {
shuffleArray(envelopes);
Player p = new Player(size);
int cutoff = 0;
int winnings = 0;
for (int i = 0; i < envelopes.length; i++) {
boolean take = p.takeQ(envelopes[i]);
if (take && envelopes[i] >= cutoff) {
winnings += envelopes[i];
cutoff = envelopes[i];
}
}
results.add(winnings);
}
Collections.sort(results);
System.out.println(
rounds + " rounds, median is " + results.get(results.size() / 2));
}
// stol... I mean borrowed from
// http://stackoverflow.com/questions/1519736/random-shuffling-of-an-array
static Random rnd = new Random();
static void shuffleArray(int[] ar) {
for (int i = ar.length - 1; i > 0; i--) {
int index = rnd.nextInt(i + 1);
// Simple swap
int a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
}
}
Penjelasan lebih rinci akan segera hadir, setelah saya menyelesaikan optimasi.
Gagasan intinya adalah untuk dapat memperkirakan hadiah dari bermain game dari set amplop tertentu. Jika set amplop saat ini adalah {2,4,5,7,8,9}, dan amplop atas adalah 5, maka ada dua kemungkinan:
- Ambil 5 dan mainkan game dengan {7,8,9}
- Lewati 5 dan mainkan permainan {2,4,7,8,9}
Jika kita menghitung hadiah yang diharapkan dari {7,8,9} dan membandingkannya dengan hadiah yang diharapkan dari {2,4,7,8,9}, kita akan dapat mengetahui apakah mengambil 5 itu sepadan.
Sekarang pertanyaannya adalah, diberikan satu set amplop seperti {2,4,7,8,9} berapa nilai yang diharapkan? Saya menemukan nilai yang diharapkan tampaknya proporsional dengan jumlah total uang di set, tetapi berbanding terbalik dengan akar kuadrat dari jumlah amplop yang dibagi menjadi uang. Ini datang dari "sempurna" memainkan beberapa permainan kecil di mana semua amplop memiliki nilai yang hampir sama.
Masalah selanjutnya adalah bagaimana menentukan " jumlah efektif amplop." Dalam semua kasus, jumlah amplop diketahui persis dengan melacak apa yang telah Anda lihat dan lakukan. Sesuatu seperti {234.235.236} pasti tiga amplop, {231.232.233.234.235} pasti 5, tetapi {1,2.234.235.236} harus benar-benar dihitung sebagai 3 dan bukan 5 amplop karena 1 dan 2 hampir tidak berharga, dan Anda tidak akan pernah LULUS pada 234 jadi Anda kemudian dapat mengambil 1 atau 2. Saya punya ide untuk menggunakan entropi Shannon untuk menentukan jumlah efektif amplop.
Saya menargetkan perhitungan saya ke situasi di mana nilai-nilai amplop didistribusikan secara seragam selama beberapa interval, yang merupakan apa yang terjadi selama pertandingan. Jika saya mengambil {2,4,7,8,9} dan memperlakukannya sebagai distribusi probabilitas, entropinya adalah 1,50242. Kemudian saya lakukan exp()
untuk mendapatkan 4.49254 sebagai jumlah efektif amplop.
Taksiran hadiah dari {2,4,7,8,9} adalah 30 * 4.4925^-0.5 * 4/3 = 18.87
Jumlah pastinya 18.1167
.
Ini bukan perkiraan yang tepat, tapi saya benar-benar bangga dengan seberapa baik ini cocok dengan data ketika amplop didistribusikan secara seragam dalam suatu interval. Saya tidak yakin dengan pengali yang benar (saya menggunakan 4/3 untuk saat ini) tetapi di sini adalah tabel data tidak termasuk pengali.
Set of Envelopes Total * (e^entropy)^-0.5 Actual Score
{1,2,3,4,5,6,7,8,9,10} 18.759 25.473
{2,3,4,5,6,7,8,9,10,11} 21.657 29.279
{3,4,5,6,7,8,9,10,11,12} 24.648 33.125
{4,5,6,7,8,9,10,11,12,13} 27.687 37.002
{5,6,7,8,9,10,11,12,13,14} 30.757 40.945
{6,7,8,9,10,11,12,13,14,15} 33.846 44.900
{7,8,9,10,11,12,13,14,15,16} 36.949 48.871
{8,9,10,11,12,13,14,15,16,17} 40.062 52.857
{9,10,11,12,13,14,15,16,17,18} 43.183 56.848
{10,11,12,13,14,15,16,17,18,19} 46.311 60.857
Regresi linier antara yang diharapkan dan aktual memberikan nilai R ^ 2 sebesar 0,999994 .
Langkah saya berikutnya untuk meningkatkan jawaban ini adalah meningkatkan estimasi ketika jumlah amplop mulai menjadi kecil, yaitu ketika amplop tidak kira-kira didistribusikan secara seragam dan ketika masalahnya mulai menjadi butiran.
Sunting: Jika ini dianggap layak bitcoin, saya baru saja mendapat alamat di 1PZ65cXxUEEcGwd7E8i7g6qmvLDGqZ5JWg
. Terima kasih! (Ini di sini sejak penulis tantangan membagikan hadiah.)