การเพิ่มประสิทธิภาพความท้าทายด้วยเหรียญแปลก ๆ


17

คุณมีnเหรียญที่แต่ละคนมีน้ำหนัก -1 หรือ 1 แต่ละคนมีป้ายกำกับจาก0เพื่อn-1ให้คุณสามารถแยกเหรียญ คุณมีอุปกรณ์ชั่งน้ำหนัก (เวทมนต์) หนึ่งชิ้นเช่นกัน ในตอนแรกคุณสามารถใส่เหรียญได้มากเท่าที่คุณต้องการบนอุปกรณ์ชั่งน้ำหนักซึ่งสามารถวัดได้ทั้งน้ำหนักติดลบและบวกและจะบอกคุณได้อย่างแม่นยำ

อย่างไรก็ตามมีบางอย่างแปลก ๆ เกี่ยวกับอุปกรณ์ชั่งน้ำหนัก หากคุณใส่เหรียญx_1, x_2, ..., x_jลงในอุปกรณ์เป็นครั้งแรกในครั้งต่อไปคุณต้องใส่เหรียญ(x_1+1), (x_2+1) , ..., (x_j+1)ในเครื่องชั่งยกเว้นคุณไม่สามารถใส่เหรียญที่มีหมายเลขสูงกว่าn-1ได้ ไม่เพียงเท่านั้นสำหรับการชั่งน้ำหนักใหม่ทุกครั้งที่คุณเลือกถ้าคุณต้องการใส่เหรียญ0ลงในเครื่องชั่ง

ภายใต้กฎนี้จำนวนการชั่งน้ำหนักที่เล็กที่สุดที่จะบอกคุณได้ว่าเหรียญใดมีน้ำหนัก 1 และน้ำหนักใด -1

เห็นได้ชัดว่าคุณสามารถใส่เหรียญ0ลงในอุปกรณ์ในเทิร์นแรกจากนั้นจะต้องใช้การnชั่งน้ำหนักเพื่อแก้ไขปัญหา

ภาษาและห้องสมุด

คุณสามารถใช้ภาษาหรือห้องสมุดที่คุณชอบ (ที่ไม่ได้ออกแบบมาสำหรับความท้าทายนี้) อย่างไรก็ตามฉันต้องการทดสอบโค้ดของคุณถ้าเป็นไปได้ดังนั้นหากคุณสามารถให้คำแนะนำที่ชัดเจนเกี่ยวกับวิธีการเรียกใช้ใน Ubuntu ที่จะได้รับการชื่นชมอย่างมาก

คะแนน

สำหรับnคะแนนของคุณจะถูกnหารด้วยจำนวนน้ำหนักที่คุณต้องการในกรณีที่แย่ที่สุด คะแนนที่สูงขึ้นจึงดีกว่า ไม่มีข้อมูลเกี่ยวกับตัวต่อนี้ แต่เป้าหมายของคุณคือค้นหาสิ่งnที่คุณจะได้รับคะแนนสูงสุด

หากมีการเสมอกันคำตอบแรกจะชนะ ในสถานการณ์ที่ไม่น่าเป็นไปได้อย่างมากที่มีคนพบวิธีที่จะได้รับคะแนนอนันต์บุคคลนั้นจะชนะทันที

งาน

งานของคุณคือการเขียนโค้ดที่ได้คะแนนสูงสุด รหัสของคุณจะต้องเลือกทั้งสองอย่างอย่างชาญฉลาดแล้วจึงปรับจำนวนน้ำหนักให้nเหมาะสม

รายการชั้นนำ

  • 4/3 7/5 ในPythonโดย Sarge Borsch
  • 26/14 ในJavaโดย Peter Taylor

8
ฉันชอบที่จะได้รับเหรียญต่อต้านแรงโน้มถ่วง
mbomb007

2
ฉันมีวิธีแก้ปัญหาที่ไม่เคยใช้เครื่องจักร: ถือเหรียญแต่ละใบแล้วดูว่าคนใดดึงมือของคุณขึ้นมาและดึงมือของคุณลงมา
คดีกองทุนของโมนิกา

