首页 > 其他分享 >grid generation

grid generation

时间:2024-07-03 09:41:59浏览次数:17  
标签:const string generation cache long int state grid

#include <iostream>
#include <vector>
#include <string>
#include <unordered_set>
#include <unordered_map>
#include <thread>
#include <mutex>
#include <chrono>
#include <ctime>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <algorithm>
#include <filesystem>
#include <queue>
#include <set>

using namespace std;

namespace fs = std::filesystem;

const int GRID_SIZE = 5;
const int MAX_STATE_NAME_LENGTH = 13; // Maximum length of U.S. state names
const char MOST_FREQUENT_CHAR = 'A';  // The most frequent character in state names
const unsigned long long SAVE_INTERVAL = 1000000; // Save cache every 1,000,000 calculations
const int SCORE_THRESHOLD = 100000000; // Score threshold for highlighting

vector<string> states = {
    "ALABAMA", "ALASKA", "ARIZONA", "ARKANSAS", "CALIFORNIA", "COLORADO", "CONNECTICUT", "DELAWARE",
    "FLORIDA", "GEORGIA", "HAWAII", "IDAHO", "ILLINOIS", "INDIANA", "IOWA", "KANSAS", "KENTUCKY",
    "LOUISIANA", "MAINE", "MARYLAND", "MASSACHUSETTS", "MICHIGAN", "MINNESOTA", "MISSISSIPPI",
    "MISSOURI", "MONTANA", "NEBRASKA", "NEVADA", "NEWHAMPSHIRE", "NEWJERSEY", "NEWMEXICO",
    "NEWYORK", "NORTHCAROLINA", "NORTHDAKOTA", "OHIO", "OKLAHOMA", "OREGON", "PENNSYLVANIA",
    "RHODEISLAND", "SOUTHCAROLINA", "SOUTDAKOTA", "TENNESSEE", "TEXAS", "UTAH", "VERMONT",
    "VIRGINIA", "WASHINGTON", "WESTVIRGINIA", "WISCONSIN", "WYOMING"
};
unordered_map<string, int> population = {
    {"ALABAMA", 5024279}, {"ALASKA", 733391}, {"ARIZONA", 7151502}, {"ARKANSAS", 3011524},
    {"CALIFORNIA", 39538223}, {"COLORADO", 5773714}, {"CONNECTICUT", 3605944}, {"DELAWARE", 989948},
    {"FLORIDA", 21538187}, {"GEORGIA", 10711908}, {"HAWAII", 1455271}, {"IDAHO", 1839106},
    {"ILLINOIS", 12812508}, {"INDIANA", 6785528}, {"IOWA", 3190369}, {"KANSAS", 2937880},
    {"KENTUCKY", 4505836}, {"LOUISIANA", 4657757}, {"MAINE", 1362359}, {"MARYLAND", 6177224},
    {"MASSACHUSETTS", 7029917}, {"MICHIGAN", 10077331}, {"MINNESOTA", 5706494}, {"MISSISSIPPI", 2961279},
    {"MISSOURI", 6154913}, {"MONTANA", 1084225}, {"NEBRASKA", 1961504}, {"NEVADA", 3104614},
    {"NEWHAMPSHIRE", 1377529}, {"NEWJERSEY", 9288994}, {"NEWMEXICO", 2117522}, {"NEWYORK", 20201249},
    {"NORTHCAROLINA", 10439388}, {"NORTHDAKOTA", 779094}, {"OHIO", 11799448}, {"OKLAHOMA", 3959353},
    {"OREGON", 4237256}, {"PENNSYLVANIA", 13002700}, {"RHODEISLAND", 1097379}, {"SOUTHCAROLINA", 5118425},
    {"SOUTDAKOTA", 886667}, {"TENNESSEE", 6910840}, {"TEXAS", 29145505}, {"UTAH", 3271616},
    {"VERMONT", 643077}, {"VIRGINIA", 8631393}, {"WASHINGTON", 7705281}, {"WESTVIRGINIA", 1793716},
    {"WISCONSIN", 5893718}, {"WYOMING", 576851}
};

const vector<pair<int, int>> directions = {
    {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}
};

bool isValid(int x, int y) {
    return x >= 0 && x < GRID_SIZE && y >= 0 && y < GRID_SIZE;
}

