Buch Cover Buch Cover Buch Cover Buch Cover

Web-Code: - Webcode Help

Farbstiftspitzen (Simulationen)

Voraussetzung: In einem Etui sind 20 Farbstifte. Alle sind stumpf und müssen gespitzt werden.
Nach folgendem Verfahren werden die Farbstifte nun gespitzt:

  1. Aufs Mal werden drei Stifte "blind" aus dem Etui genommen (beim ersten solchen "blinden Griff" sind natürlich alle drei stumpf).
  2. Alle drei Stifte werden gespitzt (die bereits spitzen darunter natürlich nicht).
  3. Die drei spitzen Stifte werden wieder zurückgelegt.

Die obigen drei Schritte werden so oft wiederholt, bis alle gespitzt sind. Dabei werden oft auch bereits gespitzte Farbstifte "gezogen".

  1. Schreiben Sie zunächst die Funktion, die drei verschiedene Zufallszahlen im Bereich 0 bis 19 findet.
  2. Simulieren Sie nun eine solche Spitzaktion und zählen Sie, wie oft herausgegriffen werden muss, bis alle gespitzt sind.
  3. Simulieren Sie nun 10 000 "Spitzaktionen" mit 20 Stiften und drei Blindgriffen pro Mal und messen Sie dabei
    • die durchschnittliche Anzahl Griffe,
    • minimale und maximale Anzahl Griffe.
  4. d) Verallgemeinern Sie die Aufgabe auf n Stifte (n > 2) und m Stifte pro Blindgriff (1 ? m < n).

0 Kommentare

Bitte melde dich an um einen Kommentar abzugeben

5 Lösung(en)

package eu.gressly.hw.simulation.spitzaktion;

import java.util.Random;

public class FarbstiftSpitzAktion {

    public static void main(String[] args) {
        new FarbstiftSpitzAktion().start(20, 3, 10000);
    }

    Random randomGenerator = new Random();

    void start(int totalStifte, int stifteAufsMal, int spitzAktionen) {

        int versuchsNummer                  =  0;
        int totalVersucheAllerSpitzaktionen =  0;
        int kuerzesteSpitzaktion            = -1;
        int laengsteSpitzaktion             =  0;
        while (versuchsNummer < spitzAktionen) {
            boolean[] neuesEtui = new boolean[totalStifte];
            int aktGriffe = spitzaktion(neuesEtui, stifteAufsMal);
            totalVersucheAllerSpitzaktionen = totalVersucheAllerSpitzaktionen
                    + aktGriffe;
            if (-1 == kuerzesteSpitzaktion) {
                kuerzesteSpitzaktion = aktGriffe;
            } else if (aktGriffe < kuerzesteSpitzaktion) {
                kuerzesteSpitzaktion = aktGriffe;
            }
            if (aktGriffe > laengsteSpitzaktion) {
                laengsteSpitzaktion = aktGriffe;
            }
            versuchsNummer = versuchsNummer + 1;
        }
        System.out.println("Benoetige durchschnittlich: "
                + ((double) totalVersucheAllerSpitzaktionen / spitzAktionen)
                + " Versuche");
        System.out.println("Min:" + kuerzesteSpitzaktion);
        System.out.println("Max:" + laengsteSpitzaktion);
    }

    
    int spitzaktion(boolean[] etui, int aufsMal) {
        int versuche = 0;
        while (!alleGespitzt(etui)) {
            spitzen(etui, aufsMal);
            versuche = versuche + 1;
        }
        return versuche;
    }

    
    boolean alleGespitzt(boolean[] etui) {
        for (boolean spitz : etui) {
            if (!spitz) {
                return false;
            }
        }
        return true;
    }

    
    void spitzen(boolean[] etui, int aufsMal) {
        // wähle "aufsMal" Zufallszahlen aus [0..etui.length - 1]
        // int[] samples = pickSample(etui.length, aufsMal);
        shuffle(aufsMal, etui.length);
        // spitze diese, egal, ob spitz oder stumpf
        int idx = 0;
        while (idx < aufsMal) {
            etui[INDIZES_ARRAY[idx]] = true; // spitz
            idx = idx + 1;
        }
    }

    /************************************************
     *  Sampling: n Zufallszahlen aus den ersten N indizes {0. ... N-1}
     */
    
    int[] INDIZES_ARRAY; // enhält 0, 1, 2, ... N-1

