შემთხვევითი რიცხვების გენერატორი. უბედური შემთხვევა, დამთხვევა, ნიმუში. შემთხვევითი რიცხვების გენერატორი 1c შემთხვევითი რიცხვი

სტატია მხოლოდ ამ ძახილით არ დავიწყე. ეს მოხდა, პროგრამისტს აქვს მოსახერხებელი ინსტრუმენტი თავის არსენალში, რომელიც საშუალებას აძლევს მას მიიღოს შემთხვევითი რიცხვი მოცემულ ინტერვალში. სხვა პროგრამირების ენების სტანდარტული ფუნქციები ქმნიან წილად რიცხვს 0-დან 1-მდე დიაპაზონში. ეს არ არის ძალიან მოსახერხებელი რიცხვი გამოსაყენებლად; თქვენ უნდა იმუშაოთ ზედმეტი იმისთვის, რომ მიიღოთ შემთხვევითი მიმდევრობა მოცემულ დიაპაზონში, მაგალითად, 1-დან 5-მდე.

მოსახერხებელი ხელსაწყო უნდა შემოწმდეს, ხშირად RNG არ არის ძალიან მაღალი ხარისხის და თქვენ დამატებით უნდა ივარჯიშოთ მათემატიკაში, რათა გაზარდოთ გენერირებული რიცხვების შემთხვევითობა, რათა თავიდან აიცილოთ ცუდად შერეული ფსევდო-მიმდევრობა. ჩვენ ხშირად ვენდობით შემთხვევით რიცხვებს საიდუმლოებით, ფინანსური რესურსებით, გართობით, მოდელირებით, კრიტიკული ავტომატური კონტროლის სისტემების ტესტირებით, სატესტო პროგრამებით, ამიტომ ძალიან მნიშვნელოვანია გვქონდეს სერიების უნიკალური თანმიმდევრობა სხვადასხვა სპეციფიკური მახასიათებლებით მნიშვნელობის ინტერვალებიდან ხარისხამდე. მიმდევრობითი რიცხვების შერევა.

ნება მომეცით მოგიყვანოთ წარუმატებელი შემთხვევითი რიცხვების წარმოქმნის მაგალითი. ჯერ კიდევ 1993 წელს, როდესაც არაფერადი VGA მონიტორი 640x480 გარჩევადობით კარგად ითვლებოდა და პროგრამისტების თვალი ნაკლებად ეცალა, Paradox DBMS ფართოდ იყო გავრცელებული. Borland International-ის გაუმაძღარმა ადამიანებმა გადაწყვიტეს მეტი ფულის გამომუშავება და ქსელში წვდომისთვის მოითხოვეს 10 ციფრისგან შემდგარი გასაღები. რაც უფრო მეტ კლავიშს შეიყვანთ, მით მეტ მომხმარებელს შეუძლია ერთდროულად დაუკავშირდეს მონაცემთა ბაზას.

ახლა დავიწყებ ჩემი წარმატებებით ამაყობას :). სხვადასხვა გზით 3 კლავიში მომივიდა და მივხვდი, რომ თანმიმდევრობა იყო ფსევდო შემთხვევითი და ცუდად შერეული. ყოველგვარი ტექნოლოგიის, რთული გამოთვლების და თუნდაც კალკულატორის გარეშე მოვახერხე ამ კლავიშების ნებისმიერი რაოდენობის აყვანა. რა თქმა უნდა, Borland კომპანიას დიდი ზარალი არ განუცდია, მაგრამ რადგან უკვე დაცვით ხართ დაკავებული, მაშინ კარგად გააკეთეთ, ან ნუ დაკარგავთ დროს უსარგებლო სამუშაოზე. ამისგან მორალს არ გამოვიყვან, იმედი მაქვს უფრო ნათელი გახდება, რომ RNG მნიშვნელოვანი საკითხია.

ფსევდო შემთხვევითი თანმიმდევრობების დასაცავად, მე ვიტყვი, რომ ზოგჯერ ისინი აუცილებელია, მაგალითად, როდესაც უსაფრთხოების გასაღები გამოითვლება ფორმულის გამოყენებით და პროგრამა გადაწყვეტს წარმატებით გადაამოწმოს გასაღები ლოკალურ რეჟიმში. 1993 წელს ინტერნეტი არ იყო ფართოდ გავრცელებული და პროგრამისტებს უნდა შეექმნათ თანმიმდევრობის ალგორითმები მესამე მხარის სერვერებზე მათი ტესტირების გარეშე. მაგრამ აუცილებლად კარგად აურიეთ. ქსელების თანამედროვე განვითარებით შესაძლებელი გახდა როგორც პროგრამების, ასევე აღჭურვილობის სერიული ნომრის გადამოწმება ვერიფიკაციის სერვერების გამოყენებით. ამ სისტემამ მნიშვნელოვნად გაზარდა გაყალბების წინააღმდეგობა, მაგრამ საიდუმლო არ არის, რომ ამის მიუხედავად, პროგრამული უზრუნველყოფის უნებართვო გამოყენება მაინც ხდება.

დასკვნა ასეთია: საკეტები და ყაბზობა პატიოსანი ხალხის მიერ არის დამონტაჟებული.

1C პლატფორმაზე ობიექტის მოქმედება უკიდურესად მარტივია, თუმცა არის გარკვეული თავისებურებები.

RNG = NewRandomNumberGenerator(ინიციალიზაცია); //აქ შეგიძლიათ შეცვალოთ შემთხვევითი რიცხვების გენერატორის მოქმედება, რიცხვის ინიციალიზაციის შეცვლა სხვადასხვა შედეგებს იძლევა. Return RNG.RandomNumber(1, SettingsOption);