bool isValidPrefix(const string& word) {
    for (const auto& state : states) {
        if (word.length() > state.length()) continue;
        int mismatchCount = 0;
        for (int i = 0; i < word.length(); ++i) {
            if (word[i] != state[i]) {
                mismatchCount++;
                if (mismatchCount > 1) break;
            }
        }
        if (mismatchCount <= 1) return true;
    }
    return false;
}

void findStates(vector<vector<char>>& grid, int x, int y, string currentWord, unordered_set<string>& foundStates, unordered_map<string, unordered_set<string>>& cache) {
    currentWord += grid[x][y];
    if (currentWord.length() > MAX_STATE_NAME_LENGTH) return;

    // First check the cache
    auto it = cache.find(currentWord);
    if (it != cache.end()) {
        foundStates.insert(it->second.begin(), it->second.end());
        return;
    }

    if (!isValidPrefix(currentWord)) return;

    unordered_set<string> localFoundStates;
    for (const auto& state : states) {
        if (currentWord == state) {
            localFoundStates.insert(state);
            break;
        }
        int mismatchCount = 0;
        if (currentWord.length() == state.length()) {
            for (int i = 0; i < currentWord.length(); ++i) {
                if (currentWord[i] != state[i]) {
                    mismatchCount++;
                    if (mismatchCount > 1) break;
                }
            }
            if (mismatchCount == 1) {
                localFoundStates.insert(state);
                break;
            }
        }
    }

    for (const auto& dir : directions) {
        int newX = x + dir.first;
        int newY = y + dir.second;
        if (isValid(newX, newY)) {
            findStates(grid, newX, newY, currentWord, localFoundStates, cache);
        }
    }

    foundStates.insert(localFoundStates.begin(), localFoundStates.end());
    cache[currentWord] = localFoundStates;
}

void printGridAndStates(ostream& os, const vector<vector<char>>& grid, const unordered_set<string>& states) {
    for (const auto& row : grid) {
        for (char c : row) {
            os << c << " ";
        }
        os << endl;
    }
    for (const auto& state : states) {
        os << state << " ";
    }
    os << endl;
}

string getCurrentTimestamp() {
    auto now = chrono::system_clock::now();
    auto now_time_t = chrono::system_clock::to_time_t(now);
    stringstream ss;
    ss << put_time(localtime(&now_time_t), "%Y-%m-%d %H:%M:%S");
    return ss.str();
}

string getLogFileName() {
    auto now = chrono::system_clock::now();
    auto now_time_t = chrono::system_clock::to_time_t(now);
    stringstream ss;
    ss << "kingsmove_log_" << put_time(localtime(&now_time_t), "%Y%m%d_%H%M%S") << ".txt";
    return ss.str();
}

mutex logMutex;
ofstream logFile;

void logMessage(const string& message, bool highlight = false) {
    string formattedMessage = "[" + getCurrentTimestamp() + "] " + message;
    if (highlight) {
        formattedMessage = "\033[1;31m" + formattedMessage + "\033[0m"; // Highlight in red
    }
    lock_guard<mutex> guard(logMutex);
    cout << formattedMessage << endl;
    logFile << formattedMessage << endl;
}

void logNewMaxScore(int threadId, int maxScore, const vector<vector<char>>& grid, const unordered_set<string>& states, bool highlight) {
    string formattedMessage = "[" + getCurrentTimestamp() + "] Thread " + to_string(threadId) + " found new max score: " + to_string(maxScore);
    if (highlight) {
        formattedMessage = "\033[1;31m" + formattedMessage + "\033[0m"; // Highlight in red
    }
    lock_guard<mutex> guard(logMutex);
    cout << formattedMessage << endl;
    logFile << formattedMessage << endl;
    printGridAndStates(cout, grid, states); // Print to console
    printGridAndStates(logFile, grid, states); // Print to log file
}

