IndexError:在图形/地图着色的约束满足问题 (CSP) 中列出超出范围的索引

问题描述

运行代码时出现以下错误。该错误通常不会发生,因为代码对于一个“相邻状态”txt 文件完美运行。但是对于另一个“相邻状态”txt 文件,它给出了这个 IndexError。我被卡住了,因为我没有看到行中有任何错误。

neighbors[lst[0]] = lst[1:]
IndexError: list index out of range

“adjacent-states”txt文件如下:

Argentina Bolivia Brazil Chile Paraguay Uruguay
Bolivia Argentina Brazil Chile Paraguay Peru
Brazil Argentina Bolivia Colombia Guyana Paraguay Peru Suriname Uruguay Venezuela
Chile Argentina Bolivia Peru
Colombia Brazil Ecuador Peru Venezuela
Ecuador Colombia Peru
Falkland_Islands
Guyana Brazil Suriname Venezuela 
Paraguay Argentina Bolivia Brazil
Peru Bolivia Brazil Chile Colombia Ecuador
Suriname Brazil Guyana
Uruguay Argentina Brazil
Venezuela Brazil Colombia Guyana

代码如下:

import sys
import os
import queue
import time

start = time.time()

neighbors = {}
frequency = {}

def load_data():
    global neighbors,frequency
    with open('adjacent-states','r') as file:
        for line in file:
            lst = line.split()
            neighbors[lst[0]] = lst[1:]
    filename = sys.argv[0] 
    with open(filename,'r') as file:
        try:
            for line in file:
                (city,freq) = line.split()
                frequency[city]=[freq]
        except ValueError:
            frequency = {}
    for key in neighbors:
        if key not in frequency and neighbors[key] != []:   # If a state has no neighbor,We can give any values to it and save the 
            frequency[key] = ['A','B','C','D']      # time in backtracking
        elif key not in frequency:
            frequency[key] = ['A']

# function mrv provides the next state whose frequency should be assigned by the backtracking function. 
# It first checks which state has minimum number of available frequency and in case of tie which has most neighbouring states. 

def mrv(assignment,frequency):
    global neighbors
    len_domain={}
    for key in frequency:
        if key not in assignment:
            len_domain[key]=len(frequency[key])
    val = sorted(len_domain.items(),key=lambda x: x[1])
    min_val = val[0][1]
    highest = 0
    mrv_state = val[0][0]
    for k in val:
        if k[1] > min_val:
            break
        (state,curr) = k
        if len(neighbors[state]) > highest:
            highest = len(neighbors[state])
            mrv_state = state
    return mrv_state

# function lcv returns a list of possible values for a state by ordering values such that value causes least conflict
# comes first in the list

def lcv(state,assignment,frequency):
    choices = frequency[state]
    conflict_queue =queue.PriorityQueue()
    lcv_lst=[]
    for choice in choices:
        value = count_conflicts(state,choice,frequency,assignment)
        conflict_queue.put((value,(choice,)))
    while conflict_queue.empty() is not True:
        (value,)) = conflict_queue.get()
        lcv_lst.append(choice)
    return lcv_lst



# Temporary assign the value to a state. Remove the rest of the frequency from state's domain,append it to a list and return the list
def temp_assign(state,value,frequency):
    remove_freq = []
    for k in frequency[state]:
        if k != value:
            remove_freq.append((state,k))
    frequency[state]= [value]
    return remove_freq



# Count the number of future conflicts caused by the possible assignment of the frequency to the state.
def count_conflicts(state,assignment):
    global neighbors
    count = 0
    con_queue = queue.Queue()
    for neighbor in neighbors[state]:
        if neighbor not in assignment:
            con_queue.put((neighbor,choice))
    while not con_queue.empty():
        (state,mychoice) = con_queue.get()
        if len(frequency[state]) == 1 and [choice] == frequency[state] :
            count += 10
        if mychoice in frequency[state]:
            count += 1
    return count
    
# Check whether frequency assignment caused any violation of constraint or not and return the result.
def arc_consistent(assignment,state=None,remove_lst=None):
    global neighbors
    myqueue = queue.Queue()
    if state == None:
        for state in neighbors:
            for neighbor in neighbors[state]:
                myqueue.put((state,neighbor))
    else:
        for neighbor in neighbors[state]:
            myqueue.put((neighbor,state))
    while not myqueue.empty():
        (state,neighbor) = myqueue.get()
        if remove_inconsistent(state,neighbor,remove_lst):
            if len(frequency[state]) == 0:
                return False
            for new_neigh in neighbors[state]:
                myqueue.put((new_neigh,state))
    return True

# Remove all the frequency from the domain of a state that violates the constraint.
def remove_inconsistent(state,remove_lst):
    removed = False
    for freq in frequency[state]:
        if len(frequency[neighbor]) == 1 and [freq] == frequency[neighbor] :
            if remove_lst != None:
                remove_lst.append((state,freq))
            frequency[state].remove(freq)
            removed = True
    return removed

# To count the number of bactracks in the program
def myfunc():
    myfunc.counter += 1
    
        

# Main backtracking function that assigns values to a state and checks whether this assignment violates the constraint or not.
# If an assignment violates the constraints,function removes the assignment and backtrack to try another assignment. This function
# is same as given in textbook and ucb's video lecture. 
def assign(assignment,frequency):
    global neighbors
    myfunc.counter = 0
    if len(assignment) == len(frequency):
        return assignment
    state = mrv(assignment,frequency)
    choices = lcv(state,frequency)
    invalid = False
    for freq in choices:
        for neighbor in neighbors[state]:
            if neighbor in assignment and assignment[neighbor] == freq:
                invalid = True
            if invalid == False:
                assignment[state] = freq
                removal_lst = temp_assign(state,freq,frequency)
                if arc_consistent(assignment,state,removal_lst) == True:
                    if (assign(assignment,frequency)) != None:
                        return True
                for k in remove_lst:
                    (state,val) = k
                    frequency[state].append(val)
    myfunc()
    if state in assignment:
        del assignment[state] 
    return None

# with given constraints,this function search for the solution and report if it does not exist.
def search_solution(frequency):
    assignment = {}
    for state in frequency:                 # Here all those states,which has just one frequency in their domain,have 
        if len(frequency[state])== 1:           # been assigned to the assignment dictionary and then checking it's consistency
            value = (frequency[state])[0]       
            assignment[state] = value
    if arc_consistent(assignment,frequency) == False:   # If legacy_constraints provides such values that no assignment is feasible
        print (" No Solution is Feasible")       # satisfying the constraints,then no solution can be predicted at this stage

    
    if assign(assignment,frequency) == None :
        print (" No assignment is valid")
    else:   
        with open("results.txt","w") as file:
            for key in assignment:
                file.write( str(key) + " :    " + str(assignment[key]))
                file.write("\n")
        file.close()

if __name__ == "__main__":
    load_data()
    search_solution(frequency)  
    end = time.time()
    print (" Total Elapses time:  " + str(end - start))
    print ("\n")
    print ("Number of backtracks:  " + str(myfunc.counter))

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...