თუ არ მიუთითებთ ინიციალიზაციას, მაშინ თანმიმდევრობები წარმოიქმნება შემთხვევით, საკუთარი თავის ინიციალიზებით. მოცემული ინიციალიზაციის ნომერი უბრუნებს პროგნოზირებად თანმიმდევრობას, რომელიც ზოგჯერ აუცილებელი და სასარგებლოა. და თუ ყოველ ჯერზე მიუთითებთ სხვადასხვა რიცხვს, მიიღებთ რიცხვების თანმიმდევრობის ძალიან კარგ შერევას.

შემთხვევითი რიცხვების გენერატორის ფუნქციონირების შესასწავლად 1C-ში, შევქმენი რამდენიმე მკურნალობა და კიდევ ერთი საინტერესო გავხადო თამაშის სახით, მაგრამ თამაში მოგვიანებით, ჯერ ბიზნესი.

გენერირებული იყო 500 შემთხვევითი რიცხვი, 0-დან 10000-მდე დიაპაზონში, გენერატორი მუდმივად ინიციალიზებულია CurrentUniversalDateInMilliseconds() ფუნქციით. დიაგრამა აჩვენებს მნიშვნელობების კარგ განაწილებას. ლამაზი ნიმუში. Y ღერძზე არის რიცხვის მნიშვნელობა, X ღერძზე არის გამეორების ნომერი.

ქულების პოზიციები საკმაოდ მწირია, ისინი თითქმის არ ებმებიან ერთმანეთს, რაც ძალიან კარგია, რაც იმას ნიშნავს, რომ გენერირებული რიცხვები ძალიან მრავალფეროვანია.

მოდით ხელოვნურად შევქმნათ დიაგრამის ცუდი ვერსია:

კარგი თაობის შემთხვევაში ასე არ უნდა იყოს.

შემთხვევითი რიცხვების გენერატორის პარამეტრები ძალიან მნიშვნელოვანი წერტილია. რამდენიმე მათგანია, მაგრამ ყველაფერი მათზეა დამოკიდებული.

ამ პარამეტრით იქმნება 500 რიცხვის თანმიმდევრობა 0-დან 10000-მდე დიაპაზონში და გენერატორი მუდმივად ინიციალიზდება ახალი რიცხვით.

მოდით გადავხედოთ გენერირებულ მნიშვნელობების ცხრილს, მანამდე დაალაგეთ იგი მნიშვნელობების მიხედვით, რათა ვნახოთ არის თუ არა გენერატორის მიერ გაცემული განმეორებითი რიცხვები.

დალაგებული სიის სწრაფმა ვიზუალურმა შემოწმებამ აჩვენა, რომ იყო გამეორებები, თუმცა მათი განხორციელების ალბათობა დაბალი იყო. რიცხვების ფართო დიაპაზონი იყო მითითებული გენერირებისთვის, მაგრამ მე-10 და 30 საფეხურზე რიცხვები განმეორდა.

ჩვენ ვასკვნით: შემთხვევითი რიცხვების გენერატორი ობიექტს შეუძლია განმეორებადი რიცხვების გენერირება.

ეს ზოგჯერ მიუღებელია. მაგალითად, ჩვენ ვქმნით შემთხვევით დოკუმენტის ნომერს, არათანმიმდევრულად, რათა შევატყობინოთ მომხმარებელს, რომელსაც შეუძლია გახსნას კონკრეტული დოკუმენტი. ამ შემთხვევაში გამეორება მიუღებელია, წინააღმდეგ შემთხვევაში გამეორებისას გაურკვეველი იქნება რომელი დოკუმენტი უნდა გაიხსნას.

რატომ არის საჭირო შემთხვევითი ნუმერაცია? ვთქვათ, ჩვენ გავცემთ ჩვენი პარტნიორების დოკუმენტის ნომრებს სარემონტოდ გადაცემული აღჭურვილობისთვის. თქვენ შეგიძლიათ გასცეთ უწყვეტი თანმიმდევრული ნუმერაციის ნომრები, მაგრამ კლიენტს, რომელსაც აქვს ერთი ნომერი, შეუძლია დაათვალიეროს მინიმუმ მეზობლები და იცის ნუმერაციის ინტერვალი, შეუძლია ნახოს ყველა დოკუმენტი. მოცემულ მაგალითში ეს არ არის ისეთი საიდუმლო, მაგრამ ზოგჯერ საჭიროა სხვა დოკუმენტებიდან ინფორმაციის საიდუმლოდ შენახვა.

გენერირების რიცხვის მნიშვნელობების დიდი ინტერვალებით, მოვლენების განმეორების ალბათობა მცირდება, მაგრამ თუ მოვლენა შეიძლება მოხდეს, მაშინ ის აუცილებლად მოხდება.

გამოსავალი შეიძლება იყოს გენერირებული რიცხვის უნიკალურობის შემოწმება, მაგრამ ძალიან გრძელი თანმიმდევრობისთვის ამას დიდი დრო დასჭირდება. ჩვენ უნდა ვიფიქროთ უფრო რთულ შერევაზე, მაგრამ ეს უფრო საინტერესოს ხდის ამოცანას ;).

დიაგრამაში მნიშვნელობების ჩვენებისას, დამუშავება იწყებს შესამჩნევად შენელებას, ჩემს კომპიუტერში 1000 მნიშვნელობის დამატების შემდეგ, ასე რომ, პარამეტრებში არის ჩამრთველი "ნუ გენერირება დიაგრამა". ინსტალაციისას, მუშაობის სიჩქარე მნიშვნელოვნად იზრდება გრძელი მიმდევრობების გენერირებისას, ამიტომ კვლევისას ფრთხილად იყავით გენერირებული რიცხვების რაოდენობის დაყენებისას.

