将Python更改为C++;:如何消除矢量中不断出现的零

将Python更改为C++;:如何消除矢量中不断出现的零,python,c++,Python,C++,我试图把这个Python代码转换成C++,但是在编译时不需要的零点不断出现。为什么会发生这种情况,我如何解决这个问题 p = [0.2, 0.2, 0.2, 0.2, 0.2] world = ['green', 'red', 'red', 'green', 'green'] measurements = ['red', 'green'] motions = [1,1] pHit = 0.6 pMiss = 0.2 pExact = 0.8 pOvershoot = 0.1 pUndershoo

我试图把这个Python代码转换成C++,但是在编译时不需要的零点不断出现。为什么会发生这种情况,我如何解决这个问题

p = [0.2, 0.2, 0.2, 0.2, 0.2]
world = ['green', 'red', 'red', 'green', 'green']
measurements = ['red', 'green']
motions = [1,1]
pHit = 0.6
pMiss = 0.2
pExact = 0.8
pOvershoot = 0.1
pUndershoot = 0.1

def sense(p, Z):
    q=[]
    for i in range(len(p)):
        hit = (Z == world[i])
        q.append(p[i] * (hit * pHit + (1-hit) * pMiss))
    s = sum(q)
    for i in range(len(q)):
        q[i] = q[i] / s
    return q

def move(p, U):
    q = []
    for i in range(len(p)):
        s = pExact * p[(i-U) % len(p)]
        s = s + pOvershoot * p[(i-U-1) % len(p)]
        s = s + pUndershoot * p[(i-U+1) % len(p)]
        q.append(s)
    return q

for k in range(len(measurements)):
    p = sense(p, measurements[k])
    p = move(p, motions[k])

print p
<> p>这里是我的C++实现代码:

#include <iostream>
#include <vector>
#include <string>
using namespace std;

vector<float> p (5);
vector<string> world (5);
vector<string> measurements (2);
vector<int> motions (2);
float pHit;
float pMiss;
float pExact;
float pOvershoot;
float pUndershoot;
vector<float> sense(vector<float> p, string Z);
vector<float> move(vector<float> p, int U);

int main(){
    vector<float> p (5, 0.2);

    world.push_back("green");
    world.push_back("red");
    world.push_back("red");
    world.push_back("green");
    world.push_back("green");

    measurements.push_back("red");
    measurements.push_back("green");

    pHit = 0.6;
    pMiss = 0.2;
    pExact = 0.8;
    pOvershoot = 0.1;
    pUndershoot = 0.1;

    vector<int> motions (2, 1);

    for(int i=0; i<measurements.size(); i++){
        p = sense(p, measurements[i]);
        p = move(p, motions[i]);
    }

    for(int i=0; i<p.size(); i++){
        cout << p[i] << " ";
    }

    return 0;
}

vector<float> sense(vector<float> p, string Z){
    vector<float> q (p.size());
    for(int i=0; i<p.size(); i++){
        bool hit = (Z == world[i]);
        q.push_back(p[i] * (hit * pHit + (1-hit) * pMiss));
    }

    float s = 0.0;
    for(int i=0; i<q.size(); i++){
        s += q[i];
    }

    for(int i=0; i<q.size(); i++){
        q[i] /= s;
    }

    return q;
}

vector<float> move(vector<float> p, int U){
    vector<float> q (p.size());
    for(int i=0; i<p.size(); i++){
        float s = pExact * p[(i-U) % p.size()];
        s = s + pOvershoot * p[(i-U-1) % p.size()];
        s = s + pUndershoot * p[(i-U+1) % p.size()];
        q.push_back(s);
    }
    return q;
}
#包括
#包括
#包括
使用名称空间std;
载体p(5);
矢量世界(5);
矢量测量(2);
矢量运动(2);
浮瓶;
浮动PMIS;
漂浮物;
浮雕;
浮球;
向量检测(向量p,字符串Z);
向量移动(向量p,int U);
int main(){
向量p(5,0.2);
世界。推回(“绿色”);
世界。推回(“红色”);
世界。推回(“红色”);
世界。推回(“绿色”);
世界。推回(“绿色”);
测量:向后推(“红色”);
测量。推回(“绿色”);
φ=0.6;
pMiss=0.2;
pExact=0.8;
pOvershoot=0.1;
Pundershot=0.1;
矢量运动(2,1);

对于Python中的(int i=0;i)
sense

def sense(p, Z):
    q=[]
vector<float> sense(vector<float> p, string Z){
    vector<float> q (p.size());
您正在声明一个空列表

但在C++ >代码>感觉< /代码>:

def sense(p, Z):
    q=[]
vector<float> sense(vector<float> p, string Z){
    vector<float> q (p.size());
然后你就可以用

q.reserve(p.size());
reserve
不是
resize
,它在内部进行分配,但不会更改
.size()
),因此
推回
不需要如此多的重新分配


一旦您修复了这个问题,您就可以对具有完全相同问题的
move
函数应用完全相同的修复。

使用c++17,您可以使代码看起来非常像python对应的代码:

#include <initializer_list>
#include <vector>
#include <numeric>
#include <algorithm>
#include <functional>
#include <iostream>
#include <string>

using namespace std::literals;

auto p = std::vector{0.2, 0.2, 0.2, 0.2, 0.2};
auto world = std::vector{"green"s, "red"s, "red"s, "green"s, "green"s};
auto measurements = std::vector{"red"s, "green"s};
auto motions = std::vector{1,1};
auto pHit = 0.6;
auto pMiss = 0.2;
auto pExact = 0.8;
auto pOvershoot = 0.1;
auto pUndershoot = 0.1;

auto sum = [](auto&& cont)
{
    using value_type = std::decay_t<decltype(*std::begin(cont))>;
    return std::accumulate(std::begin(cont), std::end(cont),
                           value_type(0), std::plus<>());
};

auto divide_all = [](auto&& container, auto&& divisor)
{
    for(auto&& val : container)
        val /= divisor;
};

auto sense = [](auto p, auto && Z)
{
    for(auto&& val : p)
    {
        auto i = std::distance(&p[0], &val); 
        auto hit = double(Z == world[i]);
        val *= (hit * pHit + (1-hit) * pMiss);
    }
    divide_all(p, sum(p));
    return p;
};

auto move = [](auto p, auto&& U)
{
    auto size = std::size(p);
    for(std::size_t i = 0 ; i < size ; ++i)
    {
        auto s = pExact * p[(i-U) % size];
        s = s + pOvershoot * p[(i-U-1) % size];
        s = s + pUndershoot * p[(i-U+1) % size];
        p[i] = s;
    }
    return p;
};

template<class Container>
void print(Container&& cont)
{
    std::cout << "[";
    const char* sep = " ";
    for (auto&& x : cont) {
        std::cout << sep << x;
        sep = ", ";
    }
    std::cout << " ]" << std::endl;
}

int main()
{

    for(std::size_t k = 0 ; k < std::size(measurements) ; ++k)
    {
        p = move(sense(p, measurements[k]), motions[k]);
    }
    std::cout << __TIMESTAMP__ << std::endl;
    print(p);
}

< /p>你在全局范围内有一个<代码>:p>代码/>代码>主代码< /代码>。我不知道这是否是问题的原因,但是它应该被解决。请注意,当你将向量传递给一个函数时,你正在复制你的向量。考虑改变你的函数来代替<代码> const < /Cord>参考。一个问题,在两个函数中重复的是,您使用的是

vectorq(p.size());
后跟
q.push_-back(…)
。这会不断增加向量的大小。您可以使用
vector q;
来删除该错误。但是,我无法清楚地按照您的逻辑找出如何在输出中获得所需的值。在
move
中也存在同样的问题。OP最好也学习通过引用传递现代编译器和复制省略实际上并不需要e。使用
move
fix编辑。我以前的反射倾向于将输入作为常量引用传递(没错,不会有什么问题)。但返回值最好作为返回值保留。至少我们知道它是一个输出,而不是一个输入/输出(复制省略确保从被调用方变量到调用方变量之间没有复制,几年前不是这样)重新修改它,也许可以将输入向量保留为by值,然后使用
std::move(p)调用是的,内存的转移。我读到了,但从来没有真正实践过。检查一下:在C++ 11中似乎是自动的: