গরম আলু বিক্রয়কর্মী


23

পয়েন্টগুলির একটি তালিকা দেওয়া, সংক্ষিপ্ততম পথটি খুঁজে নিন যা সমস্ত পয়েন্টগুলিতে যায় এবং শুরুতে ফিরে আসে।

ভ্রমণ সেলসম্যান প্রবলেম কম্পিউটার বিজ্ঞান ক্ষেত্রে সুপরিচিত, কারণ নিরূপণ / এটি আনুমানিক করার অনেক উপায় আছে। এটি পয়েন্টগুলির খুব বড় গ্রুপগুলির জন্য সমাধান করা হয়েছে, তবে কিছু বৃহত্তম এটি শেষ করতে অনেকগুলি সিপিইউ-বছর সময় নেয়।

আলু দিয়ে পোড়াবেন না।

হট আলু এমন একটি গেম যেখানে 2+ প্লেয়ার সংগীত বাজানোর সময় একটি বৃত্তের চারপাশে একটি "আলু" দেয়। অবজেক্টটি এটি পরবর্তী প্লেয়ারের কাছে দ্রুত পাঠানো হয় pass সংগীত বন্ধ হয়ে গেলে আপনি যদি আলু ধরে রাখেন তবে আপনি বাইরে চলে যাবেন।


বস্তুর গরম আলু সেলসম্যান হল:

100 টি অনন্য পয়েন্টের একটি সেট দেওয়া , সেই পয়েন্টগুলি আরও ভাল ক্রমে ফিরিয়ে দিন ( আরও নিচে সংজ্ঞায়িত সংক্ষিপ্ত মোট দূরত্ব )। এটি পরবর্তী খেলোয়াড়ের কাছে সমস্যাটি "পাস" করবে। তাদের এটির উন্নতি করতে হবে এবং এটি পরবর্তীটিতে পাস করতে হবে etc. ইত্যাদি a

এটিকে "ব্রুট-ফোর্স-মি-এ-পাথ" প্রতিযোগিতা থেকে বিরত রাখতে এই শর্তাদি রয়েছে:

  • আলু পাস করতে আপনি এক মিনিটের বেশি সময় নিতে পারবেন না । যদি আপনি এক মিনিট শেষ হওয়ার পরে একটি সংক্ষিপ্ত সমাধান খুঁজে না পেয়ে এবং পাস করেন না তবে আপনি বাইরে চলে যাবেন।

  • আপনি 25 টির বেশি পয়েন্টের অবস্থান পরিবর্তন করতে পারবেন না । যথার্থ হ'ল, >= 75পয়েন্টগুলি অবশ্যই আপনার একই স্থানে থাকতে হবে them এটা কোন ব্যাপার না , যা আপনি যেগুলি, পরিবর্তন করার সিদ্ধান্ত নেন মাত্র পরিমাণ আপনি পরিবর্তন।

যখন কেবলমাত্র একজন খেলোয়াড় বাকি থাকে, তিনি সেই খেলায় বিজয়ী হন এবং একটি পয়েন্ট পান। একটি ট্যুরে 5*nখেলাগুলি সমন্বিত, যেখানে nখেলোয়াড় সংখ্যা। প্রতিটি গেম, প্রারম্ভিক প্লেয়ার ঘোরানো হবে এবং অবশিষ্ট প্লেয়ার ক্রমটি বদলে যাবে । শেষে সবচেয়ে পয়েন্ট থাকা খেলোয়াড়টি ট্যুরের বিজয়ী। যদি ট্যুরনিটি প্রথম স্থানের সাথে টাই করে শেষ হয় তবে কেবল সেই প্রতিযোগীদের সাথেই একটি নতুন ট্যুরে খেলানো হবে। কোনও টাই না হওয়া পর্যন্ত এটি চলতে থাকবে।

প্রতিটি গেমের জন্য প্রারম্ভিক খেলোয়াড় কোনও নির্দিষ্ট ক্রমে সিউডোরডমোমলি সিলেক্টেড পয়েন্টগুলির একটি সেট পাবেন।

পয়েন্টগুলি x,yকার্টেসিয়ান গ্রিডে সংখ্যক পূর্ণসংখ্যার স্থানাঙ্ক হিসাবে সংজ্ঞায়িত করা হয়। দূরত্ব ব্যবহার পরিমাপ করা হয় ম্যানহাটন দূরত্ব , |x1-x2| + |y1-y2|। সমস্ত স্থানাঙ্ক [0..199]পরিসীমা মধ্যে থাকা হবে ।

ইনপুট

ইনপুট একটি একক স্ট্রিং আর্গুমেন্ট দিয়ে দেওয়া হয়। এটিতে চলতি খেলোয়াড়ের সংখ্যা ( m) এবং 100 পয়েন্ট উপস্থাপন করে 201 টি কমা-বিভাজিত পূর্ণসংখ্যার সমন্বয় করা হবে :

m,x0,y0,x1,y1,x2,y2,...,x99,y99

এই পয়েন্টগুলির ক্রম হল বর্তমান পথ। মোট দুরত্ব প্রতিটি পয়েন্ট থেকে পরের ( dist(0,1) + dist(1,2) + ... + dist(99,0)) এ দূরত্ব যোগ করে প্রাপ্ত হয় । মোট দূরত্ব গণনা করার সময় ফিরে যেতে ভুলবেন না!

লক্ষ্য করুন mহয় না খেলোয়াড়দের খেলা শুরু সংখ্যা, এটা সংখ্যা এখনও হয়।

আউটপুট

আউটপুট একইভাবে ইনপুট, বিয়োগের মতো দেওয়া হয় m; কমা-বিভাজিত পূর্ণসংখ্যাযুক্ত একটি একক স্ট্রিং তাদের নতুন ক্রমের পয়েন্টগুলি উপস্থাপন করে।

x0,y0,x1,y1,x2,y2,...,x99,y99

নিয়ন্ত্রণ প্রোগ্রামটি কেবল এক মিনিটের জন্য আউটপুটটির জন্য অপেক্ষা করবে। আউটপুট প্রাপ্ত হলে এটি যাচাই করবে:

  • আউটপুট সুগঠিত হয়
  • আউটপুট কেবল এবং ইনপুট উপস্থিত সমস্ত 100 পয়েন্ট নিয়ে গঠিত
  • >=75 পয়েন্টগুলি তাদের মূল অবস্থানগুলিতে
  • পূর্বের পথের চেয়ে পাথের দৈর্ঘ্য কম