void saveCache(int threadId, unsigned long long idx, int maxScore, const unordered_map<string, unordered_set<string>>& cache, const string& folderPath) {
    // Delete previous cache files for this thread
    for (const auto& entry : fs::directory_iterator(folderPath)) {
        if (entry.path().stem().string().find("thread_" + to_string(threadId) + "_cache_") == 0) {
            fs::remove(entry.path());
        }
    }

    // Save new cache file
    stringstream ss;
    ss << folderPath << "/thread_" << threadId << "_cache_" << idx / SAVE_INTERVAL << ".cache";
    ofstream cacheFile(ss.str());
    if (cacheFile.is_open()) {
        cacheFile << idx << " " << maxScore << endl;
        for (const auto& entry : cache) {
            cacheFile << entry.first << " ";
            for (const auto& state : entry.second) {
                cacheFile << state << " ";
            }
            cacheFile << "-" << endl; // Use '-' as a delimiter for the end of the state's list
        }
        cacheFile.close();
    }
}

bool loadLatestCache(int threadId, unsigned long long& idx, int& maxScore, unordered_map<string, unordered_set<string>>& cache, const string& folderPath) {
    vector<fs::path> cacheFiles;
    for (const auto& entry : fs::directory_iterator(folderPath)) {
        if (entry.path().stem().string().find("thread_" + to_string(threadId) + "_cache_") == 0) {
            cacheFiles.push_back(entry.path());
        }
    }
    if (cacheFiles.empty()) {
        return false;
    }

    sort(cacheFiles.begin(), cacheFiles.end(), [](const fs::path& a, const fs::path& b) {
        return a.stem().string() > b.stem().string();
    });

    string latestCacheFile = cacheFiles.front().string();
    ifstream cacheFile(latestCacheFile);
    if (cacheFile.is_open()) {
        cacheFile >> idx >> maxScore;
        string key, state;
        while (cacheFile >> key) {
            unordered_set<string> statesSet;
            while (cacheFile >> state && state != "-") {
                statesSet.insert(state);
            }
            cache[key] = statesSet;
        }
        cacheFile.close();
        logMessage("Thread " + to_string(threadId) + " loaded cache from " + latestCacheFile + " at index " + to_string(idx) + " with max score " + to_string(maxScore));
        return true;
    }
    return false;
}

void saveHighScore(int threadId, int score, const string& logFileName) {
    ofstream csvFile(logFileName + ".csv", ios::app);
    if (csvFile.is_open()) {
        csvFile << threadId << "," << score << "," << getCurrentTimestamp() << endl;
        csvFile.close();
    }
}

struct Grid {
    vector<vector<char>> grid;
    int heuristicScore;
    unsigned long long index;

    bool operator<(const Grid& other) const {
        return heuristicScore < other.heuristicScore;
    }
};

int calculateHeuristic(const vector<vector<char>>& grid) {
    unordered_map<char, int> charFrequency;
    for (const auto& row : grid) {
        for (char c : row) {
            charFrequency[c]++;
        }
    }

    int potentialScore = 0;
    for (const auto& entry : charFrequency) {
        if (population.count(string(1, entry.first))) {
            potentialScore += population[string(1, entry.first)] * entry.second;
        }
    }

    int charDiversity = charFrequency.size();

    return potentialScore + charDiversity * 1000000; // Adjust weight of diversity as needed
}

vector<vector<char>> generateGridVariation(const vector<vector<char>>& grid) {
    vector<vector<char>> newGrid = grid;
    int x1 = rand() % GRID_SIZE;
    int y1 = rand() % GRID_SIZE;
    int x2 = rand() % GRID_SIZE;
    int y2 = rand() % GRID_SIZE;
    swap(newGrid[x1][y1], newGrid[x2][y2]);
    return newGrid;
}