გენერატორს შეიძლება მიეცეს კონკრეტული ინიციალიზაციის მნიშვნელობა, შემდეგ რამდენჯერაც არ უნდა დააჭიროთ გენერირებას, შედეგი იგივე იქნება. როდესაც დამუშავების ველი "RNG ინიციალიზაციის ნომერი" დაყენებულია 0-ზე, ფსევდო შემთხვევითი ინიციალიზაცია ხდება რიცხვების თანმიმდევრობის გენერირებისას.

გენერატორის სიჩქარე კარგია, მაგალითად, 100 000 ნომერი შეიქმნა 0,5 წამზე ნაკლებ დროში.

მე გაჩვენებთ RNG გამოყენების მაგალითს რიცხვების მცირე დიაპაზონზე თამაშის მაგალითზე Rock, Paper, Scissors.

წესები მარტივია: ორი მოთამაშე აჩვენებს მითითებულ ობიექტებს ჟესტებით. ვისაც ამ მომენტში ძლიერი ფიგურა აქვს, იმარჯვებს.

როკმა დაამარცხა მაკრატელი.

მაკრატელი სცემს ქაღალდს.

ქაღალდი ამარცხებს სტოუნს.

ამ ვარიანტში ყველაფერი ექვივალენტურია და გამარჯვების შანსიც იგივეა.

99 თამაშის შემდეგ, თითოეულ ფიგურაზე დავაწკაპუნე იგივე რაოდენობა, 33-ჯერ, ეს ჩანს ქვედა მარჯვენა დიაგრამაზე. კომპიუტერი ჩემზე ხშირად იმარჯვებდა, რაც ცოტა გულდასაწყვეტი იყო. კომპიუტერი უფრო ხშირად იყენებდა ქაღალდს, როგორც ეს ჩანს ქვედა მარცხენა დიაგრამაში. შუაში არსებული გრაფიკი აჩვენებს, რომ მე არ ვიყავი გამარჯვებული. კომპიუტერის მოგების წითელი გრაფიკი უფრო მაღალია ვიდრე მწვანე (ჩემი მოგება).

სცადე ბედი! მიუხედავად ნაჭრების დაცემის იგივე ალბათობისა, შედეგი ყოველთვის განსხვავებულია.

თამაშის სტატისტიკა ნაჩვენებია შუაში, ზედა ელემენტების ვარდისფერ ჯგუფში.

მაუსის ღილაკზე ერთხელ დაჭერით, შეგიძლიათ გამოიყენოთ კლავიატურაზე არსებული ნომრები (და არა დამატებითი) სასურველი ფიგურის ასარჩევად. ღილაკების დაჭერით შეგიძლიათ მონაცემების შეყვანა ცოტა უფრო სწრაფად, განსაკუთრებით თუ სტატისტიკის დასაგროვებლად უაზრო თამაშების თამაში გჭირდებათ.

მოდით გავართულოთ თამაში. მოდით დავამატოთ ჭა კლასიკურ ფიგურებს.

როკმა დაამარცხა მაკრატელი.

მაკრატელი სცემს ქაღალდს.

ქაღალდი ამარცხებს როკ და კარგად.

კარგად ამარცხებს Rock and Scissors-ს.

ამ ვარიანტში ფიგურების არათანაბარი ღირებულება ჩნდება და თეორიულად უფრო მეტი შანსია მოიგოთ ქაღალდისა და ჭალის არჩევით, რადგან მათ არსენალში შეუძლიათ ორი თანამოაზრის დამარცხება. მოდით შევამოწმოთ პრაქტიკაში:

მხოლოდ ძლიერ ფიგურებზე დავაწკაპუნე და გავიმარჯვე. თეორია პრაქტიკამ დაადასტურა.

მხოლოდ სუსტ ნაწილებზე დაწკაპუნებამ შედეგი გამოიღო, დავკარგე.

თამაშის კიდევ უფრო რთული ვერსია არის მეხუთე ნაწილის, ცეცხლის შესავალი.

როკი ამარცხებს სკისორსს და კარგად აგებს ქაღალდსა და ცეცხლს.

მაკრატელი ამარცხებს ქაღალდს და ცეცხლი წააგებს Rock and Well-თან.

ქაღალდი ამარცხებს როკს და კარგად კარგავს ცეცხლი და მაკრატელი.

კარგად ამარცხებს ცეცხლი და მაკრატელი კარგავს Rock and Paper-თან.

ცეცხლი ამარცხებს ქაღალდს და კლდე კარგავს მაკრატელთან და ჭასთან.

ამ ვარიანტში ფიგურები თანაბარია, მაგრამ ორი იგებს და აგებს, ეს მატებს გარკვეულ ინტრიგას და ამცირებს ფრეების ალბათობას.

ჩემი დაწკაპუნებები ქაოტური იყო და კომპიუტერმა ისევ დამამარცხა. თამაშის დროს ხედავთ, რომელ ნაწილს იყენებს კომპიუტერი უფრო ხშირად; ამ ინფორმაციის საფუძველზე შეგიძლიათ სცადოთ არა ქაოტურად, არამედ გააზრებულად თამაში და შესაძლოა გაზარდოთ თქვენი წარმატების შანსები.

შემთხვევითი რიცხვების გენერატორის დაყენებას აქვს საკუთარი მახასიათებლები. როდესაც დროშა "არ გამოიყენო მომხმარებლის პასუხი" წაშლილია, მოთამაშის მიერ დაჭერილი კლავიშის ნომერი გამოიყენება RNG-ის ინიციალიზაციისას, რაც შემთხვევითობას მატებს თაობას. ადამიანი შემთხვევითი რიცხვების შესანიშნავი გენერატორია, მაგრამ მაინც ტვინს აქვს ფსევდო-მიმდევრობაც. თუ ადამიანს აიძულებთ კლავიშების 100 დაჭერას, მაშინ ეს პროცედურა შეიძლება შესრულდეს კეთილსინდისიერად, რაც შეიძლება მეტი სხვადასხვა ღილაკის დაჭერით, ან უყურადღებოდ, მხოლოდ ერთი ღილაკის დაჭერით. როდესაც ეს დროშა დაყენებულია, მუშაობს მხოლოდ კომპიუტერის არევა.