যদি এই চেকগুলির মধ্যে কোনওটি ব্যর্থ হয় (বা কোনও আউটপুট নেই) তবে আপনি বাইরে চলে গেছেন এবং গেমটি পরবর্তী খেলোয়াড়ের দিকে এগিয়ে যাবে।

নিয়ন্ত্রণ প্রোগ্রাম

আপনি এই লিঙ্কে নিয়ন্ত্রণ প্রোগ্রাম খুঁজে পেতে পারেন । নিয়ন্ত্রণ প্রোগ্রাম নিজেই নির্বিচারক, এবং এর ডামি বীজের সাথে পোস্ট করা হয় 1। স্কোরিংয়ের সময় ব্যবহৃত বীজ আলাদা হবে, তাই টার্ন অর্ডার / পয়েন্ট তালিকাগুলি বিশ্লেষণ করার চেষ্টা করবেন না don't

মূল ক্লাসটি হ'ল Tourney। এটি চালানো প্রতিযোগীদের যুক্তি হিসাবে প্রদত্ত একটি সম্পূর্ণ টুর্নামেন্ট করবে। এটি প্রতিটি গেমের বিজয়ী এবং শেষে একটি টেলিট আউট করে। দুটি স্যুপবটস সহ একটি নমুনা ট্যুরি দেখতে দেখতে:

Starting tournament with seed 1

(0) SwapBot wins a game! Current score: 1
(1) SwapBot wins a game! Current score: 1
(1) SwapBot wins a game! Current score: 2
(1) SwapBot wins a game! Current score: 3
(0) SwapBot wins a game! Current score: 2
(1) SwapBot wins a game! Current score: 4
(1) SwapBot wins a game! Current score: 5
(1) SwapBot wins a game! Current score: 6
(1) SwapBot wins a game! Current score: 7
(1) SwapBot wins a game! Current score: 8

Final Results:

Wins        Contestant
2       (0) SwapBot
8       (1) SwapBot

আপনি যদি একবারে কেবল একটি গেম পরীক্ষা করতে চান তবে আপনি তার Gameপরিবর্তে ক্লাস চালাতে পারেন । এটি আর্গুমেন্ট হিসাবে দেওয়া ক্রমে খেলোয়াড়দের সাথে একটি গেম চালাবে। ডিফল্টরূপে এটি বর্তমান প্লেয়ার এবং পথের দৈর্ঘ্য দেখিয়ে একটি প্লে-বাই-প্লেও মুদ্রণ করবে।

এছাড়াও অন্তর্ভুক্ত কয়েকটি পরীক্ষা খেলোয়াড়দের আছেন: SwapBot, BlockPermuter, এবং TwoSwapBot। প্রথম দুটি রান করাতে অন্তর্ভুক্ত হবে না, তাই পরীক্ষার সময় নির্দ্বিধায় তাদের ব্যবহার এবং আপত্তি জানাতে হবে। বিচার করার জন্য অন্তর্ভুক্ত করা TwoSwapBot হবে , এবং সে কোনও ঝুঁকি নেই, তাই আপনার এ-গেমটি নিয়ে আসুন।

মিশ্রিত বস্তু

  • আপনি রাষ্ট্রের তথ্য সংরক্ষণ করতে পারবেন না এবং প্রতিটি পালা আপনার প্রোগ্রামের একটি পৃথক রান। প্রতিটি বার আপনি যে তথ্য পাবেন তা হ'ল পয়েন্টের সেট।

  • আপনি বাহ্যিক সংস্থান ব্যবহার করতে পারবেন না। এর মধ্যে রয়েছে নেটওয়ার্ক কল এবং ফাইল অ্যাক্সেস।

  • আপনি টিএসপি সমস্যা বা এর রূপগুলি সমাধান / সহায়তা করার জন্য ডিজাইন করা লাইব্রেরি ফাংশন ব্যবহার করতে পারবেন না।

  • আপনি কোনওভাবেই অন্য খেলোয়াড়দের কারসাজি বা হস্তক্ষেপ করতে পারবেন না।

  • আপনি নিয়ন্ত্রণ প্রোগ্রাম বা কোনওভাবে অন্তর্ভুক্ত শ্রেণি বা ফাইলগুলিতে কোনও উপায়ে হস্তক্ষেপ বা হস্তক্ষেপ করতে পারবেন না।

  • মাল্টি-থ্রেডিং অনুমোদিত।

  • ব্যবহারকারী প্রতি এক জমা। আপনি যদি একাধিক এন্ট্রি জমা দেন তবে আমি কেবল জমা দেওয়া প্রথমটি প্রবেশ করবো। আপনি যদি আপনার জমা পরিবর্তন করতে চান তবে মূলটি সম্পাদনা / মুছুন।

  • টুর্নামেন্টটি আইউ -3--3770০ সিপিইউ এবং ১GB জিবি র‌্যাম সহ কম্পিউটারে উবুন্টু ১৩.০৪ এ চলবে । এটি কোনও ভিএম-তে চালানো হবে না। আমি দূষিত হিসাবে যে কোনও কিছু বুঝতে পারি তা অবিলম্বে বর্তমান এবং ভবিষ্যতে প্রবেশ করা আপনার জমা দেওয়া কোনও অযোগ্যতার জন্য অযোগ্য হয়ে যাবে ।

  • সমস্ত এন্ট্রি বিনামূল্যে ( বিয়ার হিসাবে ) সফ্টওয়্যার দিয়ে কমান্ড লাইন থেকে চালানো আবশ্যক । আপনার এন্ট্রি সংকলন / চালাতে আমার যদি সমস্যা হয় তবে আমি মন্তব্যগুলিতে সহায়তা করার অনুরোধ করব। যদি আপনি কোনও প্রতিক্রিয়া না জানান বা আমি শেষ পর্যন্ত এটি চালাতে না পারি তবে এটি অযোগ্য ঘোষণা করা হবে।

ফলাফল (22 মে 2014)