void generateGrids(priority_queue<Grid>& gridQueue, set<unsigned long long>& checkedGrids, unordered_set<string>& foundStates, int threadId, unsigned long long& counter, unsigned long long totalCalculations, unsigned long long start, unsigned long long end, unordered_map<string, unordered_set<string>>& cache, int& maxScore, const string& folderPath, const string& logFileName) {
    while (!gridQueue.empty()) {
        Grid current = gridQueue.top();
        gridQueue.pop();

        if (checkedGrids.count(current.index)) {
            continue;
        }
        checkedGrids.insert(current.index);

        unordered_set<string> localFoundStates;
        for (int x = 0; x < GRID_SIZE; ++x) {
            for (int y = 0; y < GRID_SIZE; ++y) {
                findStates(current.grid, x, y, "", localFoundStates, cache);
            }
        }
        unordered_set<string> combinedStates = foundStates;
        combinedStates.insert(localFoundStates.begin(), localFoundStates.end());

        int totalScore = 0;
        for (const auto& state : combinedStates) {
            totalScore += population.at(state);
        }

        if (totalScore > maxScore) {
            maxScore = totalScore;
            bool highlight = maxScore > SCORE_THRESHOLD;
            logNewMaxScore(threadId, maxScore, current.grid, combinedStates, highlight);
            saveHighScore(threadId, maxScore, logFileName);
        }
        counter++;

        if (counter % SAVE_INTERVAL == 0) {  // Save cache every SAVE_INTERVAL calculations
            saveCache(threadId, current.index, maxScore, cache, folderPath);
            double progress = static_cast<double>(counter - start) / (end - start) * 100.0;
            logMessage("Thread " + to_string(threadId) + " saved cache at counter " + to_string(counter) + " / " + to_string(end - start) + " (" + to_string(progress) + "%)");
        }

        for (int i = 0; i < 10; ++i) {
            vector<vector<char>> newGrid = generateGridVariation(current.grid);
            int heuristicScore = calculateHeuristic(newGrid);
            gridQueue.push({newGrid, heuristicScore, current.index});
        }
    }
}

void threadFunction(int threadId, unsigned long long start, unsigned long long end, int& maxScore, const string& folderPath, const string& logFileName) {
    vector<vector<char>> initialGrid(GRID_SIZE, vector<char>(GRID_SIZE, MOST_FREQUENT_CHAR)); // Initialize with the most common character
    unordered_set<string> foundStates;
    unordered_map<string, unordered_set<string>> cache;
    unsigned long long counter = start;
    priority_queue<Grid> gridQueue;
    set<unsigned long long> checkedGrids;

    // Load cache if exists
    if (loadLatestCache(threadId, counter, maxScore, cache, folderPath)) {
        logMessage("Thread " + to_string(threadId) + " continuing from cache at index " + to_string(counter) + " with max score " + to_string(maxScore));
    }

    // Initialize the priority queue with the initial grid
    int heuristicScore = calculateHeuristic(initialGrid);
    gridQueue.push({initialGrid, heuristicScore, start});

    generateGrids(gridQueue, checkedGrids, foundStates, threadId, counter, end - start, start, end, cache, maxScore, folderPath, logFileName);

    logMessage("Thread " + to_string(threadId) + " finished with max score: " + to_string(maxScore));
}

unsigned long long power(unsigned long long base, unsigned long long exp) {
    unsigned long long result = 1;
    while (exp > 0) {
        if (exp % 2 == 1) {
            result *= base;
        }
        base *= base;
        exp /= 2;
    }
    return result;
}

int main(int argc, char* argv[]) {
    if (argc != 2) {
        cerr << "Usage: " << argv[0] << " <number_of_threads>" << endl;
        return 1;
    }

    int numThreads;
    try {
        numThreads = stoi(argv[1]);
        if (numThreads <= 0) throw invalid_argument("Number of threads must be a positive integer.");
    } catch (const invalid_argument& e) {
        cerr << "Invalid number of threads: " << argv[1] << endl;
        return 1;
    }

    // Create directory with number of threads as name
    string folderPath = to_string(numThreads);
    fs::create_directory(folderPath);

    // Initialize log file with a timestamp in the name
    string logFileName = getLogFileName();
    logFile.open(folderPath + "/" + logFileName);
    if (!logFile.is_open()) {
        cerr << "Failed to open log file: " << logFileName << endl;
        return 1;
    }
    logMessage("Program started with " + to_string(numThreads) + " threads.");

    unsigned long long totalCalculations = power(26, GRID_SIZE * GRID_SIZE);
    unsigned long long calculationsPerThread = totalCalculations / numThreads;
    vector<int> threadMaxScores(numThreads, 0);

    vector<thread> threads;
    for (int i = 0; i < numThreads; ++i) {
        unsigned long long start = i * calculationsPerThread;
        unsigned long long end = (i == numThreads - 1) ? totalCalculations : start + calculationsPerThread;
        threads.emplace_back(threadFunction, i + 1, start, end, ref(threadMaxScores[i]), folderPath, folderPath + "/" + logFileName);
    }

    for (auto& t : threads) {
        t.join();
    }

    // Combine results from all threads
    int maxScore = *max_element(threadMaxScores.begin(), threadMaxScores.end());
    logMessage("Max score found: " + to_string(maxScore));
    logFile.close();

    return 0;
}

