将Python更改为C++:如何消除矢量中不断出现的零
Changing Python to C++: how to eliminate zeros that are keep appearing in vectors
我正试图将这段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
下面是我的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;
}
*期望输出:[0.21157894736842103、0.1515789473684211、0.08105263157894739、0.1684210526315789.7、0.3873684210526316]
*我的输出:0 0 0 0 0 0 0 00 0 0 0 0 0 0 00 0 0 0 0 0 0 00 0 0 0 0 0 0 00 0 0 0 0 0 0 00 0 0 0 0 0 0 00 0 0 0
在Pythonsense
:中
def sense(p, Z):
q=[]
你在声明一个空列表。
而在C++sense
:中
vector<float> sense(vector<float> p, string Z){
vector<float> q (p.size());
你声明了一个给定大小的向量,然后在它上使用push_back
。这会改变大小,并在开始时留下零值。
只需:
vector<float> q;
然后你可以用保留内存
q.reserve(p.size());
(reserve
不是resize
,它在内部分配,但不会更改.size()
),所以push_back
不需要那么多重新分配。
一旦解决了这个问题,就可以对具有完全相同问题的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);
}
尽管我得到的结果略有不同。我可能在翻译中遗漏了一些东西:
Thu Oct 12 21:37:26 2017
[ 0.231391, 0.217253, 0.207143, 0.216875, 0.223073 ]
http://coliru.stacked-crooked.com/a/f973d6c5eab3c746
相关文章:
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- Pybind11:将元组列表从Python传递到C++
- 如何在c++中使用引用实现类似python的行为
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 递归列出所有目录中的C++与Python与Ruby的性能
- IPC使用多个管道和分支进程来运行Python程序
- 从python中调用C++函数并获取返回值
- Python 3.7 和 excess_args 的 SWIG 问题
- Python中的for循环与C++有何不同
- 使用Pybind11向Python公开Eigen::张量
- Python str to C++ to Python str
- 如何使用Python从C++中读取谷物序列化数据
- 如何在C++中使用pybind11加载一个pickle python列表
- 如何在c++中使用system()来运行包含空格的python脚本
- python集合的C++等价物是什么.计数器
- 如果C++对象的类在另一个boost模块中声明,如何使用boost将指向该对象的指针返回到python
- 从python调用openMP共享库时,未定义opnMP函数
- 使用JsonCpp将数据返回到带有pybind11的python会在python调用中产生Symbol not foun
- 如何将真正的字符串从python c-api转换为python脚本
- Python ctype 'c_char_p' Memory Leak