პირისგან შემთხვევითი თანმიმდევრობის მიღებისას, მაგალითად, ელექტრონული ხელმოწერის გასაღების შესაქმნელად, მიზანშეწონილია გავითვალისწინოთ არა მხოლოდ დაჭერილი გასაღები, არამედ დაჭერებს შორის ინტერვალიც. ეს ძალიან შემთხვევითი ინფორმაციაა, თუმცა კარგ მუსიკოსს შეუძლია რამდენჯერმე წარმოქმნას ერთი და იგივე თანმიმდევრობა.

"არ გამოიყენო RNG ინიციალიზაცია" დროშა ჩართავს/გამორთავს ინიციალიზაციის რეჟიმს. თუ შემთხვევითი რიცხვების გენერატორის ობიექტის შექმნისას არ მიუთითებთ ინიციალიზაციას, მაშინ წარმოიქმნება შერეული თანმიმდევრობა, როგორც მივხვდი, ჩართულია რაიმე სახის ინიციალიზაცია, რომელიც საკმაოდ ეფექტური მომეჩვენა.

RNG = NewRandomNumberGenerator();

ასევე, დამუშავების დროს, შეგიძლიათ დააყენოთ თქვენი საკუთარი ინიციალიზაციის ნომერი, შემდეგ იგივე რიცხვი პროგნოზირებულად გენერირებულია.

მოგების გამოთვლის პროცედურის დაწერისას, შედეგის აღწერის პრობლემას წავაწყდი, განსაკუთრებით ხუთფიგურიანი თამაშისთვის. მას შემდეგ რაც გავარკვიე, მივხვდი, რომ ბევრი ასო იქნებოდა, რადგან ბევრი ვარიანტია ამდენი ფორმის მქონე. კომბინატორიკა გვეუბნება, რომ სამი ფიგურით გვაქვს მაქსიმუმ 9 ვარიანტი, ოთხი 16 ვარიანტით და ხუთი 25 ვარიანტით. გათამაშების უგულებელყოფა, სწორედ მაშინ, როდესაც აირჩევა იგივე ფიგურა, მივხვდი, რომ პირობების 19 ვარიანტის დაწერა მომიწევდა.

ვფიქრობდი ამაზე, რადგან ეს აშკარად გამოიწვევდა ცუდად წასაკითხ კოდს და ვიპოვე ის, რაც ვფიქრობ, მშვენიერი გამოსავალია. სულ 9 პირობით.

Res = მოთამაშე - კომპ; თუ SettingsOption = 3 მაშინ If (Res = -1) OR (Res = 2) მაშინ დააბრუნეთ 1; //გაიმარჯვეთ წინააღმდეგ შემთხვევაში დაბრუნდით 2; //დამარცხება EndIf; ElseIfSettingsOption = 4 შემდეგ თუ (Res = -1) OR (Res = 2) OR (Res = 3) შემდეგ დააბრუნეთ 1; //გაიმარჯვეთ წინააღმდეგ შემთხვევაში დაბრუნდით 2; //დამარცხება EndIf; ElseIf Settings Option = 5 After If (Res = -1) OR (Res = 2) OR (Res = -3) OR (Res = 4) then Return 1; //გაიმარჯვეთ წინააღმდეგ შემთხვევაში დაბრუნდით 2; //დამარცხება EndIf; დაასრულე თუ;

კომპაქტური, ნათელი, მარტივი რედაქტირება.

მე მივხვდი, რომ თითოეულ ფიგურას აქვს თავისი ნომერი: 1 - ქვა, 2 - მაკრატელი, 3 - ქაღალდი, 4 - კარგად, 5 - ცეცხლი. თამაშის შედეგად ვიანგარიშებ სხვაობას ფიგურების რაოდენობას შორის და ეს სხვაობა ნათელ პასუხს მაძლევს კითხვაზე, ვინ მოიგო.

დამუშავება, რომელიც ეხმარება მართული აპლიკაციისთვის შემთხვევითი მიმდევრობების თვისებების შესწავლას და იწერება კონფიგურაციის მითითების გარეშე. ტესტირება პლატფორმაზე 8.3.10, 8.3.11 თინ კლიენტზე.

ამ სტატიით იმედი მქონდა გადმომეცა შემთხვევითი რიცხვების მიმდევრობის გენერირების მნიშვნელობა და სერიოზულობა.

21
//ფუნქცია წარმოქმნის მნიშვნელობების ადვილად წასაკითხ წარმოდგენას. // რიცხვის ფორმატირების მაგალითები ValueFormat = Format(123456.789, " NRT=10; NRT=2"); //ValueFormat = "123,456.79"ValueFormat = ფორმატი(123456.789, "HH=0; NHV=2"); //ღირებულება 16
სრული ტექსტის ძიება - საშუალებას მოგცემთ იპოვოთ ტექსტური ინფორმაცია გამოყენებული კონფიგურაციის თითქმის ნებისმიერ ადგილას. ამ შემთხვევაში, თქვენ შეგიძლიათ მოძებნოთ საჭირო მონაცემები ან მთლიანი კონფიგურაციის განმავლობაში, ან შევიწროებით... 8
„დროის წერტილი“ არის ვირტუალური ველი, რომელიც არ ინახება მონაცემთა ბაზაში. შეიცავს Point in Time ობიექტს (რომელიც მოიცავს თარიღს და დოკუმენტის ბმულს) 7.7-ში იყო Document Position კონცეფცია, ხოლო 8.x Point in Time To მისაღებად... 6
8.x FindByLinks-ისთვის (FindDataByRef) სინტაქსი: FindByLinks (ბმულების სია) პარამეტრები: საჭირო ბმულების სია ტიპი: მასივი. მასივი ობიექტების ბმულების სიით, რომელთა ბმულების პოვნაც საჭიროა. ...


