AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / user-5678653

Konchog's questions

Martin Hope
Konchog
Asked: 2025-03-05 01:03:17 +0800 CST

Combinando linhas e colunas onde há uma célula diferente de zero

  • 6

Tenho uma tabela no Google Sheets que se preocupa com nomes de funções/grupos. Às vezes, eles são compartilhados, às vezes, não.
Preciso usar apenas os nomes que pertencem ao serviço de nuvem relevante - e, então, usarei isso em uma tabela cruzada em relação às posições dentro da organização (de modo que se possa identificar quais posições dentro da organização devem ter quais funções/associações de grupo). Pode muito bem haver funções que não estão atribuídas ou serviços de nuvem que não têm funções.

Minha ideia é retornar uma coluna de texto concatenado (GitHub: Backend, etc.) ou duas colunas, conforme o caso.

Nome da função VPN Atlassiano Google Caixa de depósito
Superadministrador 0 0 1 0
Grupos Admin 0 0 1 0
Gerenciamento de usuários 0 0 1 0
Administrador do Help Desk 0 0 1 0
Administração de serviços 0 0 1 0
Administrador de armazenamento 0 0 1 0
Administração de inventário 0 0 1 0
Usuário 0 1 1 0
Funcionários 0 0 0 0
Raiz 0 0 0 0
Back-end 1 0 0 0
Front-end 1 0 0 0
Gerenciamento de projetos 1 0 0 0
Administradores 1 0 0 0
Usuários 1 0 0 0
Administração da organização 0 1 0 0
Administrador do site 0 1 0 0
Administrador de acesso do usuário 0 1 0 0
Administrador de equipe 0 0 0 1
Membro 0 0 0 1

Idealmente, quero uma fórmula automantida (célula única). Ela precisará preservar a identidade com a adição de novas colunas e novas linhas, junto com a remoção das mesmas, para que não percamos a coerência em outro lugar.

Algo como o seguinte seria um ótimo começo

Função na Nuvem
Google: Superadministrador
Google: Administração de grupos
...
DropBox: Membro

Embora alguma forma de garantir alguma forma de integridade referencial seria ainda melhor.

google-sheets
  • 1 respostas
  • 34 Views
Martin Hope
Konchog
Asked: 2025-02-06 00:00:56 +0800 CST

Calculando valores derivados

  • 5

Estou tentando descobrir como escrever uma fórmula intuitiva no Planilhas Google que, dadas duas tabelas (de booleanos) com dimensões AxB, CxB, uma gere a tabela correlacionada CxAseguindo o booleano OR.

Que fórmula pode ser usada para gerar a tabela CxA? Eu definitivamente quero que a tabela seja preenchida usando uma fórmula de célula única.

Tenho pensado em usar map, byrow, bycolou scan, mas cada vez que começo me perco na matriz.

As tabelas abaixo destacam o caso em que Ré verdadeiro para [a,e]; [1,2,3,6]são verdadeiros para a; e [3,4,6]são verdadeiros para e:- portanto [1,2,3,4,6]são verdadeiros para R.

AxB R B G E
um 1 0 0 0
b 0 0 0 1
c 0 1 1 0
e 0 1 0 0
e 1 1 0 0
CxB 1 2 3 4 5 6
um 1 1 1 0 0 1
b 0 0 1 0 1 0
c 0 1 0 1 1 0
e 1 1 0 1 1 0
e 0 0 1 1 0 1
CxA 1 2 3 4 5 6
R 1 1 1 1 0 1
B 1 1 1 1 1 1
G 0 1 0 1 1 0
E 0 0 1 0 1 0
google-sheets
  • 4 respostas
  • 73 Views
Martin Hope
Konchog
Asked: 2025-01-20 00:53:14 +0800 CST

SciPy minimiza para encontrar a função inversa?

  • 7

Eu tenho uma função (não invertível) ak([u,v,w])

Isso pega um ponto na superfície do octaedro unitário (p: tal que |u|+|v|+|w| = 1) e retorna um ponto na superfície da esfera unitária. A função não é perfeita, mas a intenção é manter a distância entre os pontos autálicos.