    void initIndizes(int len) {
        INDIZES_ARRAY = new int[len];
        int actPos = 0;
        while (actPos < len) {
            INDIZES_ARRAY[actPos] = actPos;
            actPos = actPos + 1;
        }
    }

    
    // zahl zwischen min und max (beide inklusive)
    int rndPos(int min, int max) {
        return ((int) (randomGenerator.nextDouble() * (max - min + 1))) + min;
    }

    
    void swap(int a, int b) {
        int tmp = INDIZES_ARRAY[a];
        INDIZES_ARRAY[a] = INDIZES_ARRAY[b];
        INDIZES_ARRAY[b] = tmp;
    }

    
    // nach "shuffle" sind die ersten n aus N gemischt.
    void shuffle(int n, int N) {
        if (null == INDIZES_ARRAY || INDIZES_ARRAY.length != N) {
            initIndizes(N);
        }
        int inPos = 0;
        while (inPos <= n - 1) {
            int rndPos = rndPos(inPos, N - 1);
            swap(inPos, rndPos);
            inPos = inPos + 1;
        }
    }

    /*
     * Altenativ, falls die Sample Anzahl hoch im Verhältnis zur Gesamtzahl. //
     * see: http://www.javamex.com/tutorials/random_numbers/random_sample.shtml
     * int[] pickSample(int left, int samplesNeeded) { int[] result = new
     * int[samplesNeeded]; int pickedAlready = 0; int act = 0; while
     * (samplesNeeded > 0) { int rand = randomGenerator.nextInt(left); if (rand
     * < samplesNeeded) { result[pickedAlready] =act; pickedAlready =
     * pickedAlready + 1; samplesNeeded = samplesNeeded - 1; } left = left - 1;
     * act = act + 1; } return result; }
     */


} // end of class FarbstiftSpitzAktion
                
#Farbstiftspitzen
import random

def spitzaktion(Etui, stifteAufsMal):
    zaehler =0
    while (False in Etui):
        zaehler +=1
        for i in range(stifteAufsMal):
            zug = random.randint(0, len(Etui)-1)
            Etui[zug] = True

    return zaehler    

def farbstiftSpitzAktion(totalStifte, stifteAufsMal,spitzAktionen):
    versuchsNummer= 0
    totalVersucheAllerSpitzaktionen=0
    kuerzesteSpitzaktion=1000000
    laengsteSpitzaktion=0
    while(versuchsNummer < spitzAktionen):
        neuesEtui = [False]*totalStifte
        aktGriffe = spitzaktion(neuesEtui, stifteAufsMal)
        if (aktGriffe < kuerzesteSpitzaktion):
            kuerzesteSpitzaktion = aktGriffe
        if (aktGriffe > laengsteSpitzaktion):
            laengsteSpitzaktion = aktGriffe
        totalVersucheAllerSpitzaktionen += aktGriffe
        versuchsNummer +=1

    print 'Total Anzahl Spitzaktionen (3 Stifte): '+str(totalVersucheAllerSpitzaktionen)
    print 'Kuerzeste Spitzaktion: '+str(kuerzesteSpitzaktion)
    print 'Laengste Spitzaktion: '+str(laengsteSpitzaktion)


# 20 Stifte, 3 werden gezogen, 10000 Wiederholungen
farbstiftSpitzAktion(20,3,100000)
                
const NUMBER_OF_CRAYONS = 20,
      NUMBER_OF_TAKES = 3;

Array.prototype.max = function() { return Math.max.apply(null, this); }
Array.prototype.min = function() { return Math.min.apply(null, this); }
Array.prototype.avg = function() { return this.reduce((a, b) => a + b, 0) / this.length; }

let pencilCase = [];
// buntstifte initialisieren
// false = ungespitzt, true = angespitzt
pencilCase.reset = function() {
  for (let i = 0; i < NUMBER_OF_CRAYONS; i++)
    pencilCase[i] = false;
}


// anspitz-prozedur
function sharpenSome() {
  // zufällige stifte wählen
  let rndCrayons = [];
  while (rndCrayons.length < NUMBER_OF_TAKES) {
    let x = Math.floor(Math.random() * NUMBER_OF_CRAYONS);
    if (rndCrayons.indexOf(x) == -1) rndCrayons.push(x);
  }
  // buntstifte spitzen
  // könnte stark verkürzt werden, ich lass es aber mal so, der
  // lesbarkeit zuliebe
  for (let i = 0; i < rndCrayons.length; i++) {
    x = rndCrayons[i];
    if (pencilCase[x] == false) pencilCase[x] = true;
  }
}