1
นอกจากนี้ในฐานะที่เป็นหมายเหตุด้านข้างคุณควรเขียน "ถ้าคุณชั่งเหรียญ a ถึง b จากนั้นในครั้งต่อไปที่คุณต้องทำ +1 กับ b + 1" (อาจมีการโยน 'อย่างน้อย' ด้วยเช่นกัน และการจัดรูปแบบที่ดีขึ้น) แทนที่จะเป็นตัวห้อยแสดงถึงหมายเลขเหรียญ ทำให้ดูเหมือนว่าเป็นทรัพย์สินหรือปริมาณของเหรียญ _ แทนที่จะเป็นเหรียญ
คดีฟ้องร้องกองทุนโมนิก้า

1
@ mbomb007 ในการชั่งน้ำหนักแต่ละครั้งคุณสามารถเลือกที่จะชั่งเหรียญ 0 เช่นเดียวกับเหรียญอื่น ๆ ที่คุณจะชั่งน้ำหนัก คุณมีทางเลือกใหม่สำหรับการชั่งน้ำหนักแต่ละอย่างที่คุณทำ

3
@ mbomb007 @QPaysTaxes เกี่ยวกับสัญกรณ์x_i: เราสามารถยกตัวอย่างเช่นการชั่งน้ำหนักครั้งแรกของ (x_1, x_2, x_3) = (3, 2, 7) และจากนั้นการชั่งน้ำหนักครั้งที่สองอาจเป็น (4, 3, 8) หรือ ( 0, 4, 3, 8) ฉลากเหรียญไม่จำเป็นต้องต่อเนื่องกันและดัชนีiในx_iไม่ได้อ้างอิงถึงฉลากของเหรียญ
Mitch Schwartz

คำตอบ:


3

C ++, คะแนน23/12 25/13 27/14 28/14 = 2 31/15

การแก้ปัญหาของMatrix property X revisited (หรือ Joy of X)สามารถใช้งานได้โดยตรงเป็นวิธีแก้ปัญหานี้ เช่นคำตอบของ 31 แถว 15 คอลัมน์:

1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 0 1 1 0 
1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 0 1 1 
1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 0 1 
1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 0 
1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 
0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 1 1 
0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 1 
1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 
0 1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 
0 0 1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 
0 0 0 1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 
1 0 0 0 1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 
0 1 0 0 0 1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 
0 0 1 0 0 0 1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 
1 0 0 1 0 0 0 1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 

แถว N แสดงถึงเหรียญที่คุณใส่ลงในเครื่องชั่งสำหรับการวัด N ไม่ว่าผลลัพธ์ของการชั่งน้ำหนักที่คุณได้รับจะมีค่าของชุดเหรียญที่ให้น้ำหนักนั้นอย่างเห็นได้ชัด หากมีชุดค่าผสมอื่นด้วย (โซลูชันไม่ซ้ำกัน) พิจารณาว่าแตกต่างกันอย่างไร คุณต้องเปลี่ยนการตั้งค่าของเหรียญน้ำหนักโดยเหรียญน้ำหนัก1 -1นี่เป็นชุดของคอลัมน์ที่สอดคล้องกับการพลิกนั้น นอกจากนี้ยังมีการตั้งค่าของเหรียญน้ำหนักที่คุณแทนที่โดย-1 1นั่นคือชุดคอลัมน์อื่น เนื่องจากการวัดไม่ได้เปลี่ยนแปลงระหว่างสองวิธีนั่นหมายความว่าผลรวมคอลัมน์ของทั้งสองชุดจะต้องเท่ากัน แต่การแก้ปัญหาของMatrix property X กลับมาอีกครั้ง (หรือ Joy of X) เป็นเมทริกซ์เหล่านี้ทั้งหมดที่ไม่มีชุดคอลัมน์ดังกล่าวดังนั้นจึงไม่มีการทำซ้ำและแต่ละโซลูชันไม่ซ้ำกัน

0/1เมทริกซ์บางตัวสามารถอธิบายชุดการวัดจริงแต่ละชุดได้ แต่แม้ว่าบางคอลัมน์จะตั้งค่าผลรวมเป็นเวกเตอร์เดียวกันก็อาจเป็นได้ว่าสัญญาณของค่าเหรียญวิธีแก้ปัญหาผู้สมัครนั้นไม่ตรงกับชุดดังกล่าว ดังนั้นฉันไม่รู้ว่าเมทริกซ์เช่นที่กล่าวมานั้นเหมาะสมหรือไม่ แต่อย่างน้อยพวกเขาก็ให้ขอบเขตที่ต่ำกว่า ความเป็นไปได้ที่ 31 เหรียญสามารถทำได้น้อยกว่า 15 การวัดที่ยังเปิดอยู่