საკვანძო სიტყვები: გენერატორი, შემთხვევითი, რიცხვები, რიცხვი, ალგორითმი, შემთხვევითი, რანდომიზება, განაწილება, უნიფორმა, ლატარია

არ მეგონა, რომ 1C-ში გამოგადგებათ, მაგრამ აი, თქვენ... კლიენტებმა გადაწყვიტეს გამართონ აქცია, როგორიცაა "აკრიფეთ ქუდები", მხოლოდ თქვენ გჭირდებათ სიტყვების შეგროვება, ვინც აგროვებს სწორ სიტყვას მათი ნაკრებიდან. ასოები იმარჯვებს. ზოგადად, ამოცანა მარტივი ჩანდა: არის ანბანი, არის გარკვეული სიტყვა, რომელიც უნდა შეგროვდეს, მაგალითად "კონიაკი", მას აქვს 6 ასო, როგორც ხედავთ.

თქვენ უნდა: შექმნათ შემთხვევითი ექვსასოიანი კომბინაციების გარკვეული რაოდენობა ანბანის ნებისმიერი ასოდან, დაამატეთ რამდენიმე ვარიანტი, რომლებშიც სიტყვა კვლავ შეიძლება დაემატოს, მაგალითად, "nkkoya" - სიტყვა იქმნება, მაგრამ "კავრი" აშკარად არ არის შესაფერისი.

დამატებითი პირობა: ყველა ეს ვარიანტი (სწორი და არა) უნდა იყოს დანომრილი, რათა „საპრიზო“ ბარათის მიღებისას შეძლოთ ნომერი (იყო თუ არა).

როგორც ჩანს, რა შუაშია 1C? ასე რომ, მათ სურთ ამ ბარათებისა და პრიზების აღრიცხვის დამატება ბუღალტრული აღრიცხვის პროგრამაში და ამავდროულად მოითხოვეს შემთხვევითი კომბინაციების გენერირება (კარგი, ხელით არ შედგენა).
ყოველი აქციისთვის კომბინაციები გენერირდება ერთხელ, შემდეგ მათზე დაყრდნობით კეთდება ბარათები, ე.ი. შემდეგ ჯერზე სიტყვა განსხვავებული იქნება და ა.შ.

ზოგადად, დავალება შემდეგნაირად იშლება:
1. შექმენით შემთხვევითი რიცხვები, სასურველია დიდი გავრცელებით.
2. რიცხვის გამოყენებით გამოთვალეთ ასოების კომბინაცია (ანუ იპოვეთ გარკვეული შესაბამისობა შესაძლო კომბინაციებსა და მათ რიცხვებს შორის).
3. წინა წერტილის საპირისპირო წერტილი - შეამოწმეთ კომბინაციის ნომერი სიტყვით.

გამოსავალი:
1. რადგან გენერატორმა avb-დან და NS-დან შემთხვევითი რიცხვების მცირე გავრცელება მისცა, მე მომიწია ოდნავ განსხვავებული ალგორითმის გამოყენება:

ფუნქცია Random() თუ ცარიელი მნიშვნელობა(randSeed) = 1 მაშინ randSeed = _getperformancecounter(); დაასრულე თუ; randSeed=(a*randSeed+c)%m; დააბრუნეთ randSeed; საბოლოო ფუნქცია

Აქ:
a=1664525; c=1013904223; m=4294967296;
ბოლო ცვლადი არის 2-დან 32-ე ხარისხამდე, დანარჩენი ორი არის ასეთი მიზნებისთვის რეკომენდებული კოეფიციენტები

მაქსიმალური მნიშვნელობის ლიმიტი 2^32 შეირჩა კომბინაციების მაქსიმალური რაოდენობის საფუძველზე (მოჭრილი ანბანისთვის 28 ასო და 7 სიტყვა, რადგან რეალურ პრობლემაში არის ზუსტად 7 მათგანი, კომბინაციების საერთო რაოდენობა იქნება 28 ^7, ამდენად, შერჩეული ლიმიტი დევს დაახლოებით შუა ინტერვალში, რაც სავსებით საკმარისია 20-30 ათასი ვარიანტის ნიმუშისთვის)

ჩვენ ასევე გვჭირდება კიდევ ერთი დამხმარე ფუნქცია - აწევა დადებით მთელ რიცხვამდე:

ფუნქციის ხარისხი(მნიშვნელობა a, მნიშვნელობა b, Res=1) თუ b>0 მაშინ Res=Res*a; b=b-1; ხარისხი (a,b,res); დაბრუნება Res; წინააღმდეგ შემთხვევაში Return Res; დაასრულე თუ; EndFunction

აქ: a - ხარისხის საფუძველი, b - მაჩვენებელი, Res - შედეგი

2. თანმიმდევრულ კომბინაციებს შორის ურთიერთობის დადგენა საოცრად მარტივი აღმოჩნდა:

რიგი ელემენტების თანმიმდევრობით დალაგების შემდეგ, მე გამოვავლინე სიმბოლოების განლაგების მსგავსება რიცხვთა სისტემასთან, მხოლოდ არა ათობითი, არამედ ამ შემთხვევაში "თექვსმეტობითი" (შედეგში "სიტყვის" სიმბოლოების რაოდენობით).
ამრიგად, კომბინაციის გამოთვლა მისი რიცხვით, საჭირო იყო მისი რიცხვის გადაყვანა სწორედ ამ რიცხვთა სისტემაში.

ჩვენი რიცხვითი სისტემისთვის საფუძველი იქნება ექვსის სიმძლავრე, ე.ი. მარცხნივ პირველი ციფრის მისაღებად, თქვენ უნდა გავყოთ ჩვენი კომბინაციის რიცხვი 6-ით მე-5 ხარისხამდე, შემდეგ გაყოფის დარჩენილი ნაწილი 6-ით მე-4 ხარისხამდე და ა.შ.