// spitzen, bis alle spitz sind
function sharpenAll() {
  let counter = 0;
  pencilCase.reset();
  while (pencilCase.indexOf(false) != -1) {
    sharpenSome();
    counter++;
  }
  return counter;
}

// testreihe
let records = [];
for (let i = 1; i <= 1e4; i++) records.push(sharpenAll());

// ausgabe
console.log(`Durchschnittliche Anzahl der Durchgänge: ${records.avg().toFixed(1)}`);
console.log(`Kleinste Anzahl der Durchgänge: ${records.min()}`);
console.log(`Höchste Anzahl der Durchgänge: ${records.max()}`); 
                                                             // lissalanda@gmx.at

                

Lösung von: Lisa Salander (Heidi-Klum-Gymnasium Bottrop)

// C++ 20 | VS-2022
#include <iostream>
#include <random>
#include <array>
#include <algorithm>
#include <tuple>
#include <numeric>

constexpr size_t NUM_OF_PENCILS{ 20 };
constexpr size_t NUM_OF_PICK_OUT{ 3 };
constexpr size_t NUM_OF_TESTS{ 100'000 };

inline const auto get_attempts() {
    std::array<bool, NUM_OF_PENCILS>arr{};
    auto counter{ 0 };
    while (!std::all_of(arr.begin(), arr.end(), [](auto x) {return x == true; })) {
        ++counter;
        std::shuffle(arr.begin(), arr.end(), std::random_device());
        for (auto it{ arr.begin() }; it < arr.begin() + NUM_OF_PICK_OUT; ++it) *it = true;
    }
    return counter;
}

inline const auto get_test_results() {
    size_t min{ INT_MAX };
    size_t max{ 0 };
    size_t sum{ 0 };

    for (size_t i{ 0 }; i < NUM_OF_TESTS; ++i) {
        const auto res{ get_attempts() };
        sum += res;
        if (res < min) min = res;
        if (res > max) max = res;
    }
    const double avg{ (double)sum / NUM_OF_TESTS };
    return std::make_tuple(min, max, avg);
}

int main() {
    const auto& [min, max, avg] = get_test_results(); // C++ 20!
    std::cout <<"Minimum: " << min << "\n";
    std::cout <<"Maximum: " << max << "\n";
    std::cout <<"Mittelwert: " << avg << "\n";
}
                

Lösung von: Jens Kelm (@JKooP)

// NET 7.x | C# 11.x | VS-2022
const int NUM_OF_PENCILS = 20;
const int NUM_OF_PICK_OUT = 3;
const int NUM_OF_TESTS = 10_000;

var (min, max, avg) = GetTestResults();
Console.WriteLine($"Minimum: {min}\n");
Console.WriteLine($"Maximum: {max}\n");
Console.WriteLine($"Mittelwert: {avg}\n");

int GetAttempts() {
    var rnd = new Random();
    var lst = new List<bool>(new bool[NUM_OF_PENCILS]);
    var counter = 0;
    while(!lst.All(x => x)) {
        ++counter;
        lst = lst.OrderBy(x => rnd.Next()).ToList();
        for (int i = 0; i < NUM_OF_PICK_OUT; i++)
            lst[i] = true;
    }
    return counter;
}

(int, int, double) GetTestResults() {
    var min = int.MaxValue;
    var max = 0;
    var sum = 0;
    for (int i = 0; i < NUM_OF_TESTS; i++) {
        var res = GetAttempts();
        sum += res;
        if (res < min) min = res;
        if (res > max) max = res;
    }
    var avg = (double)sum / NUM_OF_TESTS;
    return (min, max, avg);
}
                

Lösung von: Jens Kelm (@JKooP)

Verifikation/Checksumme:

Bei 10 000 Spitzaktionen, 20 Stiften und 3 Stiften pro "blindem Griff" ergeben sich in etwa die folgenden Zahlen für die Anzahl Griffe:

Mittelwert: 23.05 +/- 0.05

Minimum: 7 (mathematisch), meist 8 oder 9

Maximum: ca. 65 bis 100; mathematisch gibt es keine(!) Obergrenze.

Aktionen

Bewertung

Durchschnittliche Bewertung:

Eigene Bewertung:
Bitte zuerst anmelden

Meta

Zeit: 2
Schwierigkeit: k.A.
Webcode: i7ox-fcxf
Autor: Stefan Dürrenberger (IDM Studios GmbH)

Download PDF

Download ZIP

Zu Aufgabenblatt hinzufügen