โปรดสังเกตว่านี่เป็นความจริงเฉพาะสำหรับกลยุทธ์ที่ไม่แน่นอนซึ่งการตัดสินใจของคุณที่จะใส่เหรียญ0บนเครื่องชั่งขึ้นอยู่กับผลลัพธ์ของน้ำหนักก่อนหน้า มิฉะนั้นคุณจะมีวิธีแก้ปัญหาที่สัญญาณของเหรียญสอดคล้องกับชุดที่มีผลรวมคอลัมน์เดียวกัน


สถิติโลกปัจจุบัน :)

คอมพิวเตอร์ประมาณว่าคุณจะต้องมีความเร็วถึง 2 เท่า

@ Lembik ฉันไม่มั่นใจ 2 เป็นไปได้ ฉันไม่รู้ว่าทำไม แต่ผลลัพธ์ในปัจจุบันแนะนำให้คุณเข้าใกล้ 2 โดยไม่
ตั้งใจ

คุณได้รับโอกาสในการตรวจสอบเมทริกซ์เวียนโลหิต 25 โดย 50 ที่ฉันวางซึ่งควรให้ 2 หรือไม่? 01011011100010111101000001100111110011010100011010 เป็นแถวแรกของเมทริกซ์หมุนเวียน

ฉันไม่รู้วิธีตรวจสอบเมทริกซ์นั้นโดยไม่ต้องเขียนโปรแกรมเฉพาะที่จะทำงานเป็นเวลานาน
Ton Hospel

5

Python 2 คะแนน = 1.0

นี่เป็นคะแนนง่ายในกรณีที่ไม่มีใครพบคะแนนที่ดีกว่า (สงสัย) nweighings nสำหรับแต่ละ

import antigravity
import random

def weigh(coins, indices):
    return sum(coins[i] for i in indices)

def main(n):
    coins = [random.choice([-1,1]) for i in range(n)]
    for i in range(len(coins)):
        print weigh(coins, [i]),

main(4)

ฉันนำเข้าantigravityเพื่อให้โปรแกรมสามารถทำงานกับน้ำหนักเชิงลบได้


มีประโยชน์มาก ขอบคุณ :)

การนำเข้าantigravityนั้นเป็นแบบไม่ใช้งานใช่ไหม
ชื่อที่ปรากฏ

@SargeBorsch สำหรับจุดประสงค์ของโปรแกรมนี้ก็คือ แต่มันจะทำอะไรซักอย่างจริงๆ
mbomb007

5

คะแนน = 26/14 ~ = 1.857

import java.util.*;

public class LembikWeighingOptimisation {

    public static void main(String[] args) {
        float best = 0;
        int opt = 1;
        for (int n = 6; n < 32; n+=2) {
            long start = System.nanoTime();
            System.out.format("%d\t", n);
            opt = optimise(n, n / 2 + 1);
            float score = n / (float)opt;
            System.out.format("%d\t%f", opt, score);
            if (score > best) {
                best = score;
                System.out.print('*');
            }
            System.out.format(" in %d seconds", (System.nanoTime() - start) / 1000000000);
            System.out.println();
        }
    }

    private static int optimise(int numCoins, int minN) {
        MaskRange.N = numCoins;
        Set<MaskRange> coinSets = new HashSet<MaskRange>();
        coinSets.add(new MaskRange(0, 0));

        int allCoins = (1 << numCoins) - 1;

        for (int n = minN; n < numCoins; n++) {
            for (int startCoins = 1; startCoins * 2 <= numCoins; startCoins++) {
                for (int mask = (1 << startCoins) - 1; mask < (1 << numCoins); ) {
                    // Quick-reject: in n turns, do we cover the entire set?
                    int qr = (1 << (n-1)) - 1;
                    for (int j = 0; j < n; j++) qr |= mask << j;
                    if ((qr & allCoins) == allCoins && canDistinguishInNTurns(mask, coinSets, n)) {
                        System.out.print("[" + Integer.toBinaryString(mask) + "] ");
                        return n;
                    }

                    // Gosper's hack to update
                    int c = mask & -mask;
                    int r = mask + c;
                    mask = (((r^mask) >>> 2) / c) | r;
                }
            }
        }

        return numCoins;
    }

