股民解套问题的两个算法--算法分析与设计

文章介绍了如何使用两种算法策略——蛮力法和回溯法,来解决股民在限定交易日内的证券价格走势问题,以达到期望的收益目标。当证券交易最多持续3天且需至少获利1单位时,给出了4种可能的价格走势。示例代码分别展示了这两种算法的实现,帮助理解算法在解决此类问题中的应用。
摘要由CSDN通过智能技术生成

某股民投资某证券,购入该证券时间作为起始点0,当天的盈亏也定为0。假定证券价格每个交易日的变化有三档:比前一个交易日上涨1个单位,与前一个交易日持平,比前一个交易日下跌1个单位。

该股民对其持有证券的收益期望值是k个单位。即:只要该证券的价格比其购入的价格高k个单位,他就会卖出该证券获利了结,反之如果没有达到预期的利润,他就会继续持有该证券,持有的天数最多为N个交易日。在第N个交易日,股民已经失去了耐心,无论是否达到收益预期,证券都会被该股民卖出。

1.请根据已经学过的算法策略,在屏幕输出从证券购买日开始,能使该股民在第N以及第N个交易日以内获利k个单位的证券每日价格走势组合,并统计符合条件的价格走势总数。

2.要求用2种算法策略实现。

测试用例:当N=3,k=1时,表示最多持有3个交易日,获利1个单位即了结。

输入:

3 1

屏幕输出结果为:

1

0 1

0 0 1

-1 1 1

count=4

以上屏幕输出表示3个交易日内获利1个单位的所有组合,分别是:

1              第1个交易日价格上涨1

0    1        第1个交易日价格持平,第2个交易日价格上涨1

0  0  1      第1、2个交易日价格持平,第3个交易日价格上涨1

-1  1  1      第1个交易日价格下跌1,第2、3个交易日价格上涨1

count=4      表示以上符合要求的价格走势一共有4种。

代码如下:

第一种方法使用蛮力算法使用python实现,假设n为4,k为2:

from itertools import product
n=int(input("输入天数:"))
k=int(input("输入期望:"))
num_list=[-1,0,1]
result_list=[]
count_num=0
for i, j, s, t in product(num_list,repeat=n):
    if i+j+s+t==k:
        result_list.append((i,j,s,t))
        count_num += 1
        if i==j:
            result_list.remove((i,j,s,t))
result_list.append((i,i,0,0))
result_list.sort(reverse=True)
#print(result_list)
for i in result_list:
    print(i)
print("count="+str((count_num-n+1)))

运行结果如图:

第二种方法使用回溯算法,使用和测试用例相同的条件:

result=[]
def permutations(arr, position, end):
    global result
    if position == end:
       list1=[]
       k=1
       if arr[0]+arr[1]+arr[2]==k:
        n=3
        result.append(arr[0:n])
    else:
        for index in range(position, end):
            arr[index], arr[position] = arr[position], arr[index]
            permutations(arr, position+1, end)
            arr[index], arr[position] = arr[position], arr[index]
arr=[1,0,0,1,-1]
permutations(arr, 0, len(arr))
chao=[]
for i in result:
    if i not in chao:
        chao.append(i)
chao1=[]
count=0
for j in chao:
    if j[0]==0 or j[0]==-1:
        count=count+1
        chao1.append(j)
chao1.append([1,0,0])
count=count+1
chao1.sort(reverse=True)
for s in chao1:
    print(s)
print("count="+str(count))

运行结果如图: 

思路分析:

根据问题描述,可以分析出股民解套问题的实质是一个允许有重复数字的排列问题,-1,0,1可以看成是要产生数字的基础数字,n可以看成是重复的次数,k是产生数字的限定条件。

既然是排列问题,蛮力法肯定可以使用,本题其实也不适合第二种算法。核对课本可以发现回溯法和蛮力法在书中属于不同的算法,就可以想到第二个算法使用回溯法。

算法设计:

蛮力法的设计是通过n层for循环来产生所有的-1,0,1组成的数字,在最内层for循环中嵌套if语句,if语句的功能是判断循环产生的数字相加的和是不是为k,符合条件的将结果存放到结果集中。

以k为2,n为4为例,在根据蛮力法设计完基本代码后,要考虑到在循环结束后,1组成的不同数字还有n个,虽然这n个数字符合相加为k的条件,但是不符合题目k为2就跳出的要求,所以在这里用if语句删除所有第一个和第二个字符都是1组成的数字,在结果集加入[1,1,0,0],排序后按行输出结果集。

而回溯法设计是使用递归回溯+排列树的思路,递归产生-1,0,1组成的数字,在递归中采用元素交换的方法,求出排列后回溯,再继续求其他排列,到递归条件后终止。

具体实现为先统计-1,0,1各自测试用例中出现的次数,可以看出1在测试用例的结果中出现一次,0会有2次重复,-1也是二次重复,所以在递归传递数要传递5个数,也就是-1,-1,0,0,1。之后进行递归调用,对于排列树的第i层,扩展状态是a[i]到a[n-1]的任何元素,所以将a[i]和a[j]交换,求出排列后回溯。到递归条件后,如果满足产生的列表的前三个元素的-1,0,1相加为k的条件,将结果放入到结果集。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lihuacat233

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值