Eu estava pensando em usar o SciPy minimize para fornecer um inverso numérico, mas não consigo entender.

entrada: pt esférico [x,y,z],
saída pts octaédricos [u,v,w] tais que ak([u,v,w])=[x,y,z]

Minha função ak() é definida assim:

def ak(p):
    # Convert point on octahedron onto the sphere.
    # Credit to Anders Kaseorg: https://math.stackexchange.com/questions/5016695/
    # input:  oct_pt is a Euclidean point on the surface of a unit octagon.
    # output: UVW on a unit sphere.
    a = 3.227806237143884260376580641604959964752197265625  # 𝛂 - vis. Kaseorg.
    p1 = (np.pi * p) / 2.0
    tp1 = np.tan(p1)
    xu, xv, xw = tp1[0], tp1[1], tp1[2]
    u2, v2, w2 = xu ** 2, xv ** 2, xw ** 2
    y0p = xu * (v2 + w2 + a * w2 * v2) ** 0.25
    y1p = xv * (u2 + w2 + a * u2 * w2) ** 0.25
    y2p = xw * (u2 + v2 + a * u2 * v2) ** 0.25
    pv = np.array([y0p, y1p, y2p])
    return pv / np.linalg.norm(pv, keepdims=True)

Esta função é baseada em uma postagem que fiz no Math StackExchange .

Alguma dica?

python
  • 2 respostas
  • 98 Views
Martin Hope
Konchog
Asked: 2024-10-19 07:59:35 +0800 CST

Aumente kamada_kawai_spring_layout usando topologia derivada de GeographicLib ... falhando

  • 6

Estou tentando fazer um layout de mola kamada kawai funcionar na superfície de um elipsoide. Escrevi uma especialização convex_topology que implementa as funções Geodesic do GeographicLib e, então, apliquei uma rede (armazenada em json) junto com posições iniciais (armazenadas da mesma forma).

No entanto, meu código falha. Não sei se é porque a topologia está mal definida, ou se minha implementação do layout kamada kawai do Boost está faltando algo que precisa, ou se estou apenas esperando muito de tudo.