    private static boolean canDistinguishInNTurns(int mask, Set<MaskRange> coinsets, int n) {
        if (n < 0) throw new IllegalArgumentException("n");
        int count = 0;
        for (MaskRange mr : coinsets) count += mr.size();
        if (count <= 1) return true;
        if (n == 0) return false;

        // Partition.
        Set<MaskRange>[] p = new Set[Integer.bitCount(mask) + 1];
        for (int i = 0; i < p.length; i++) p[i] = new HashSet<MaskRange>();
        for (MaskRange range : coinsets) range.partition(mask, p);

        for (int d = 0; d < 2; d++) {
            boolean ok = true;
            for (Set<MaskRange> s : p) {
                if (!canDistinguishInNTurns((mask << 1) + d, s, n - 1)) {
                    ok = false;
                    break;
                }
            }

            if (ok) return true;
        }

        return false;
    }

    static class MaskRange {
        public static int N;
        public final int mask, value;

        public MaskRange(int mask, int value) {
            this.mask = mask;
            this.value = value & mask;
            if (this.value != value) throw new IllegalArgumentException();
        }

        public int size() {
            return 1 << (N - Integer.bitCount(mask));
        }

        public void partition(int otherMask, Set<MaskRange>[] p) {
            otherMask &= (1 << N) - 1;

            int baseline = Integer.bitCount(value & otherMask);
            int variables = otherMask & ~mask;
            int union = mask | otherMask;
            partitionInner(value, union, variables, baseline, p);
        }

        private static void partitionInner(int v, int m, int var, int baseline, Set<MaskRange>[] p) {
            if (var == 0) {
                p[baseline].add(new MaskRange(m, v));
            }
            else {
                int lowest = var & (1 + ~var);
                partitionInner(v,          m, var & ~lowest, baseline, p);
                partitionInner(v | lowest, m, var & ~lowest, baseline + 1, p);
            }
        }

        @Override
        public String toString() {
            return String.format("(x & %x = %x)", mask, value);
        }
    }
}

บันทึกเป็นLembikWeighingOptimisation.javaรวบรวมเป็นjavac LembikWeighingOptimisation.java, java LembikWeighingOptimisationการทำงานเป็น

ขอบคุณมากสำหรับMitch Schwartz ที่ชี้จุดบกพร่องในรุ่นแรกของการปฏิเสธอย่างรวดเร็ว

นี่ใช้เทคนิคพื้นฐานที่ค่อนข้างเป็นธรรมซึ่งฉันไม่สามารถพิสูจน์ได้อย่างจริงจัง มันกำลังดุร้าย แต่สำหรับการเริ่มต้นการชั่งน้ำหนักซึ่งใช้เกือบครึ่งเหรียญ: ลำดับที่ใช้มากกว่าครึ่งหนึ่งของเหรียญไม่สามารถถ่ายโอนโดยตรงไปยังการชั่งน้ำหนักเสริม (เพราะเราไม่รู้น้ำหนักรวมทั้งหมด) แต่ในระดับคลื่นมือควรมีข้อมูลประมาณเท่ากัน นอกจากนี้ยังวนซ้ำผ่านการเริ่มต้นการชั่งน้ำหนักตามจำนวนเหรียญที่เกี่ยวข้องบนพื้นฐานที่ว่ามันครอบคลุมการชั่งน้ำหนักแบบกระจาย (ซึ่งหวังว่าจะให้ข้อมูลเกี่ยวกับปลายด้านบนค่อนข้างเร็ว) โดยไม่ต้องคลานผ่านพวงที่เริ่มต้นด้วยชุดย่อยที่หนาแน่น ปลายล่าง

MaskRangeระดับคือการปรับปรุงใหญ่ในรุ่นก่อนหน้านี้ในแง่ของการใช้หน่วยความจำและเอา GC จากการเป็นคอขวด

20      [11101001010] 11        1.818182* in 5364 seconds
22      [110110101000] 12       1.833333* in 33116 seconds
24      [1000011001001] 13      1.846154* in 12181 seconds                                                                                                            
26      [100101001100000] 14    1.857143* in 73890 seconds  

คุณไม่สามารถรับ 12/7 ได้หรือไม่? ฉันค่อนข้างแน่ใจว่าใช้งานได้ ยังไงประมาณ 19/10 ฉันคิดว่ารหัสของฉันให้ฉันครั้งเดียว แต่ฉันไม่สามารถทำซ้ำได้ในขณะนี้