নতুন ফলাফল আছে! UntangleBot প্রতিযোগিতাটি বেশ সাবলীলভাবে পরাজিত করেছে। টুস্বপবট সাতটি জয়কে পরিচালনা করে এবং এসএনএএনবটও জিততে পারে। এখানে একটি স্কোরবোর্ড এবং কাঁচা আউটপুটটির লিঙ্ক রয়েছে :

Wins        Contestant
22      (2) ./UntangleBot
7       (0) TwoSwapBot
1       (5) SANNbot.R
0       (1) BozoBot
0       (3) Threader
0       (4) DivideAndConquer

যেমনটি এখন দাঁড়িয়ে আছে , আনটঙ্গলবট চেকমার্কটি জিতেছে। যদিও তাতে আপনাকে প্রবেশ করতে নিরুৎসাহিত করবেন না, যেহেতু আমি আরও প্রতিযোগী উপস্থিত হওয়ার সাথে সাথে টুর্নামেন্টটি চালাব এবং সেই অনুসারে গৃহীত উত্তরটি পরিবর্তন করব।


মন্তব্য মুছে ফেলা। কোনও সম্ভাব্য হারিয়ে যাওয়া তথ্যের জন্য দয়া করে আমাকে অবহিত করুন।
ডুরকনব

কেন এই চ্যালেঞ্জটি আমার চূড়ান্ত পরীক্ষার সময় থাকতে হবে (অবশেষে, স্কুল ইয়ে সহ)। আপনি নিশ্চয়ই একজন খারাপ পরিকল্পনাকারী জিওবিটস;) অদ্ভুত / দুঃখজনকভাবে সেই সময়ে পাহাড়ের অনেকগুলি প্রশ্ন ছিল এবং এখন আর কিছু নেই (সম্ভবত এটি যদি কেবল একবারে থাকে তবে আরও ভাল কাজ করে, ইঙ্গিত ইঙ্গিত) ...
হার্জন

@ হারজান বর্তমান চ্যাম্পটি মোকাবেলার জন্য নির্দ্বিধায় নতুন প্রতিযোগী প্রদর্শিত আমি আবার কৃত্রিম যুদ্ধ রান করব, তাই প্রতিযোগিতা নয় ওভার বা কিছু। স্যারডিয়ারিয়াসকে মারুন এবং এটি আপনাকে বা অন্য কাউকে মারতে উত্সাহিত করতে পারে, এতে প্রাণ ফিরে আসতে পারে;)
জিওবিটস

@ হারজান দয়া করে একটি এন্ট্রি জমা দিন! আমি বিশ্বাস করি এখানে উন্নতির জন্য অনেক জায়গা আছে। খনি সহ এখানে বেশিরভাগ সমাধানগুলি এই সমস্যাটির জন্য নির্দিষ্ট চতুর অ্যালগরিদমের উপর নির্ভর করে না।
স্যারডিয়ারিয়াস

আমি মনে করি পরিবর্তনের সীমাবদ্ধতায় সমস্যা আছে। কিছু সময় হিসাবে এটি আরও ভাল সমাধান পেতে সম্পূর্ণ সেট ডেটা পরিবর্তন করতে হবে।
ইলিয়া গাজমান

উত্তর:


8

UntangleBot (পূর্বে নিসবট)

একটি সি ++ 11 বট যা দুটি কৌশল ব্যবহার করে।
প্রথমে এটি 25 পয়েন্টের বেশিের কাছাকাছি পথগুলির মধ্যে ছেদগুলি সনাক্ত করে, যদি সম্ভব হয় তবে পথটিকে "আনুভূক্ত" করার চেষ্টা করবে (যেহেতু আনটাঙ্গলিং সমস্ত পয়েন্টকে মধ্যবর্তী স্থানে পরিবর্তন করে বোঝায়)।
যদি প্রথম কৌশলটি ব্যর্থ হয়, এটি এলোমেলোভাবে একটি ভাল পথ সন্ধান না করা অবধি ভাল দূরত্বের জন্য পয়েন্টগুলি অদলবদল করে।

এই বটটি ধারাবাহিকভাবে আমার পরীক্ষার ট্যুরেয়গুলিতে একটি ক্ষতির জন্য পাঁচটি জয়ের আনুমানিক অনুপাতের সাথে টুশপ্পবটকে পরাজিত করে।

// g++ -std=c++11 -O3 -o UntangleBot UntangleBot.cpp
#include <algorithm>
#include <chrono>
#include <cmath>
#include <iostream>
#include <iterator>
#include <random>
#include <set>
#include <sstream>

const int NPOINTS = 100;

struct Point {
    int x, y;

    Point():x(0),y(0) {}    
    Point(int x, int y):x(x),y(y) {}

    int distance_to(const Point & pt) const {
        return std::abs(x - pt.x) + std::abs(y - pt.y);
    }
};

std::ostream & operator<<(std::ostream & out, const Point & point) {
    return out << point.x << ',' << point.y;
}

int total_distance(const Point points[NPOINTS]) {
    int distance = 0;
    for (int i = 0; i < NPOINTS; ++i) {
        distance += points[i].distance_to(points[(i+1)%NPOINTS]);
    }
    return distance;
}

bool intersects(const Point & p1, const Point & p2, const Point & p3, const Point & p4) {
    double s1_x, s1_y, s2_x, s2_y;
    s1_x = p2.x - p1.x;
    s1_y = p2.y - p1.y;
    s2_x = p4.x - p3.x;
    s2_y = p4.y - p3.y;

    double s, t;
    s = (-s1_y * (p1.x - p3.x) + s1_x * (p1.y - p3.y)) / (-s2_x * s1_y + s1_x * s2_y);
    t = ( s2_x * (p1.y - p3.y) - s2_y * (p1.x - p3.x)) / (-s2_x * s1_y + s1_x * s2_y);

    return s >= 0 && s <= 1 && t >= 0 && t <= 1;
}

int main(int argc, char ** argv) {
    Point points[NPOINTS];

    using Clock = std::chrono::system_clock;
    const Clock::time_point start_time = Clock::now();

    // initialize points
    if (argc < 2) {
        std::cerr << "Point list is missing" << std::endl;
        return 1;
    }
    std::stringstream in(argv[1]);
    int players;
    char v;
    in >> players >> v;
    for (int i = 0; i < NPOINTS; ++i) {
        in >> points[i].x >> v >> points[i].y >> v;
    }

    int original_distance = total_distance(points);

    // detect intersection between any 4 points
    for (int i = 0; i < NPOINTS; ++i) {
        for (int j = i+1; j < NPOINTS; ++j) {
            Point & p1 = points[i];
            Point & p2 = points[(i+1)%NPOINTS];
            Point & p3 = points[j];
            Point & p4 = points[(j+1)%NPOINTS];

            // points must all be distinct
            if (p1.distance_to(p3) == 0 || p1.distance_to(p4) == 0 || p2.distance_to(p3) == 0 || p2.distance_to(p4) == 0) {
                continue;
            }

            // do they intersect ?
            if (!intersects(p1, p2, p3, p4)) {
                continue;
            }

            // can modify less than 25 points ?
            if (std::abs(j-i) > 25) {
                continue;
            }

            // swap points
            for (int m = 0; m < std::abs(j-i)/2; ++m) {
                if (i+1+m != j-m) {
                    std::swap(points[i+1+m], points[j-m]);
                    //std::cerr << "untangle " << i+1+m << " <=> " << j-m << '\n';
                }
            }

            int new_distance = total_distance(points);
            if (new_distance < original_distance) {
                std::copy(std::begin(points), std::end(points)-1, std::ostream_iterator<Point>(std::cout, ","));
                std::cout << points[NPOINTS-1];
                return 0;
            }
            else {
                // swap points back
                for (int m = 0; m < std::abs(j-i)/2; m++) {
                    if (i+1+m != j-m) {
                        std::swap(points[i+1+m], points[j-m]);
                    }
                }
            }
        }
    }

    // more traditional approach if the first fails
    std::mt19937 rng(std::chrono::duration_cast<std::chrono::seconds>(start_time.time_since_epoch()).count());
    std::uniform_int_distribution<> distr(0, NPOINTS-1);
    while (true) {
        // try all possible swaps from a random permutation
        int p1 = distr(rng);
        int p2 = distr(rng);
        std::swap(points[p1], points[p2]);

        for (int i = 0; i < NPOINTS; ++i) {
            for (int j = i+1; j < NPOINTS; ++j) {
                std::swap(points[i], points[j]);
                if (total_distance(points) < original_distance) {
                    std::copy(std::begin(points), std::end(points)-1, std::ostream_iterator<Point>(std::cout, ","));
                    std::cout << points[NPOINTS-1];
                    return 0;
                }
                else {
                    std::swap(points[i], points[j]);
                }
            }
        }

        // they didn't yield a shorter path, swap the points back and try again
        std::swap(points[p1], points[p2]);
    }
    return 0;
}

তুমি আমাকে 19 মিনিটের মধ্যে মারধর করেছ!
রেইনবোল্ট

আজকের ফলাফল থেকে বিচার করে এর আরও বেশি উত্সাহ দেওয়া উচিত।
জিওবিটস

@ জিওবিটস আমি এখনও খুব আশ্চর্য হয়েছি যে আমি খুব ভাল সম্পাদন করে এসেছি সবচেয়ে ভাল জিনিসটি। আশাবাদী আরও প্রতিদ্বন্দ্বী প্রতিযোগীরা প্রবেশ করবে!
স্যারডিয়ারিয়াস

@SirDarius ঠিক আছে, জরিমানা । একটি আছে চ্যালেঞ্জের বিট।
জিওবিটস 16:25

4

SANNbot

(ক মধ্যে কৃত্রিম পোড়ানো বট আর )

সঙ্গে ডাকা উচিত Rscript SANNbot.R

input <- strsplit(commandArgs(TRUE),split=",")[[1]]
n <- as.integer(input[1])                            # Number of players
init_s <- s <- matrix(as.integer(input[-1]),ncol=2,byrow=TRUE) # Sequence of points
totdist <- function(s){                              # Distance function
    d <- 0
    for(i in 1:99){d <- d + (abs(s[i,1]-s[i+1,1])+abs(s[i,2]-s[i+1,2]))}
    d
    }
gr <- function(s){                                   # Permutation function
    changepoints <- sample(1:100,size=2, replace=FALSE)
    tmp <- s[changepoints[1],]
    s[changepoints[1],] <- s[changepoints[2],]
    s[changepoints[2],] <- tmp
    s
    }
d <- init_d <- totdist(s)                            # Initial distance
k <- 1                                               # Number of iterations
v <- 0
t <- n*(init_d/12000)                                 # Temperature
repeat{
    si <- gr(s)                                      # New sequence
    di <- totdist(si)                                # New distance
    dd <- di - d                                     # Difference of distances
    if(dd <= 0 | runif(1) < exp(-dd/t)){             # Allow small uphill changes
        d <- di
        s <- si
        v <- v+2
        }
    k <- k+1
    if(k > 10000){break}
    if(d > init_d & v>20){s <- init_s; d <- init_d; v <- 0}
    if(v>23){break}
}
cat(paste(apply(s,1,paste,collapse=","),collapse=","))

ধারণাটি তুলনামূলকভাবে সহজ: প্রতিটি বাঁকটি "তাপমাত্রা" হিসাবে এখনও খেলায় থাকা খেলোয়াড়ের সংখ্যার সাথে সিমুলেটেড অ্যানিলিংয়ের একটি "কুলিং স্টেপ " (বর্তমানের দূরত্বকে 12000 এর বেশি অর্থাৎ প্রায় প্রাথমিক দূরত্বের মাধ্যমে সংশোধন করা হয়েছে)। শুধুমাত্র উপযুক্ত সিমুলেটেড অ্যানিলিংয়ের সাথে পার্থক্য হ'ল আমি যাচাই করেছিলাম যে আমি 25 টিরও বেশি উপাদানকে অনুমতি দিচ্ছি না এবং যদি আমি 20 টি পদক্ষেপ ব্যবহার করি তবে ফলস্বরূপ ক্রমটি প্রাথমিকের চেয়ে মূল্যবান হয় তবে এটি আবার শুরু হবে।


@ জিওবিটস হায় দুঃখিত, সেই লাইনে মুছে ফেলা হয়েছে যেখানে init_s দুর্ঘটনার দ্বারা সংজ্ঞায়িত হয়েছিল (ভাল "দুর্ঘটনা": আমি লাইনটি দেখেছি এবং ভেবেছিলাম "আবার এখানে কেন?" এবং এটি মুছে ফেলেছে :))। সংশোধন।
প্ল্যানাপাস