标签:const,string,generation,cache,long,int,state,grid
From: https://www.cnblogs.com/cysm/p/18280992

相关文章

  • [论文阅读] Calligraphy Font Generation via Explicitly Modeling Location-Aware Gl
    Pretitle:CalligraphyFontGenerationviaExplicitlyModelingLocation-AwareGlyphComponentDeformationssource:TMM2023paper:https://ieeexplore.ieee.org/document/10356848code:None关键词:generativeadversarialnetworks,imageprocessing,imagesynth......
  • 认识Retrieval Augmented Generation(RAG)
    什么是RAG?Retrieval-AugmentedGeneration(RAG)是一种结合信息检索和生成式AI技术的框架。它通过从外部数据源检索信息,增强语言模型(如GPT-3)的生成能力,从而提供更加准确和相关的回答。RAG的组成部分信息检索模块(Retriever)功能:从预先构建的知识库或文档库中检索与用......
  • C#实现禁用DataGridView控件列表头自动排序功能 (附完整源码)
    C#实现禁用DataGridView控件列表头自动排序功能代码说明:在C#中,可以通过设置DataGridView控件的列的SortMode属性来禁用列头的自动排序功能。以下是一个完整的示例代码,展示了如何实现这一功能:usingSystem;usingSystem.Windows.Forms;​namespace......
  • GridPane网格布局
    JavaFX的GridPane是一种基于网格的布局方式,它允许你将子节点放置在网格的行和列中。GridPane提供了高度的灵活性来创建复杂的用户界面布局。以下是GridPane的一些基本用法:添加节点到网格:使用add方法将子节点添加到特定的行和列。行和列的索引:行和列的索引都是从0开......
  • [题解]AT_abc224_e [ABC224E] Integers on Grid
    比较符合CCF造数据水平的题。思路首先可以用两个vector<pair<int,int>>v[N]分别将每一行、每一列的元素的权值与编号存储下来。那么可以对所有的\(v_i\)按照权值从小到大排序。那么发现对于所有的满足v[i][p].fst<v[i][q].fst的\((p,q)\)都可以建一条从\(p\)指......
  • 【论文笔记】Prefix-Tuning: Optimizing Continuous Prompts for Generation
    题目:Prefix-Tuning:OptimizingContinuousPromptsforGeneration来源:ACL2021模型名称:Prefix-Tuning论文链接:https://aclanthology.org/2021.acl-long.353/项目链接:https://github.com/XiangLi1999/PrefixTuning感觉与prompt的想法很相近,那么问题来了,为什......
  • ORION Space Scene Generation Framework
    ORION太空场景生成框架是一个涵盖所有太空场景生成方面的系统,从程序化的行星和宇宙飞船到任何相关的特效,支持所有管道。重要提示!!!:ORION资产可以从SkyMasterULTIMATE升级,从而可以与SkyMasterULTIMATE的全容积行星云和大气效果相结合,最适合在云层中飞行。这是该系统的第一......
  • DevExpress WPF中文教程:Grid - 如何将更改发布到数据库(设计时)?
    DevExpressWPF拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpressWPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。无论是Office办公软件的衍伸产品,还是以数据为中心......
  • WPF/C#:在DataGrid中显示选择框
    前言在使用WPF的过程中可能会经常遇到在DataGrid的最前或者最后添加一列选择框的需求,今天跟大家分享一下,在自己的项目中是如何实现的。整体实现效果如下:如果对此感兴趣,可以接下来看具体实现部分。实践假设数据库中的模型如下:publicclassPerson{publicintId......
  • 论文阅读:Corrective Retrieval Augmented Generation
    CorrectiveRetrievalAugmentedGeneration(https://arxiv.org/pdf/2401.15884.pdf)https://github.com/jiangnanboy/paper_read_note一.序言RAG即检索增强生成(retrievalaugmentedgeneration),当检索到不准确的数据时,会产生对模型的生成干扰。CorrectiveRetrievalAugme......