@ Lembik ฉันลงทะเบียน 12/7 แต่สิ่งที่ดีที่สุดที่ฉันทำได้ 19 คือ 19/11
Peter Taylor

โอ้ใช่ขอโทษ เป็นไปได้ไหมที่ฮิวริสติกของคุณละทิ้งวิธีแก้ปัญหาบ้าง ฉันค่อนข้างมั่นใจว่า 19/10 ควรทำงานเช่นกัน

เป็นไปได้ใช่ถ้าทางออกเดียวที่มีการชั่งครั้งแรกที่มีมากกว่าครึ่งหนึ่งของเหรียญ แม้ว่าฉันจะประหลาดใจเล็กน้อย
Peter Taylor

มันคุ้มค่าที่จะเพิ่มเกณฑ์ครึ่งหนึ่งให้มากกว่าแค่ครึ่งเล็กน้อยหรือไม่?

2

Python 3 คะแนน = 4/3 = 1.33 … (N = 4)คะแนน = 1.4 (N = 7)

อัปเดต: นำการค้นหาแบบ brute-force มาใช้ในชุดตัวแก้ไข "แบบคงที่" และได้รับผลลัพธ์ใหม่

ฉันคิดว่ามันสามารถปรับปรุงให้ดีขึ้นได้ด้วยการค้นหาตัวแก้ไขแบบไดนามิกซึ่งสามารถใช้ผลการถ่วงน้ำหนักเพื่อการตัดสินใจเพิ่มเติม

นี่คือรหัสไพ ธ อนที่ค้นหาตัวแก้ปัญหาแบบคงที่ทั้งหมดเพื่อหาค่าเล็ก ๆ n (ตัวแก้เหล่านี้จะชั่งน้ำหนักชุดเหรียญเดียวกันเสมอดังนั้นชื่อ "คงที่") และกำหนดหมายเลขกรณีที่เลวร้ายที่สุดของขั้นตอนเพียงแค่ตรวจสอบว่า ตั้งในทุกกรณี นอกจากนี้ยังติดตามคะแนนที่ดีที่สุดที่พบจนถึงนักแก้ปัญหาลูกพรุนและต้นซึ่งแสดงว่าพวกเขาเลวร้ายยิ่งกว่าที่เคยพบมาก่อน นี่คือการเพิ่มประสิทธิภาพที่สำคัญมิฉะนั้นฉันไม่สามารถรอผลลัพธ์นี้ด้วยn= 7 (แต่ก็ยังไม่ได้รับการปรับให้เหมาะสมอย่างชัดเจน)

อย่าลังเลที่จะถามคำถามหากยังไม่ชัดเจนว่ามันทำงานอย่างไร ...

#!/usr/bin/env python3
import itertools
from functools import partial


def get_all_possible_coinsets(n):
    return tuple(itertools.product(*itertools.repeat((-1, 1), n)))


def weigh(coinset, indexes_to_weigh):
    return sum(coinset[x] for x in indexes_to_weigh)


# made_measurements: [(indexes, weight)]
def filter_by_measurements(coinsets, made_measurements):
    return filter(lambda cs: all(w == weigh(cs, indexes) for indexes, w in made_measurements), coinsets)


class Position(object):
    def __init__(self, all_coinsets, coinset, made_measurements=()):
        self.all_coinsets = all_coinsets
        self.made_measurements = made_measurements
        self.coins = coinset

    def possible_coinsets(self):
        return tuple(filter_by_measurements(self.all_coinsets, self.made_measurements))

    def is_final(self):
        possible_coinsets = self.possible_coinsets()
        return (len(possible_coinsets) == 1) and possible_coinsets[0] == self.coins

    def move(self, measurement_indexes):
        measure_result = (measurement_indexes, weigh(self.coins, measurement_indexes))
        return Position(self.all_coinsets, self.coins, self.made_measurements + (measure_result,))


def get_all_start_positions(coinsets):
    for cs in coinsets:
        yield Position(coinsets, cs)


def average(xs):
    return sum(xs) / len(xs)


class StaticSolver(object):
    def __init__(self, measurements):
        self.measurements = measurements

    def choose_move(self, position: Position):
        index = len(position.made_measurements)
        return self.measurements[index]

    def __str__(self, *args, **kwargs):
        return 'StaticSolver({})'.format(', '.join(map(lambda x: '{' + ','.join(map(str, x)) + '}', self.measurements)))

    def __repr__(self):
        return str(self)


class FailedSolver(Exception):
    pass


def test_solvers(solvers, start_positions, max_steps):
    for solver in solvers:
        try:
            test_results = tuple(map(partial(test_solver, solver=solver, max_steps=max_steps), start_positions))
            yield (solver, max(test_results))
        except FailedSolver:
            continue


def all_measurement_starts(n):
    for i in range(1, n + 1):
        yield from itertools.combinations(range(n), i)


def next_measurement(n, measurement, include_zero):
    shifted = filter(lambda x: x < n, map(lambda x: x + 1, measurement))
    if include_zero:
        return tuple(itertools.chain((0,), shifted))
    else:
        return tuple(shifted)


def make_measurement_sequence(n, start, zero_decisions):
    yield start
    m = start
    for zero_decision in zero_decisions:
        m = next_measurement(n, m, zero_decision)
        yield m


def measurement_sequences_from_start(n, start, max_steps):
    continuations = itertools.product(*itertools.repeat((True, False), max_steps - 1))
    for c in continuations:
        yield tuple(make_measurement_sequence(n, start, c))


def all_measurement_sequences(n, max_steps):
    starts = all_measurement_starts(n)
    for start in starts:
        yield from measurement_sequences_from_start(n, start, max_steps)


def all_static_solvers(n, max_steps):
    return map(StaticSolver, all_measurement_sequences(n, max_steps))


def main():
    best_score = 1.0
    for n in range(1, 11):
        print('Searching with N = {}:'.format(n))
        coinsets = get_all_possible_coinsets(n)
        start_positions = tuple(get_all_start_positions(coinsets))


        # we are not interested in solvers with worst case number of steps bigger than this
        max_steps = int(n / best_score)

        solvers = all_static_solvers(n, max_steps)
        succeeded_solvers = test_solvers(solvers, start_positions, max_steps)

        try:
            best = min(succeeded_solvers, key=lambda x: x[1])
        except ValueError:  # no successful solvers
            continue
        score = n / best[1]
        best_score = max(score, best_score)
        print('{}, score = {}/{} = {}'.format(best, n, best[1], score))
    print('That\'s all!')


def test_solver(start_position: Position, solver, max_steps):
    p = start_position
    steps = 0
    try:
        while not p.is_final():
            steps += 1
            if steps > max_steps:
                raise FailedSolver
            p = p.move(solver.choose_move(p))
        return steps
    except IndexError:  # solution was not found after given steps — this solver failed to beat score 1
        raise FailedSolver


if __name__ == '__main__':
    main()

ผลลัพธ์:

Searching with N = 1:
(StaticSolver({0}), 1), score = 1/1 = 1.0
Searching with N = 2:
(StaticSolver({0}, {0,1}), 2), score = 2/2 = 1.0
Searching with N = 3:
(StaticSolver({0}, {0,1}, {0,1,2}), 3), score = 3/3 = 1.0
Searching with N = 4:
(StaticSolver({0,1}, {1,2}, {0,2,3}, {0,1,3}), 3), score = 4/3 = 1.3333333333333333
Searching with N = 5:
Searching with N = 6:
Searching with N = 7:
(StaticSolver({0,2}, {0,1,3}, {0,1,2,4}, {1,2,3,5}, {0,2,3,4,6}), 5), score = 7/5 = 1.4
Searching with N = 8:
Searching with N = 9:
(I gave up waiting at this moment)

บรรทัดนี้ (StaticSolver({0,2}, {0,1,3}, {0,1,2,4}, {1,2,3,5}, {0,2,3,4,6}), 5), score = 7/5 = 1.4ค้นพบตัวแก้ปัญหาที่ดีที่สุด ตัวเลขใน{}เครื่องหมายปีกกาคือดัชนีของเหรียญเพื่อใส่อุปกรณ์ถ่วงน้ำหนักในแต่ละขั้นตอน


4
ป.ล. ฉันเขียนสิ่งนี้ในขณะที่แหล่งจ่ายไฟฟ้าในบ้านของฉันเสียดังนั้นฉันจึงมีแล็ปท็อปที่ใช้พลังงานจากแบตเตอรี่และไม่มีการเชื่อมต่ออินเทอร์เน็ตและฉันก็ไม่มีอะไรจะทำดีไปกว่าการไขปริศนา ฉันเดาว่าคงไม่รบกวนถ้าทุกอย่างเรียบร้อยดี: D
ชื่อที่ปรากฏ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.