আমি আপনার প্রোগ্রামটি ব্যবহার করে চেষ্টা করেছি java Tourney "java Swapbot" "Rscript SANNbot.R"এবং দেখে মনে হচ্ছে এটি কার্যকর হবে।
প্ল্যানাপাস

হ্যাঁ, এটি এখন কাজ করছে বলে মনে হচ্ছে।
জিওবিটস

তত্ত্ব অনুসারে (আমি যদি পুরোপুরি ভুল না হয়ে থাকি) আরও খেলোয়াড়রা গেমটিতে প্রবেশ করার সময় এটি আরও ভাল করা উচিত।
প্ল্যানাপাস

যেমনটি হ'ল, আমার পরীক্ষায় "অনেকগুলি পয়েন্ট পরিবর্তিত" হওয়ার কারণে এই প্রোগ্রামটি সর্বদা প্রথম দিকে চলে যায়। আমি যদি uচেকের সীমাটিকে বাধা দেয় তবে এটি ঘটে না (এবং এটি আরও ভাল সম্পাদন করে)। যদিও আপনার কোডটি বেশ সোজা মনে হচ্ছে , আমি আর এর স্পর্শগুলি জানি না তাই যুক্তিটি ভুল কিনা তা আমি বলতে পারি না। (নিয়ন্ত্রকের সর্বশেষতম সংস্করণটি চলার সময় কেন একটি বট বেরিয়ে যায় সে সম্পর্কে বার্তা দেবে Game, যাতে সমস্যাটি চিহ্নিত করতে সহায়তা করতে পারে)
জিওবিটস

4

BozoBot

আরও ভাল পথ খুঁজে পেতে বোজোসর্টের পিছনে জটিল যুক্তি ব্যবহার করে। দেখে মনে হচ্ছে।

  • এলোমেলো পয়েন্ট অদলবদল
  • আমরা উন্নতি যদি
    • উত্তর ফিরিয়ে দিন
  • অন্যভাবে
    • আবার চেষ্টা কর

মাল্টিথ্রেডিংয়ের মাধ্যমে বোজোবট এখন উন্নত হয়েছে ! চারটি মিনিট এখন লক্ষ্যহীনভাবে পয়েন্টগুলি জগল করে না ফেলে যতক্ষণ না তারা কোনও উন্নতিতে হোঁচট খায়। সমাধানটি সন্ধানকারী প্রথমটি একটি কুকি পায়!

স্পষ্টতই আমি মাল্টিথ্রেডিংয়ে ব্যর্থ।

import java.util.Random;
public class BozoBot {
    public static String[] input;
    public static void main(String[] args) {
        input = args;
        for(int i = 0; i < 4; i++) new Minion().run();
    }
}

class Minion implements Runnable {
    public static boolean completed = false;
    public static synchronized void output(int[] x, int[] y) {
        if(!completed) {
            completed = true;
            String result = x[0]+","+y[0];
            for (int i = 1; i < 100; i++)
                result+=","+x[i]+","+y[i];
            System.out.print(result);
            // receiveCookie(); // Commented out to save money
        }
    }
    public void run() {
        String[] args = BozoBot.input[0].split(",");
        int[] x = new int[100];
        int[] y = new int[100];
        for (int i = 1; i < 201; i+=2) {
            x[(i-1)/2] = Integer.parseInt(args[i]);
            y[i/2] = Integer.parseInt(args[i+1]);
        }
        int startDistance = 0;
        for (int i = 1; i < 100; i++)
            startDistance += Math.abs(x[i-1]-x[i]) + Math.abs(y[i-1]-y[i]);
        int r1, r2, r3, r4, tX, tY, newDistance;
        Random gen = new java.util.Random();
        while (true) {
            r1 = gen.nextInt(100);
            r2 = gen.nextInt(100);
            r3 = gen.nextInt(100);
            r4 = gen.nextInt(100);
            tX = x[r1];
            x[r1] = x[r2];
            x[r2] = tX;
            tY = y[r1];
            y[r1] = y[r2];
            y[r2] = tY;
            tX = x[r3];
            x[r3] = x[r4];
            x[r4] = tX;
            tY = y[r3];
            y[r3] = y[r4];
            y[r4] = tY;
            newDistance = 0;
            for (int i=1; i < 100; i++)
                newDistance += Math.abs(x[i-1]-x[i]) + Math.abs(y[i-1]-y[i]);
            if(newDistance < startDistance)
                break;
            tX = x[r1];
            x[r1] = x[r2];
            x[r2] = tX;
            tY = y[r1];
            y[r1] = y[r2];
            y[r2] = tY;
            tX = x[r3];
            x[r3] = x[r4];
            x[r4] = tX;
            tY = y[r3];
            y[r3] = y[r4];
            y[r4] = tY;
        }
        output(x,y);
    }
}

এহহহম ... রান () বলার পরিবর্তে আপনার কি নিজের মিনিটগুলিকে কোনও থ্রেডে রাখা উচিত নয়?
আফাইক এটি

@ মনু তুমি আমাকে ধরেছ! আমি নিজে থেকে এটি শিখতে চেষ্টা করেছি এবং ব্যর্থ হয়েছি। কোন পয়েন্টার?
রেইনবোল্ট

আমি মনে করি এটি হওয়া উচিতnew Thread(new Minion()).start()
কমনগ্যু

1
@ মানু ধন্যবাদ দৃশ্যত আমি যখন কোডিং করছিলাম তখন এই টিউটোরিয়ালটির অর্ধেকটি পড়েছি ।
রেইনবোল্ট

3

TwoSwapBot

এতে আপগ্রেড করা SwapBot, এই লোকটি প্রতি জোড়া অদলবদল পরীক্ষা করে। প্রথমে তিনি পরীক্ষা করেন যে কোনও একক অদলবদল পথটি ছোট করবে কিনা। যদি তা করে, তা সঙ্গে সঙ্গে ফিরে আসে। যদি তা না হয়, তবে তিনি অন্য প্রত্যেকে এটি সংক্ষিপ্ত করবে কিনা তা পরীক্ষা করে দেখুন । তা না হলে সে কেবল মারা যায়।