A topologia atual está armazenando pontos como latitude/longitude duplas, e point_difference como um par de distância/rumo, com min/max usando a distância do Polo Norte. Pode ser melhor usar as coordenadas xyz que o Geodesic fornece (superfície no elipsoide, mas quando tentei isso também falhou.

Aqui está o código que estou usando.

#include <algorithm>
#include <cassert>
#include <chrono>
#include <cmath>
#include <fstream>
#include <getopt.h>
#include <iostream>
#include <sstream>
#include <streambuf>
#include <string>
#include <unordered_map>
#include <vector>
#include <random>
#include <numbers>

#include <GeographicLib/Intersect.hpp>
#include <GeographicLib/Geodesic.hpp>
#include <GeographicLib/Constants.hpp>

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/kamada_kawai_spring_layout.hpp>
#include <boost/graph/random_layout.hpp>

#include "rapidjson/document.h"
#include "rapidjson/istreamwrapper.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/ostreamwrapper.h"

using namespace std;
using namespace rapidjson;
using namespace GeographicLib;

template <typename RandomNumberGenerator = minstd_rand > class geo_topology : public boost::convex_topology<2>
{
public:
    typedef typename convex_topology<2>::point_type point_type;
    typedef typename convex_topology<2>::point_difference_type point_difference_type;
    typedef boost::uniform_01< RandomNumberGenerator, double > rand_t;

private:
    shared_ptr< RandomNumberGenerator > gen_ptr;
    shared_ptr< rand_t > rand;
    Geodesic wgs84;

public:
    explicit geo_topology(Geodesic& g) : gen_ptr(new RandomNumberGenerator) , rand(new rand_t(*gen_ptr)),wgs84(g) {}
    geo_topology(RandomNumberGenerator& gen): gen_ptr(), rand(new rand_t(gen)),wgs84(Geodesic::WGS84()) {}
    
    point_type random_point() const {
        point_type p;
        p[0] = fmod((*rand)(),180.0) - 90.0;  // latitude.
        p[1] = fmod((*rand)(),360.0) - 180.0; // longitude.
        if (isnan(p[0]) or isnan(p[1])) {
            std::cerr << "nan in random_point" << std::endl;
        }
        return p;
    }

    point_type bound(point_type a) const {
        a[0] = fmod(a[0] + 90.0,180.0) - 90.0;   // latitude.
        a[1] = fmod(a[1] + 180.0,360.0) - 180.0; // longitude.
        if (isnan(a[0]) or isnan(a[1])) {
            std::cerr << "nan in bound" << std::endl;
        }
        return a;
    }

    double distance_from_boundary(point_type a) const {
        return 1000.0; // really don't know if this means anything.
    }

    point_type center() const {
        point_type result;
        result[0] = 90.0; // latitude.
        result[1] = 0.0;
        return result;
    }

    point_type origin() const {
        point_type result;
        result[0] = 0.0; // latitude.
        result[1] = 0.0;
        return result;
    }

    point_difference_type extent() const {
        point_difference_type result;
        result[0] = wgs84.EquatorialRadius(); // dist.
        result[1] = 360.0; // r_fwd_azi
        return result;
    }
        
    double distance(point a, point b) const {
        double dist = 0.0;
        double r_fwd_azi, r_rev_azi;
        wgs84.Inverse(a[0], a[1], b[0], b[1], dist, r_fwd_azi, r_rev_azi);
        if (isnan(dist)) {
            std::cerr << "dist shows nan distance" << std::endl;
        }
        return dist;
    }

    point move_position_toward(point a, double fraction, point b) const {
        point c;
        double dist = 0.0;
        double r_fwd_azi, r_rev_azi;
        wgs84.Inverse(a[0], a[1], b[0], b[1], dist, r_fwd_azi, r_rev_azi);
        GeodesicLine gl = wgs84.Line(a[0], a[1], r_fwd_azi);
        gl.Position(fraction * dist, c[0], c[1]);
        if (isnan(c[0]) or isnan(c[1])) {
            std::cerr << "nan in move_position_toward" << std::endl;
        }
        return c;
    }

    point_difference difference(point a, point b) const {  // a-b
        point_difference result;
        double r_rev_azi;
        wgs84.Inverse(a[0], a[1], b[0], b[1], result[0], result[1], r_rev_azi);
        if (isnan(result[0]) or isnan(result[1])) {
            std::cerr << "nan in point_difference" << std::endl;
        }
        return result;
    }

    point adjust(point a, point_difference delta) const {
        point result;  //point_difference = dist/fwd_azi
        if (isnan(delta[0]) or isnan(delta[1])) {
//          std::cerr << "nan in adjust.delta for point at " << a[0] << "," << a[1] << std::endl;
            point b = random_point();
            result = move_position_toward(a, 0.000001, b);
        } else {
            GeodesicLine gl = wgs84.Line(a[0], a[1], delta[1]);
            gl.Position(delta[0], result[0], result[1]);
            if (isnan(result[0]) or isnan(result[1])) {
                std::cerr << "nan in adjust" << std::endl;
            }
        }
        return result;
    }

    point pointwise_min(point a, point b) const {
        point result;
        double a_dist, b_dist = 0.0;
        double r_fwd_azi, r_rev_azi;
        wgs84.Inverse(90.0, 0.0, a[0], a[1], a_dist, r_fwd_azi, r_rev_azi);
        wgs84.Inverse(90.0, 0.0, b[0], b[1], b_dist, r_fwd_azi, r_rev_azi);
        result = a_dist <= b_dist ? a : b;
        if (isnan(result[0]) or isnan(result[1])) {
            std::cerr << "nan in pointwise_min" << std::endl;
        }
        return result;
    }

    point pointwise_max(point a, point b) const {
        point result;
        double a_dist, b_dist = 0.0;
        double r_fwd_azi, r_rev_azi;
        wgs84.Inverse(90.0, 0.0, a[0], a[1], a_dist, r_fwd_azi, r_rev_azi);
        wgs84.Inverse(90.0, 0.0, b[0], b[1], b_dist, r_fwd_azi, r_rev_azi);
        result = a_dist >= b_dist ? a : b;
        if (isnan(result[0]) or isnan(result[1])) {
            std::cerr << "nan in pointwise_max" << std::endl;
        }
        return result;
    }

    double norm(point_difference delta) const {
        return delta[0] / wgs84.EquatorialRadius();
    }

    double volume(point_difference delta) const {
        return delta[1];
    }

};

struct ExampleSpherical {
    
    static constexpr double r_mux = numbers::pi / 180.0;
    static constexpr double d_mux = 180.0 / numbers::pi;
    static constexpr double radius = 6371008.7714;
    static constexpr double q_circ = radius * numbers::pi * 0.5;

    using Topology           = geo_topology<>;
    using Point              = Topology::point_type;
    using EdgeWeightProperty = boost::property<boost::edge_weight_t, double> ;

    using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,                 //
                                        boost::property<boost::vertex_index_t, int>,                  //
                                        boost::property<boost::edge_index_t, int, EdgeWeightProperty> //
                                        >;
    size_t depth;
    double line_length;
    std::vector<unsigned long> vertices;
    using PosVector = std::vector<Point>;
    using vertex_id_t = unsigned long; //std::size_t;

    map<vertex_id_t,set<vertex_id_t>> net;
    map<vertex_id_t,Point> pos;
    Geodesic geo;
    Topology topo;

    ExampleSpherical(size_t d) : depth(d),geo(Geodesic::WGS84()),topo(geo) {
        line_length = q_circ / pow(3.0, double(depth+1));
    }
    
    void load_positions(const std::string filename) {
    //  Load latitude/longitude positions.
        auto start = std::chrono::system_clock::now();
        Document jpos;
        ifstream pos_file(filename);   // dict of node: pos
        string pos_str((istreambuf_iterator<char>(pos_file)),istreambuf_iterator<char>());
        jpos.Parse(pos_str.c_str());
        if (!jpos.HasParseError()) {
            auto n_end = jpos.MemberEnd();
            for (auto p_it = jpos.MemberBegin(); p_it != n_end; ++p_it) {
                unsigned long node = std::stoul (p_it->name.GetString());
                Point p;
                p[0] = p_it->value[0].GetDouble();
                p[1] = p_it->value[1].GetDouble();
                pos.insert({node,p});
            }
        }
        for (auto& a : pos) {
            for (auto & b : pos) {
                if (a.first != b.first) {
                    auto dx = topo.difference(a.second, b.second);
                    if (dx[0] < line_length) {
                        line_length = dx[0];
                    }
                    if (dx[0] < 0.000001) {
                        cout << "found overlapping nodes";
                        exit(0);
                    }
                }
            }
        }
        cout << "Minimum Node Distance:" << line_length;
        auto end = std::chrono::system_clock::now();
        auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
        cout << "position load took: " << ms << "ms\n";
    }
    void load_network(const std::string filename) {
        auto start = std::chrono::system_clock::now();
        Document jnet;
        ifstream net_file(filename); // dict with list "nodes" = each= eg {"id"=0}, and list links=eg {"source": 0, "target":2}
        string net_str((istreambuf_iterator<char>(net_file)),istreambuf_iterator<char>());
        jnet.Parse(net_str.c_str());
        if (!jnet.HasParseError()) {
            rapidjson::Value::ConstValueIterator n_ite = jnet["nodes"].Begin();
            rapidjson::Value::ConstValueIterator n_end = jnet["nodes"].End();
            do {
                net.insert({n_ite->GetObject()["id"].GetUint64(),{{},{}}});
                n_ite++;
            } while (n_ite != n_end);
            n_ite = jnet["links"].Begin();
            n_end = jnet["links"].End();
            do {
                unsigned long ia = n_ite->GetObject()["source"].GetUint64();
                unsigned long ib = n_ite->GetObject()["target"].GetUint64();
                net[ia].insert(ib);
                net[ib].insert(ia);
                n_ite++;
            } while (n_ite != n_end);
        }
        auto end = std::chrono::system_clock::now();
        auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
        cout << "network load took: " << ms << "ms\n";
    }
    void validate_graph() {
        deque<vertex_id_t> dx;
        for (auto& node : net) {
            if (pos.find(node.first) == pos.end()) {
                dx.push_back(node.first);
            }
        }
        for (auto& node : net) {
            if (node.second.empty()) {
                dx.push_back(node.first);
            }
            for (auto& q : node.second ) {
                if (net.find(q) == net.end()) {
                    dx.push_back(node.first);
                }
            }
        }
        if (!dx.empty()) {
            cerr << "files did not reconcile correctly";
        }
    }
    void load_and_validate() {
        ostringstream graph_file_str;
        ostringstream graph_pos_str;
        graph_file_str << "graph_" << depth << ".json";
        graph_pos_str << "graph_ll_pos_"  << depth << ".json";
        load_network(graph_file_str.str());
        load_positions(graph_pos_str.str());
        validate_graph();
    }
    void save_positions(PosVector& final_pos) {
        ostringstream result_pos_str;
        result_pos_str << "result_ll_pos_"  << depth << ".json";
        auto start = std::chrono::system_clock::now();
        Document jpos;
        jpos.SetObject();
        auto& alloc = jpos.GetAllocator();
        for (auto& node: pos) {
            ostringstream os;
            os << node.first;
            string id = os.str();
            Value array(kArrayType);
            array.PushBack(final_pos[node.first][0],alloc);
            array.PushBack(final_pos[node.first][1],alloc);
            auto j_id = Value(id.c_str(), alloc);
            jpos.AddMember(j_id, array, alloc);
        }
        std::ofstream ofs { result_pos_str.str() };
        if ( !ofs.is_open() ) {
            std::cerr << "Could not open file for writing!\n";
        }
        OStreamWrapper osw { ofs };
        Writer<OStreamWrapper> writer2 { osw };
        jpos.Accept(writer2);
    
        auto end = std::chrono::system_clock::now();
        auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
        cout << "position save took: " << ms << "ms\n";
    }

    struct kamada_kawai_done {
        kamada_kawai_done() : last_delta() {}
        template<typename Graph>
        bool operator()(double delta_p,
                        typename boost::graph_traits<Graph>::vertex_descriptor /*p*/,
                        const Graph& /*g*/,
                        bool global)
        {
            if (global) {
                double diff = last_delta - delta_p;
                if (diff < 0) diff = -diff;
                std::cout << "delta_p: " << delta_p << std::endl;
                last_delta = delta_p;
                return diff < 0.01;
            } else {
                return delta_p < 0.01;
            }
        }
        double last_delta;
    };
    
    void evaluate() {
        load_and_validate();
        vertices.resize(net.size());
        size_t i=0;
        for (auto n: net) {
            vertices[i] = n.first;
            i++;
        }
        Graph g(this->vertices.size());
        PosVector position(num_vertices(g));

        for (auto n: net) {
            auto& s = n.first;
            for (auto d: n.second) {
                if (d != s) {
                    add_edge(s, d, 1.0, g);
                } else {
                    cout << "Weird. source and destinations " << s << " and " << d << " are the same. Skipping that." << endl;
                }
            }
            position[s] = pos[s];
        }
        auto position_map = boost::make_iterator_property_map(position.begin(), get(boost::vertex_index, g));
        boost::kamada_kawai_spring_layout(g, position_map, get(boost::edge_weight, g), topo, boost::edge_length(10.0), kamada_kawai_done());
        save_positions(position);
    }
};

int main() {
    ExampleSpherical p(1);
    p.evaluate();
}

gráfico_0.json

{"directed": false, "multigraph": false, "graph": {}, "nodes": [{"id": 0}, {"id": 1}, {"id": 2}, {"id": 3}, {"id": 4}, {"id": 5}, {"id": 6}, {"id": 7}, {"id": 8}, {"id": 9}, {"id": 10}, {"id": 11}, {"id": 12}, {"id": 13}, {"id": 14}, {"id": 15}, {"id": 16}, {"id": 17}, {"id": 18}, {"id": 19}, {"id": 20}, {"id": 21}, {"id": 22}, {"id": 23}, {"id": 24}, {"id": 25}, {"id": 26}, {"id": 27}, {"id": 28}, {"id": 29}, {"id": 30}, {"id": 31}, {"id": 32}, {"id": 33}, {"id": 34}, {"id": 35}, {"id": 36}, {"id": 37}], "links": [{"source": 0, "target": 2}, {"source": 0, "target": 1}, {"source": 0, "target": 4}, {"source": 0, "target": 3}, {"source": 1, "target": 7}, {"source": 1, "target": 3}, {"source": 1, "target": 5}, {"source": 1, "target": 2}, {"source": 1, "target": 6}, {"source": 2, "target": 4}, {"source": 2, "target": 8}, {"source": 2, "target": 5}, {"source": 2, "target": 10}, {"source": 3, "target": 9}, {"source": 3, "target": 11}, {"source": 3, "target": 6}, {"source": 3, "target": 4}, {"source": 4, "target": 9}, {"source": 4, "target": 8}, {"source": 4, "target": 12}, {"source": 5, "target": 7}, {"source": 5, "target": 14}, {"source": 5, "target": 16}, {"source": 5, "target": 10}, {"source": 6, "target": 15}, {"source": 6, "target": 17}, {"source": 6, "target": 11}, {"source": 6, "target": 7}, {"source": 7, "target": 15}, {"source": 7, "target": 13}, {"source": 7, "target": 14}, {"source": 8, "target": 10}, {"source": 8, "target": 20}, {"source": 8, "target": 12}, {"source": 8, "target": 22}, {"source": 9, "target": 21}, {"source": 9, "target": 12}, {"source": 9, "target": 11}, {"source": 9, "target": 23}, {"source": 10, "target": 20}, {"source": 10, "target": 16}, {"source": 10, "target": 18}, {"source": 11, "target": 17}, {"source": 11, "target": 19}, {"source": 11, "target": 21}, {"source": 12, "target": 22}, {"source": 12, "target": 24}, {"source": 12, "target": 23}, {"source": 13, "target": 14}, {"source": 13, "target": 25}, {"source": 13, "target": 15}, {"source": 14, "target": 28}, {"source": 14, "target": 16}, {"source": 14, "target": 25}, {"source": 15, "target": 25}, {"source": 15, "target": 29}, {"source": 15, "target": 17}, {"source": 16, "target": 26}, {"source": 16, "target": 28}, {"source": 16, "target": 18}, {"source": 17, "target": 27}, {"source": 17, "target": 29}, {"source": 17, "target": 19}, {"source": 18, "target": 26}, {"source": 18, "target": 20}, {"source": 19, "target": 27}, {"source": 19, "target": 21}, {"source": 20, "target": 26}, {"source": 20, "target": 22}, {"source": 20, "target": 31}, {"source": 21, "target": 32}, {"source": 21, "target": 23}, {"source": 21, "target": 27}, {"source": 22, "target": 30}, {"source": 22, "target": 31}, {"source": 22, "target": 24}, {"source": 23, "target": 24}, {"source": 23, "target": 30}, {"source": 23, "target": 32}, {"source": 24, "target": 30}, {"source": 25, "target": 28}, {"source": 25, "target": 29}, {"source": 25, "target": 33}, {"source": 26, "target": 34}, {"source": 26, "target": 31}, {"source": 26, "target": 28}, {"source": 27, "target": 29}, {"source": 27, "target": 35}, {"source": 27, "target": 32}, {"source": 28, "target": 33}, {"source": 28, "target": 34}, {"source": 29, "target": 33}, {"source": 29, "target": 35}, {"source": 30, "target": 32}, {"source": 30, "target": 36}, {"source": 30, "target": 31}, {"source": 31, "target": 36}, {"source": 31, "target": 34}, {"source": 32, "target": 35}, {"source": 32, "target": 36}, {"source": 33, "target": 37}, {"source": 33, "target": 35}, {"source": 33, "target": 34}, {"source": 34, "target": 37}, {"source": 34, "target": 36}, {"source": 35, "target": 37}, {"source": 35, "target": 36}, {"source": 36, "target": 37}]}

e graph_ll_0.json

{"0": [0.0, 180.0], "1": [0.0, -150.0], "2": [-30.000000000000004, 180.0], "3": [29.999999999999996, 180.0], "4": [0.0, 150.0], "5": [-35.264389682754654, -135.0], "6": [35.264389682754654, -135.0], "7": [0.0, -120.00000000000001], "8": [-35.264389682754654, 135.0], "9": [35.264389682754654, 135.0], "10": [-59.99999999999999, 180.0], "11": [59.99999999999999, 180.0], "12": [0.0, 120.00000000000001], "13": [0.0, -90.0], "14": [-29.999999999999996, -90.0], "15": [29.999999999999996, -90.0], "16": [-59.99999999999999, -90.0], "17": [59.99999999999999, -90.0], "18": [-90.0, 0.0], "19": [90.0, 0.0], "20": [-60.00000000000001, 90.0], "21": [60.00000000000001, 90.0], "22": [-30.000000000000004, 90.0], "23": [29.999999999999996, 90.0], "24": [0.0, 90.0], "25": [0.0, -60.00000000000001], "26": [-60.00000000000001, 0.0], "27": [60.00000000000001, 0.0], "28": [-35.264389682754654, -45.0], "29": [35.264389682754654, -45.0], "30": [0.0, 60.00000000000001], "31": [-35.264389682754654, 45.0], "32": [35.264389682754654, 45.0], "33": [0.0, -29.999999999999996], "34": [-30.000000000000004, 0.0], "35": [29.999999999999996, 0.0], "36": [0.0, 29.999999999999996], "37": [0.0, 0.0]}

Atualizar

A contribuição de Sehe abaixo resolveu muitos bugs no meu código - especialmente em relação à minha falta de compreensão do kamada_kawai_spring_layout do boost

O método topológico 'norm' deve retornar o absoluto do point_difference (que é um couplet {distance, bearing}). O delta point_difference não deve chegar com um valor negativo, mas está acontecendo em algum lugar dentro de kamada_kawai.

    double norm(point_difference delta) const {
        return abs(delta[0]);
    }

Agora estou vendo que os valores da mola estão distorcendo as posições mais do que os valores iniciais (isso é mostrado em uma resolução mais alta da rede, mas não faz diferença para o problema. Observe que o restante dos vértices não mudou do original: eca

É mais ou menos assim que o kamada_kawai deveria ficar (embora ele tenha sido desenhado ajustando-se a uma esfera unitária, em vez de um elipsoide, usando o networkx no python - e, embora o networkx seja bom, ele é muito lento, consome muita memória e não suporta topologias arbitrárias). melhorar

Isto mostra as posições iniciais. insira a descrição da imagem aqui

Estou usando um script python para converter as saídas em KMZ para visualização.

import json
import simplekml
from utility.spherical import Spherical


def add_line(kz, pts, idx, name=None, col=(154, 154, 154), alpha=0.5, width=4):
    tpt = [pts[i] for i in idx]
    if len(tpt[0]) == 3:
        tpt = [sp.xyz_ll(tf) for tf in tpt]
    lo = [i[1] for i in tpt]
    mim = max(lo) - min(lo)
    if mim > 179.9999:
        path = [(o if o >= 0 else o + 360.0000, a) for (a, o) in tpt]
    else:
        path = [(o, a) for (a, o) in tpt]
    lstr = kz.newlinestring(name=name)
    lstr.coords = path
    lstr.style.linestyle.width = width


if __name__ == '__main__':
    sp = Spherical()
    for depth in [2]:
        pos_f = open(f'result_ll_pos_{depth}.json', 'r')
        pos_n = json.load(pos_f)
        pos_f.close()
        pos = dict()
        for k, v in pos_n.items():
            key = int(k)
            pos[key] = tuple(v)
        net_f = open(f'graph_{depth}.json', 'r')
        net = json.load(net_f)
        net_f.close()
        edges = net['links']
        kml = simplekml.Kml(open=1)
        for edge in edges:
            add_line(kml, pos, [edge['source'], edge['target']])
        kml.save(f'kkp_l_{depth}.kml')
        print(f'kml file generated {depth}')
c++
  • 2 respostas
  • 41 Views

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve