通过将用户输入与产品功能递归匹配来创建产品包

如何解决通过将用户输入与产品功能递归匹配来创建产品包

我正在从事产品包创建和推荐项目。捆绑和推荐必须根据用户输入实时进行。

条件是 1.产品包应尽可能涵盖用户输入。 2. 推荐项目之间的用户输入应该减少重复。

user_input=['a','b','c']

d1=['a','c','d']
d2=['a','e','f']
d3=['a','f']
d4=['b']
d5=['g','a']
d6=['g']

expected output - d1 + d4,d3,d1+d2,d5+d4+d1

以下是我的代码,它给出了结果,但它显示了重复的结果,也没有显示所有的组合。任何帮助表示赞赏。

dlist=[d1,d2,d4,d5,d6]
diff_match=[]
# find match n diff of each product based on user input
for i in range(len(dlist)):
    match=set(user_input).intersection(set(dlist[i]))
    #print("match is",match)
    diff=set(user_input).difference(set(dlist[i]))
    #print("diff is",diff)
    temp={'match':match,'diff':diff}
    diff_match.append(temp)
    
for i in range(len(diff_match)):
    # if match is found,recommend the product alone
    diff_match_temp=diff_match[i]['match']
    print("diff match temp is",diff_match_temp)
    if diff_match_temp==user_input:
        print ("absolute match")
    #scenario where the user input is subset of product features,seperate from partial match
    elif (all(x in list(diff_match_temp) for x in list(user_input))):
        print("User input subset of product features")
        print("The parent list is",diff_match[i]['match'])
        print("the product is",dlist[i])
    else:
        '''else check if the difference between user input and the current product is fulfilled by other product,if yes,these products are bundled together'''
        for j in range(len(diff_match)):
            temp_diff=diff_match[i]['diff']
            print("temp_diff is",temp_diff)
            # empty set should be explicitly checked to avoid wrong match
            if (temp_diff.intersection(diff_match[j]['match'])==temp_diff and len(temp_diff)!=0 and list(temp_diff) != user_input) :
            #if temp_diff==diff_match[j]['match'] and len(temp_diff)!=0 and list(temp_diff) != user_input :
                print("match found with another product")
                print("parent is",dlist[i])
                print("the combination is",dlist[j] )

解决方法

要以递归方式执行此操作,您可以创建一个函数,该函数返回具有最大组件覆盖率的产品并递归以完成包含剩余组件的捆绑包:

def getBundles(C,P):
    cSet     = set(C) # use set operations,largest to smallest coverage
    coverage = sorted(P.items(),key=lambda pc:-len(cSet.intersection(pc[1])))
    for i,(p,cs) in enumerate(coverage):
        if cSet.isdisjoint(cs):continue          # no coverage
        if cSet.issubset(cs): yield [p];continue # complete (stop recursion)
        remaining = cSet.difference(cs)   # remaining components to bundle
        unused    = dict(coverage[i+1:])  # products not already bundled
        yield from ([p]+rest for rest in getBundles(remaining,unused))

输出:

prods = {"d1":['a','c','d'],"d2":['a','b','e','f'],"d3":['a',"d4":['b'],"d5":['g','a'],"d6":['g']}

user_input=['a','c']

for bundle in getBundles(user_input,prods):
    print(bundle)

['d3']
['d1','d2']
['d1','d4']

请注意,排除了 ['d5','d1','d2'] 等冗余组合,因为 d1+d2 涵盖了 d5 涵盖的所有内容以及更多内容,因此 d5 是冗余的。相同产品的排列也被排除(例如 d1+d2 与 d2+d1 相同)

[编辑]

如果您需要提供冗余组合(可能作为扩展选择选项),您可以编写一个略有不同的递归函数,不会排除它们。您还应该在呈现结果时按最接近的顺序对结果进行排序:

def getBundles(C,P,remain=None,bundle=None):
    cSet  = set(C)                               # use set operations
    if remain is None: remain,bundle = cSet,[]   # track coverage & budle
    prods = list(P.items())                      # remaining products
    for i,cs) in enumerate(prods):
        if cSet.isdisjoint(cs):continue         # no coverage
        newBundle = bundle+[p]                  # add product to bundle
        if remain.issubset(cs): yield newBundle # full coverage bundle 
        toCover = remain.difference(cs)         # not yet covered 
        unused  = dict(prods[i+1:])             # remainin products
        yield from getBundles(C,unused,toCover,newBundle) # recurse for rest

输出:

prods = {"d1":['a',"d6":['g']}    
user_input=['a','c']

for bundle in sorted(getBundles(user_input,prods),key=lambda b:sum(map(len,(prods[p] for p in b)))):
    print(bundle)

['d1','d4']
['d3']
['d3','d4']
['d1','d3']
['d1','d4','d5']
['d3','d5']
['d1','d2','d3','d4']
['d2','d3']
['d3','d5']
['d2','d5']

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?