যদিও পথটি এখনও আধা-এলোমেলো, এটি সাধারণত প্রায় 100 মিমিগুলিতে ফিরে আসে। যদি তাকে প্রতিটি 2-স্ব্যাপ (প্রায় 25M) পরীক্ষা করতে হয় তবে এটি প্রায় 20 সেকেন্ড সময় নেয় seconds

জমা দেওয়ার সময়, এটি পরীক্ষার রাউন্ডে অন্য সমস্ত প্রতিযোগীদের পরাজিত করে।

public class TwoSwapBot {

    static int numPoints = 100;

    String run(String input){
        String[] tokens = input.split(",");
        if(tokens.length < numPoints*2)
            return "bad input? nope. no way. bye.";

        Point[] points = new Point[numPoints];  
        for(int i=0;i<numPoints;i++)
            points[i] = new Point(Integer.valueOf(tokens[i*2+1]), Integer.valueOf(tokens[i*2+2]));
        int startDist = totalDistance(points);

        Point[][] swapped = new Point[(numPoints*(numPoints+1))/2][];       
        int idx = 0;
        for(int i=0;i<numPoints;i++){
            for(int j=i+1;j<numPoints;j++){
                Point[] test = copyPoints(points);
                swapPoints(test,i,j);
                int testDist = totalDistance(test);
                if( testDist < startDist)
                    return getPathString(test);
                else
                    swapped[idx++] = test;
            }
        }

        for(int i=0;i<idx;i++){
            for(int k=0;k<numPoints;k++){
                for(int l=k+1;l<numPoints;l++){
                    swapPoints(swapped[i],k,l);
                    if(totalDistance(swapped[i]) < startDist)
                        return getPathString(swapped[i]);
                    swapPoints(swapped[i],k,l);
                }
            }
        }
        return "well damn";
    }

    void swapPoints(Point[] in, int a, int b){
        Point tmp = in[a];
        in[a] = in[b];
        in[b] = tmp;
    }

    String getPathString(Point[] in){
        String path = "";
        for(int i=0;i<numPoints;i++)
            path += in[i].x + "," + in[i].y + ",";
        return path.substring(0,path.length()-1);
    }

    Point[] copyPoints(Point[] in){
        Point[] out = new Point[in.length];
        for(int i=0;i<out.length;i++)
            out[i] = new Point(in[i].x, in[i].y);
        return out;
    }

    static int totalDistance(Point[] in){
        int dist = 0;
        for(int i=0;i<numPoints-1;i++)
            dist += in[i].distance(in[i+1]);
        return dist + in[numPoints-1].distance(in[0]);
    }

    public static void main(String[] args) {
        if(args.length < 1)
            return;
        System.out.print(new TwoSwapBot().run(args[0]));
    }

    class Point{
        final int x; final int y;
        Point(int x, int y){this.x = x; this.y = y;}
        int distance(Point other){return Math.abs(x-other.x) + Math.abs(y-other.y);}
    }
}

2

স্ক্রুর গুণকারী যন্ত্র

এই বট

  1. 25 10 পয়েন্টের 4 10 টুকরোতে 100 পয়েন্ট আপকে বিভক্ত করে
  2. প্রতিটি টুকরা জন্য একটি থ্রেড শুরু
  3. প্রারম্ভ- এবং শেষ পয়েন্টটি স্থির রেখে, থ্রেডে, এলোমেলোভাবে অ্যারে পরিবর্তন করুন
  4. নতুন অ্যারের দূরত্ব যদি কম হয় তবে এটি রাখুন
  5. 59 এর পরে, মূল থ্রেড ফলাফল সংগ্রহ করে এবং এটি মুদ্রণ করে

ধারণাটি হ'ল পথটির সর্বোত্তম উন্নতি সন্ধান করা, যাতে অন্য বটগুলি তাদের যুক্তি দিয়ে ব্যর্থ হয়।

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

public class Threader {
    public static final int THREAD_COUNT = 10;
    public static final int DOT_COUNT = 100;
    private final Dot[] startDots = new Dot[THREAD_COUNT];
    private final Dot[] endDots = new Dot[THREAD_COUNT];
    private final Dot[][] middleDots = new Dot[THREAD_COUNT][DOT_COUNT/THREAD_COUNT-2];
    private final Worker worker[] = new Worker[THREAD_COUNT];
    private final static long TIME = 59000; 

    public static void main(String[] args) {
        Threader threader = new Threader();
        //remove unnecessary player count to make calculation easier
        threader.letWorkersWork(args[0].replaceFirst("^[0-9]{1,3},", "").split(","));
    }

    public void letWorkersWork(String[] args) {
        readArgs(args);
        startWorkers();
        waitForWorkers();
        printOutput();
    }

    private void readArgs(String[] args) {
        final int magigNumber = DOT_COUNT*2/THREAD_COUNT;
        for (int i = 0; i < args.length; i += 2) {
            Dot dot = new Dot(Integer.parseInt(args[i]), Integer.parseInt(args[i + 1]));
            if (i % magigNumber == 0) {
                startDots[i / magigNumber] = dot;
            } else if (i % magigNumber == magigNumber - 2) {
                endDots[i / magigNumber] = dot;
            } else {
                middleDots[i / magigNumber][(i % magigNumber) / 2 - 1] = dot;
            }
        }
    }

    private void startWorkers() {
        for (int i = 0; i < THREAD_COUNT; i++) {
            worker[i] = new Worker(startDots[i], endDots[i], middleDots[i]);
            Thread thread = new Thread(worker[i]);
            thread.setDaemon(true);
            thread.start();
        }
    }

    private void waitForWorkers() {
        try {
            Thread.sleep(TIME);
        } catch (InterruptedException e) {
        }
    }

    private void printOutput() {
        //get results
        Worker.stopWriting = true;
        int workerOfTheYear = 0;
        int bestDiff = 0;
        for (int i = 0; i < THREAD_COUNT; i++) {
            if (worker[i].diff() > bestDiff) {
                bestDiff = worker[i].diff();
                workerOfTheYear = i;
            }
        }
        //build output
        StringBuilder result = new StringBuilder(1000);
        for (int i = 0; i < THREAD_COUNT; i++) {
            result.append(startDots[i]);
            Dot middle[] = middleDots[i];
            if (i == workerOfTheYear) {
                middle = worker[i].bestMiddle;
            }
            for (int j = 0; j < middle.length; j++) {
                result.append(middle[j]);
            }
            result.append(endDots[i]);
        }
        result.replace(0, 1, ""); //replace first comma
        System.out.print(result);
    }

}

class Worker implements Runnable {

    public Dot start;
    public Dot end;
    private Dot[] middle = new Dot[Threader.DOT_COUNT/Threader.THREAD_COUNT-2];
    public Dot[] bestMiddle = new Dot[Threader.DOT_COUNT/Threader.THREAD_COUNT-2];
    public static boolean stopWriting = false;
    private int bestDist = Integer.MAX_VALUE;
    private final int startDist;

    public Worker(Dot start, Dot end, Dot[] middle) {
        this.start = start;
        this.end = end;
        System.arraycopy(middle, 0, this.middle, 0, middle.length);
        System.arraycopy(middle, 0, this.bestMiddle, 0, middle.length);
        startDist = Dot.totalDist(start, middle, end);
    }

    @Override
    public void run() {
        while (true) {
            shuffleArray(middle);
            int newDist = Dot.totalDist(start, middle, end);
            if (!stopWriting && newDist < bestDist) {
                System.arraycopy(middle, 0, bestMiddle, 0, middle.length);
                bestDist = newDist;
            }
        }
    }

    public int diff() {
        return startDist - bestDist;
    }

    private void shuffleArray(Dot[] ar) {
        Collections.shuffle(Arrays.asList(ar));
    }

}

class Dot {

    public final int x;
    public final int y;

    public Dot(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int distTo(Dot other) {
        return Math.abs(x - other.x) + Math.abs(y - other.y);
    }

    public static int totalDist(Dot start, Dot[] dots, Dot end) {
        int distance = end.distTo(start);
        distance += start.distTo(dots[0]);
        distance += end.distTo(dots[dots.length - 1]);
        for (int i = 1; i < dots.length; i++) {
            distance += dots[i].distTo(dots[i - 1]);
        }
        return distance;
    }

    @Override
    public String toString() {
        return "," + x + "," + y;
    }
}

2
নোট: আমি পরিবর্তন printlnকরতে printআপনার আউটপুট শেষে সম্পর্কে newline পরিত্রাণ পেতে। অন্যথায় এটি ক্রাশ আউট।
জিওবিটস

পরিবর্তিত printlnহয়েছে printএবং থ্রেড-কাউন্ট গতিশীল করেছে। এটি এখন 10 টি থ্রেড দিয়ে শুরু হয় ...
কমনগ্যুই

1

ভাগ করুন এবং বিজয়ী করুন + লোভী বট

দ্রষ্টব্য: আমি আপনার Gameকোডটির দিকে নজর রেখেছি যার জন্য গেম.পার্সপথটিতে নিম্নলিখিতগুলি অন্তর্ভুক্ত রয়েছে:

for(int i=0;i<numPoints;i++){
        test[i] = new Point(Integer.valueOf(tokens[i*2]), Integer.valueOf(tokens[i*2+1]));
        if(test[i].equals(currentPath[i]))
            same++;

যাইহোক, কোনও catch(NumberFormatException)ব্লক নেই, সুতরাং যখন কোনও প্লেয়ার প্রোগ্রাম স্ট্রিং আউট করে (তখন আমার প্রোগ্রামের mainপদ্ধতির শেষে প্রদর্শিত হবে) আপনার প্রোগ্রামটি সম্ভবত ক্রাশ হবে । আমি আপনাকে এটি ঠিক করার পরামর্শ দিচ্ছি, কারণ প্রোগ্রামগুলি ব্যতিক্রম, স্ট্যাক ট্রেস বা এই জাতীয় ফলাফল আউটপুট করতে পারে। অন্যথায়, আপনার প্রোগ্রামটি চালানোর আগে আমার প্রোগ্রামে সেই লাইনটি মন্তব্য করুন।

বিষয় ফিরে

এই বাস্তবায়ন (জাভাতে) পয়েন্টের তালিকাটিকে 25 এর অংশগুলিতে বিভক্ত করে, এলোমেলোভাবে তালিকায় স্থান করে d তারপরে, এটি প্রতিটি অংশের পয়েন্টগুলির মধ্যে পথটি সংক্ষিপ্ত করতে থ্রেড তৈরি করে (অতএব, "ভাগ করুন এবং জয়")। মূল থ্রেড অন্যকে পর্যবেক্ষণ করে এবং সময়সীমার মধ্যে সংক্ষিপ্ততম সমাধান উপস্থাপন করে তা নিশ্চিত করে। যদি কোনও থ্রেড সমাধান ছাড়াই বা ছাড়াই মারা যায়, তবে এটি আবার অন্য থ্রেডটি আবার শুরু করে ch

প্রতিটি থ্রেড "লোভী" অ্যালগরিদম ব্যবহার করে যা এলোমেলো পয়েন্ট থেকে শুরু হয়ে নিকটতম বিন্দুতে যায় এবং সমস্ত পয়েন্ট আচ্ছাদন না করা পর্যন্ত পুনরাবৃত্তি করে (সুতরাং, "লোভী")।

নোট

  • এটি পুরো 1 মিনিটের মধ্যে চলবে (আমি প্রোগ্রাম স্টার্টআপ / শাটডাউন এবং জেভিএম স্টার্টআপের জন্য 3 সেকেন্ড দিয়েছিলাম - আপনি কখনই জানেন না যে জেভিএম স্টার্টআপ রুটিনগুলি পরবর্তী সময়ে কীভাবে ধরা পড়ে ...)
  • এমনকি যদি এটি সমাধানগুলি খুঁজে পেয়েছে তবে এটি অনুসন্ধান চালিয়ে যাবে এবং 1 মিনিট শেষ হওয়ার পরে এটি এটি খুঁজে পাওয়া সেরা সমাধানটি উপস্থাপন করে।
  • আমি নিশ্চিত নই যে এই বাস্তবায়নটি আসলে কোনও ভাল কিনা। যদিও আমি কোডিং করতে কিছু মজা পেয়েছিলাম :)
  • যেহেতু প্রচুর জিনিস এলোমেলো তাই এটি একই ইনপুটটির জন্য একই আউটপুট দিতে পারে না।

শুধু সংকলন এবং java DivideAndConquer.classচালানোর জন্য ব্যবহার করুন।

public class DivideAndConquer extends Thread {
    static LinkedList<Point> original;
    static Solution best;
    static LinkedList<DivideAndConquer> bots;
    static final Object _lock=new Object();

    public static void main(String[] args){
        if(args.length != 1) {
            System.err.println("Bad input!");
            System.exit(-1);
        }
        // make sure we don't sleep too long... get the start time
        long startTime = System.currentTimeMillis();
        // parse input
        String[] input=args[0].split(",");
        int numPlayers=Integer.parseInt(input[0]);
        original=new LinkedList<Point>();
        for(int i=1;i<input.length;i+=2){
            original.add(new Point(Integer.parseInt(input[i]), Integer.parseInt(input[i+1])));
        }
        // start threads
        bots=new LinkedList<DivideAndConquer>();
        for(int i=0;i<6;i++)
            bots.add(new DivideAndConquer(i));
        // sleep
        try {
            Thread.sleep(57000 - (System.currentTimeMillis() - startTime));
        } catch(Exception e){} // should never happen, so ignore
        // time to collect the results!
        Solution best=getBestSolution();
        if(best!=null){
            best.apply(original);
            String printStr="";
            for(int i=0;i<original.size();i++){
                Point printPoint=original.get(i);
                printStr+=printPoint.x+","+printPoint.y+",";
            }
            printStr=printStr.substring(0, printStr.length()-1);
            System.out.print(printStr);
        } else {
            System.out.println("Hey, I wonder if the tournament program crashes on NumberFormatExceptions... Anyway, we failed");
        }
    }

    // check the distance
    public static int calculateDistance(List<Point> points){
        int distance = 0;
        for(int i=0;i<points.size();i++){
            int next=i+1;
            if(next>=points.size())next=0;
            distance+=points.get(i).distance(points.get(next));
        }
        return distance;
    }

    public static void solutionFound(Solution s){
        // thanks to Java for having thread safety features built in
        synchronized(_lock){
            // thanks to Java again for short-circuit evaluation
            // saves lazy programmers lines of code all the time
            if(best==null || best.distDifference < s.distDifference){
                best=s;
            }
        }
    }

    public static Solution getBestSolution(){
        // make sure we don't accidentally return
        // the best Solution before it's even
        // done constructing
        synchronized(_lock){
            return best;
        }
    }

    List<Point> myPoints;
    int start;
    int length;
    int id;

    public DivideAndConquer(int id){
        super("DivideAndConquer-Processor-"+(id));
        this.id=id;
        myPoints=new LinkedList<Point>();
        start=(int) (Math.random()*75);
        length=25;
        for(int i=start;i<start+length;i++){
            myPoints.add(original.get(i));
        }
        start();
    }

    public void run(){
        // copy yet again so we can delete from it
        List<Point> copied=new LinkedList<Point>(myPoints);
        int originalDistance=calculateDistance(copied);
        // this is our solution list
        List<Point> solution=new LinkedList<Point>();
        int randomIdx=new Random().nextInt(copied.size());
        Point prev=copied.get(randomIdx);
        copied.remove(randomIdx);
        solution.add(prev);
        while(copied.size()>0){
           int idx=-1;
           int len = -1;
           for(int i=0;i<copied.size();i++){
               Point currentPoint=copied.get(i);
               int dist=prev.distance(currentPoint);
               if(len==-1 || dist<len){
                   len=dist;
                   idx=i;
               }
           }
           prev=copied.get(idx);
           copied.remove(idx);
           solution.add(prev);
        }
        // aaaand check our distance
        int finalDistance=calculateDistance(solution);
        if(finalDistance<originalDistance){
            // yes! solution
            Solution aSolution=new Solution(start, length, solution, originalDistance-finalDistance);
            solutionFound(aSolution);
        }
        // start over regardless
        bots.set(id, new DivideAndConquer(id));
    }

    // represents a solution
    static class Solution {
        int start;
        int length;
        int distDifference;
        List<Point> region;
        public Solution(int start, int length, List<Point> region, int distDifference){
            this.region=new LinkedList<Point>(region);
            this.start=start;
            this.length=length;
            this.distDifference=distDifference;
        }
        public void apply(List<Point> points){
            for(int i=0;i<length;i++){
                points.set(i+start, region.get(i));
            }
        }
    }

    // copied your Point class, sorry but it's useful...
    // just added public to each method for aesthetics
    static class Point{
        int x;
        int y;
        Point(int x, int y){
            this.x = x;
            this.y = y;
        }
        Point(Point other){
            this.x = other.x;
            this.y = other.y;
        }
        public boolean equals(Point other){
            if(this.x==other.x && this.y==other.y)
                return true;
            return false;
        }

        public int distance(Point other){
            return Math.abs(x-other.x) + Math.abs(y-other.y);
        }
    }
}

এটা আপনি বিশ্বাস করতে পারেন? এসএক্স যখন আমি এটি জমা দিয়েছিলাম তখন আমাকে ক্যাপচা চেয়েছিল ! এটি কি আপনার কাছে বট-মেড দেখাচ্ছে? সিরিয়াসলি?
ড্যাঙ্কমেমস

1
NFException ধাক্কা জন্য স্থির করুন। এটি এখন প্রোগ্রামটিকে হত্যা করার পরিবর্তে খেলোয়াড়কে হত্যা করবে।
জিওবিটস

রেকর্ডটির জন্য, আমি মনে করি না যে এটি আপনার " আরে, আমি যদি ভাবছি ... " লাইনে ক্র্যাশ হয়ে গেছে। এটি <200পার্স করার চেষ্টা করার আগে টোকেন রয়েছে কিনা তা এটি পরীক্ষা করে। তবুও এটির জন্য চেক করা আরও ভাল।
জিওবিটস

@ জিওবিটস হাহা বুঝতে পারেনি
ড্যাঙ্কমিমেস

দ্রষ্টব্য: এটি সংকলন করতে আমাকে )19 লাইনে একটি যুক্ত করতে হয়েছিল; পরিবর্তন substrকরার জন্য substringউপর 38; আরম্ভ idxমধ্যে কিছু run()পদ্ধতি।
জিওবিটস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.