ამრიგად, ჩვენ ვიღებთ ექვსი რიცხვის კომპლექტს, რომლებიც არსებითად არის ჩვენი ანბანის ასოების სერიული ნომრები.

შედეგად მიღებული კოდი:

ფუნქცია GetCharacters (Pos,TechChar=1 ,SymStr="") თუ TechChar<к Тогда Делитель=Степень(СтрДлина(Буквы),к-ТекСимв); ТекОст=Поз%Делитель; СимСтр=Строка(СимСтр)+Сред(Буквы,Цел(Поз/Делитель+?(ТекОст>0 ,1 ,0 )),1 ); GetSymbols(TekOst,TekSymv+1,SymStr); დაბრუნება SimStr; წინააღმდეგ შემთხვევაში SimStr=SimStr+Average(Letters,(?(Pos=0 ,StrLength(Lets),Pos)),1 ); დაბრუნება SimStr; დაასრულე თუ; EndFunction

Აქ:
Pos - კომბინირებული ნომერი (ფსევდორანდომური რიცხვი)
TechSym - მიმდინარე სიმბოლო მუშავდება
SimStr - შედეგად მიღებული სიმბოლოების სტრიქონი
ასოები = სტრიქონი, რომელიც შეიცავს ანბანის ასოებს სტანდარტული თანმიმდევრობით ("abv...yuya")
k - სიმბოლოების რაოდენობა საძიებო სიტყვაში (ამ შემთხვევაში = 6)

3. საპირისპირო ტრანსფორმაცია ასევე ტრივიალურია:

ფუნქცია GetCombination(Word, TechCharacter=0 , Pos=0 ) NomCharacter=Find(ასოები, საშუალო(Word, to-TechCharacter, 1 )); თუ TechCym>0 მაშინ თუ TechSym<к Тогда Поз=Поз+(НомСимв-1 )*Степень(СтрДлина(Буквы),ТекСимв); ПолучитьКомбинацию(Слово,ТекСимв+1 ,Поз); Иначе Возврат Поз; КонецЕсли; Иначе Поз=?(НомСимв=СтрДлина(Буквы),0 ,НомСимв); ПолучитьКомбинацию(Слово,ТекСимв+1 ,Поз); Возврат Поз; КонецЕсли; КонецФункции

Აქ:
სიტყვა არის სიმბოლოების ერთობლიობა, რომელთა რიცხვსაც ჩვენ ვეძებთ
TekSymv - მიმდინარე სიმბოლოს დამუშავება (არსებითად თექვსმეტობითი "რიცხვის" ციფრი)
Pos - საჭირო კომბინაციის ნომერი

შეურიეთ N რიცხვი:

a=1-დან N მარყუჟის მასივისთვის[a]=a; ციკლის დასასრული; a=1-დან N-1 ციკლისთვის Cl=Case(a,N); // მთელი შემთხვევითი რიცხვი ინტერვალში [a..N] K=მასივი[a]; მასივი[a]=მასივი[Sl]; მასივი[Sl]=K; საბოლოო ციკლი;

Sc = CreateObject ("MSScriptControl.ScriptControl"); Sc.language = "VBscript"; sc.executeStatement("randomize"); ეს იქნება აქ = Sc.eval("rnd");

როგორ შევადგინო 1-დან 100-მდე შემთხვევით შერჩეული რიცხვები?

Rand=_GetPerformanceCounter()%(100 +1 );
როგორც ჩანს, ეს საუკეთესოა

ბიბლიოთეკის ხალიჩა. ფუნქციონირებს იქ, სადაც არის sl გენერატორი. ნომრები:
http://1c.proclub.ru/modules/mydownloads/personal.php?cid=92&lid=2688

8.0-ში შეგიძლიათ გამოიყენოთ ჩაშენებული GUID გენერატორი შემთხვევითი რიცხვების გენერირებისთვის.
აქ არის მარტივი ფუნქციის მაგალითი:

//მხოლოდ მთელი რიცხვებისთვისფუნქცია GetRandomNumber(Min,Max) //Randomize-ის ნაცვლად n = 1 By 100 Cycle Unique = New UniqueIdentifier; საბოლოო ციკლი; //GUID Unique = AbbrLP(New UniqueIdentifier) ​​გენერირება; //მხოლოდ ნომრების შენარჩუნებაუნიკალური = StrReplace(უნიკალური,"- ",""); უნიკალური = StrReplace (უნიკალური,"a ",""); უნიკალური = StrReplace (უნიკალური,"b ",""); უნიკალური = StrReplace(უნიკალური,"c ",""); უნიკალური = StrReplace (უნიკალური,"d ",""); უნიკალური = StrReplace(უნიკალური,"e ",""); უნიკალური = StrReplace (უნიკალური,"f ",""); //მნიშვნელს უნდა ჰქონდეს ნულების იგივე რაოდენობა + 1მნიშვნელი = 10 ; n = 2-ისთვის (StrLength(StrReplace(Unique,Characters.NPP,""))) ციკლის მნიშვნელი = მნიშვნელი * 10 ; საბოლოო ციკლი; საქმე = ნომერი(უნიკალური) / მნიშვნელი; //აქ ვიღებთ წილადობრივ შემთხვევით რიცხვს 0-დან 1-მდე //გადაიყვანეთ შემთხვევით რიცხვად მოცემული ინტერვალიდან, დაამრგვალეთ უახლოეს მთელ რიცხვამდე NumberOfInterval = Min(Max(Ab(Min + (Max-Min)*Rand),Min),Max); დაბრუნება NumberFromInterval; EndFunction

სისტემის კიდევ ერთი ვარიანტი:
Rnd = CreateObject ("System.Random"); ანგარიში (Rnd.Next());

საკვანძო სიტყვები: გენერატორი, შემთხვევითი, რიცხვები, რიცხვი, ალგორითმი, შემთხვევითი, რანდომიზება, განაწილება, უნიფორმა, ლატარია

არ მეგონა, რომ 1C-ში გამოგადგებათ, მაგრამ თქვენთვის... კლიენტებმა გადაწყვიტეს აქციის გამართვა, როგორიცაა „შეაგროვეთ ქუდები“, მხოლოდ თქვენ გჭირდებათ სიტყვების შეგროვება, ვინც აგროვებს სწორ სიტყვას მათი ასოების ნაკრებიდან. იგებს. ზოგადად, ამოცანა მარტივი ჩანდა: არის ანბანი, არის გარკვეული სიტყვა, რომელიც უნდა შეგროვდეს, მაგალითად "კონიაკი", მას აქვს 6 ასო, როგორც ხედავთ.

თქვენ უნდა: შექმნათ შემთხვევითი ექვსასოიანი კომბინაციების გარკვეული რაოდენობა ანბანის ნებისმიერი ასოდან, დაამატეთ რამდენიმე ვარიანტი, რომლებშიც სიტყვა კვლავ შეიძლება დაემატოს, მაგალითად, "nkkoya" - სიტყვა იქმნება, მაგრამ "კავრი" აშკარად არ არის შესაფერისი.

დამატებითი პირობა: ყველა ეს ვარიანტი (სწორი და არა) უნდა იყოს დანომრილი, რათა „საპრიზო“ ბარათის მიღებისას შეძლოთ ნომერი (იყო თუ არა).

როგორც ჩანს, რა შუაშია 1C? ასე რომ, მათ სურთ ამ ბარათებისა და პრიზების აღრიცხვის დამატება ბუღალტრული აღრიცხვის პროგრამაში და ამავდროულად მოითხოვეს შემთხვევითი კომბინაციების გენერირება (კარგი, ხელით არ შედგენა).
ყოველი აქციისთვის კომბინაციები გენერირდება ერთხელ, შემდეგ მათზე დაყრდნობით კეთდება ბარათები, ე.ი. შემდეგ ჯერზე სიტყვა განსხვავებული იქნება და ა.შ.

ზოგადად, დავალება შემდეგნაირად იშლება:
1. შექმენით შემთხვევითი რიცხვები, სასურველია დიდი გავრცელებით.
2. რიცხვის გამოყენებით გამოთვალეთ ასოების კომბინაცია (ანუ იპოვეთ გარკვეული შესაბამისობა შესაძლო კომბინაციებსა და მათ რიცხვებს შორის).
3. წინა წერტილის საპირისპირო წერტილი - შეამოწმეთ კომბინაციის ნომერი სიტყვით.

გამოსავალი:
1. რადგან გენერატორმა avb-დან და NS-დან შემთხვევითი რიცხვების მცირე გავრცელება მისცა, მე მომიწია ოდნავ განსხვავებული ალგორითმის გამოყენება:

ფუნქცია შემთხვევითი ()
თუ ცარიელი მნიშვნელობა(randSeed) = 1 მაშინ
randSeed = _getperformancecounter();
დაასრულე თუ;

RandSeed=(a*randSeed+c)%m;
დააბრუნეთ randSeed;
საბოლოო ფუნქცია

Აქ:
a=1664525; c=1013904223; m=4294967296;
ბოლო ცვლადი არის 2-დან 32-ე ხარისხამდე, დანარჩენი ორი არის ასეთი მიზნებისთვის რეკომენდებული კოეფიციენტები

მაქსიმალური მნიშვნელობის ლიმიტი 2^32 შეირჩა კომბინაციების მაქსიმალური რაოდენობის საფუძველზე (მოჭრილი ანბანისთვის 28 ასო და 7 სიტყვა, რადგან რეალურ პრობლემაში არის ზუსტად 7 მათგანი, კომბინაციების საერთო რაოდენობა იქნება 28 ^7, ამდენად, შერჩეული ლიმიტი დევს დაახლოებით შუა ინტერვალში, რაც სავსებით საკმარისია 20-30 ათასი ვარიანტის ნიმუშისთვის)

ჩვენ ასევე გვჭირდება კიდევ ერთი დამხმარე ფუნქცია - აწევა დადებით მთელ რიცხვამდე:

ფუნქციის ხარისხი (მნიშვნელობა a, მნიშვნელობა b, Res=1)
თუ b>0 მაშინ
რეს=რეს*ა;
b=b-1;
ხარისხი (a,b,res);
დაბრუნება Res;
წინააღმდეგ შემთხვევაში
დაბრუნება Res;
დაასრულე თუ;
EndFunction

აქ: a - ხარისხის საფუძველი, b - მაჩვენებელი, Res - შედეგი

2. თანმიმდევრულ კომბინაციებს შორის ურთიერთობის დადგენა საოცრად მარტივი აღმოჩნდა:

რიგი ელემენტების თანმიმდევრობით დალაგების შემდეგ, მე გამოვავლინე სიმბოლოების განლაგების მსგავსება რიცხვთა სისტემასთან, მხოლოდ არა ათობითი, არამედ ამ შემთხვევაში "თექვსმეტობითი" (შედეგში "სიტყვის" სიმბოლოების რაოდენობით).
ამრიგად, კომბინაციის გამოთვლა მისი რიცხვით, საჭირო იყო მისი რიცხვის გადაყვანა სწორედ ამ რიცხვთა სისტემაში.

ჩვენი რიცხვითი სისტემისთვის საფუძველი იქნება ექვსის სიმძლავრე, ე.ი. მარცხნივ პირველი ციფრის მისაღებად, თქვენ უნდა გავყოთ ჩვენი კომბინაციის რიცხვი 6-ით მე-5 ხარისხამდე, შემდეგ გაყოფის დარჩენილი ნაწილი 6-ით მე-4 ხარისხამდე და ა.შ.

ამრიგად, ჩვენ ვიღებთ ექვსი რიცხვის კომპლექტს, რომლებიც არსებითად არის ჩვენი ანბანის ასოების სერიული ნომრები.

შედეგად მიღებული კოდი:

ფუნქცია GetCharacters (Pos,TexCharacter=1,SymStr="")
თუ TekSymv Divisor=Degree(StrLength(Letter),k-TekSymv);
TechOst=Pos%Divider;
SimStr=სტრიქონი(SimStr)+Av(ასო, მთელი რიცხვი(Pos/Divisor+?(TekOst>0,1,0)),1);
GetSymbols(TekOst,TekSymv+1,SymStr);
დაბრუნება SimStr;
წინააღმდეგ შემთხვევაში
SimStr=SimStr+Average(ასო,(?(Pos=0,StrLength(ასო),Pos)),1);
დაბრუნება SimStr;
დაასრულე თუ;
EndFunction

Აქ:
Pos - კომბინირებული ნომერი (ფსევდორანდომური რიცხვი)
TechSym - მიმდინარე სიმბოლო მუშავდება
SimStr - შედეგად მიღებული სიმბოლოების სტრიქონი
ასოები = სტრიქონი, რომელიც შეიცავს ანბანის ასოებს სტანდარტული თანმიმდევრობით ("abv...yuya")
k - სიმბოლოების რაოდენობა საძიებო სიტყვაში (ამ შემთხვევაში = 6)

3. საპირისპირო ტრანსფორმაცია ასევე ტრივიალურია:

ფუნქცია GetCombination (Word,TexCharacter=0,Pos=0)
NomSymv=Find(ასოები,Am(Word,k-TekSymv,1));
თუ TechCym>0 მაშინ
თუ TechCym Pos=Pos+(NomSym-1)*Degree(StrLength(Letters),TechCym);
წინააღმდეგ შემთხვევაში
დაბრუნების პოზი;
დაასრულე თუ;
წინააღმდეგ შემთხვევაში
Pos=?(NomCym=StrLength(ასო),0,NomSymv);
GetCombination (Word, TechCharacter+1, Pos);
დაბრუნების პოზი;
დაასრულე თუ;
EndFunction

Აქ:
სიტყვა არის სიმბოლოების ერთობლიობა, რომელთა რიცხვსაც ჩვენ ვეძებთ
TekSymv - მიმდინარე სიმბოლოს დამუშავება (არსებითად თექვსმეტობითი "რიცხვის" ციფრი)
Pos - საჭირო კომბინაციის ნომერი


************************

შეურიეთ N რიცხვი:

a=1-დან N ციკლისთვის
მასივი[a]=a;
ციკლის დასასრული;
a=1-დან N-1 ციკლისთვის
Sl=Case(a,N);// მთელი შემთხვევითი რიცხვი ინტერვალში [a..N]
K=მასივი[a];
მასივი[a]=მასივი[Sl];
მასივი[Sl]=K;
საბოლოო ციკლი;

//********************************************************************************
************************

Sc = CreateObject ("MSScriptControl.ScriptControl");
Sc.language = "VBscript";
sc.executeStatement("randomize");
ეს იქნება აქ = Sc.eval("rnd");

როგორ შევადგინო 1-დან 100-მდე შემთხვევით შერჩეული რიცხვები?

Rand=_GetPerformanceCounter()%(100+1);

როგორც ჩანს, ეს საუკეთესოა

//********************************************************************************
************************

8.0-ში შეგიძლიათ გამოიყენოთ ჩაშენებული GUID გენერატორი შემთხვევითი რიცხვების გენერირებისთვის.
აქ არის მარტივი ფუნქციის მაგალითი:

//მხოლოდ მთელი რიცხვებისთვის
ფუნქცია GetRandomNumber (მინ., მაქს)

//Randomize-ის ნაცვლად
n = 1-მდე 100 ციკლისთვის
Unique = New UniqueIdentifier;
საბოლოო ციკლი;

//GUID-ის გენერირება
უნიკალური = AbbrLP(New UniqueIdentifier);

//მხოლოდ ნომრების შენარჩუნება
უნიკალური = StrReplace(უნიკალური,"-","");
უნიკალური = StrReplace(უნიკალური"a","");
უნიკალური = StrReplace(უნიკალური"b","");
უნიკალური = StrReplace (უნიკალური, "c", "");
უნიკალური = StrReplace(უნიკალური"d","");
უნიკალური = StrReplace(უნიკალური"e","");
უნიკალური = StrReplace (უნიკალური"f","");

//მნიშვნელს უნდა ჰქონდეს ნულების იგივე რაოდენობა + 1
მნიშვნელი = 10;
n = 2-ისთვის (StrLength(StrReplace(Unique,Characters.NPP,""))) ციკლი
მნიშვნელი = მნიშვნელი * 10;
საბოლოო ციკლი;

საქმე = ნომერი(უნიკალური) / მნიშვნელი; //აქ ვიღებთ წილადობრივ შემთხვევით რიცხვს 0-დან 1-მდე

//გადაიყვანეთ შემთხვევით რიცხვად მოცემული ინტერვალიდან, დაამრგვალეთ უახლოეს მთელ რიცხვამდე
NumberOfInterval = Min(Max(Ab(Min + (Max-Min)*Rand),Min),Max);

დაბრუნება NumberFromInterval;

EndFunction

გადაღებულია [ბმულის სანახავად უნდა დარეგისტრირდეთ]

//********************************************************************************
************************

PS. მე წავაწყდი ამ სტატიას შემთხვევითი რიცხვების გენერატორის ძიებისას. ასე რომ, მე ავირჩიე ვარიანტი
Rand=_GetPerformanceCounter()%(100+1);